guide: add intro
This commit is contained in:
		
							parent
							
								
									b4587482d7
								
							
						
					
					
						commit
						dfa95a1ece
					
				
					 2 changed files with 568 additions and 4 deletions
				
			
		
							
								
								
									
										516
									
								
								content/docs/configuration/intro.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										516
									
								
								content/docs/configuration/intro.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,516 @@
 | 
			
		|||
+++
 | 
			
		||||
title = "Introduction"
 | 
			
		||||
+++
 | 
			
		||||
 | 
			
		||||
This page will walk you through the process of creating a simple bar/panel, and
 | 
			
		||||
introduce you to all the basic concepts involved.
 | 
			
		||||
 | 
			
		||||
There are many links to the [QML Overview](../qml-overview)
 | 
			
		||||
and [Type Reference](/docs/types) which you should follow if you don't
 | 
			
		||||
fully understand the concepts involved.
 | 
			
		||||
 | 
			
		||||
## Shell Files
 | 
			
		||||
 | 
			
		||||
Every quickshell instance starts from a shell root file, conventionally named `shell.qml`.
 | 
			
		||||
The default path is `~/.config/quickshell/shell.qml`.
 | 
			
		||||
(where `~/.config` can be substituted with `$XDG_CONFIG_HOME` if present.)
 | 
			
		||||
 | 
			
		||||
Each shell file starts with the shell root object. Only one may exist per configuration.
 | 
			
		||||
 | 
			
		||||
```qml {filename="~/.config/quickshell/shell.qml"}
 | 
			
		||||
import Quickshell
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
  // ...
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The shell root is not a visual element but instead contains all of the visual
 | 
			
		||||
and non visual objects in your shell. You can have multiple different shells
 | 
			
		||||
with shared components and different shell roots.
 | 
			
		||||
 | 
			
		||||
{{% details title="Shell search paths and manifests" closed="true" %}}
 | 
			
		||||
 | 
			
		||||
Quickshell can be launched with configurations in locations other than the default one.
 | 
			
		||||
 | 
			
		||||
The `-p` or `--path` option will launch the shell root at the given path.
 | 
			
		||||
It will also accept folders with a `shell.qml` file in them.
 | 
			
		||||
It can also be specified via the `QS_CONFIG_PATH` environment variable.
 | 
			
		||||
 | 
			
		||||
The `-c` or `--config` option will launch a configuration from the current manifest,
 | 
			
		||||
or if no manifest is specified, a subfolder of quickshell's base path.
 | 
			
		||||
It can also be specified via the `QS_CONFIG_NAME` environment variable.
 | 
			
		||||
 | 
			
		||||
The base path defaults to `~/.config/quickshell`, but can be changed using
 | 
			
		||||
the `QS_BASE_PATH` environment variable.
 | 
			
		||||
 | 
			
		||||
The `-m` or `--manifest` option specifies the quickshell manifest to read configs
 | 
			
		||||
from. When used with `-c`, the config will be chosen by name from the manifest.
 | 
			
		||||
It can also be specified via the `QS_MANIFEST` environment variable.
 | 
			
		||||
 | 
			
		||||
The manifest path defaults to `~/.config/quickshell/manifest.conf` and is a list
 | 
			
		||||
of `name = path` pairs where path can be relative or absolute.
 | 
			
		||||
Lines starting with `#` are comments.
 | 
			
		||||
 | 
			
		||||
```properties
 | 
			
		||||
# ~/.config/quickshell/manifest.conf
 | 
			
		||||
myconf1 = myconf
 | 
			
		||||
myconf2 = ./myconf
 | 
			
		||||
myconf3 = myconf/shell.nix
 | 
			
		||||
myconf4 = ~/.config/quickshell/myconf
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You can use `quickshell --current` to print the current values of any of these
 | 
			
		||||
options and what set them.
 | 
			
		||||
 | 
			
		||||
{{% /details %}}
 | 
			
		||||
 | 
			
		||||
## Creating Windows
 | 
			
		||||
 | 
			
		||||
Quickshell has two main window types available,
 | 
			
		||||
[PanelWindow](/docs/types/quickshell/panelwindow) for bars and widgets, and
 | 
			
		||||
[FloatingWindow](/docs/types/quickshell/floatingwindow) for standard desktop windows.
 | 
			
		||||
 | 
			
		||||
We'll start with an example:
 | 
			
		||||
```qml
 | 
			
		||||
import Quickshell // for ShellRoot and PanelWindow
 | 
			
		||||
import QtQuick // for Text
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
  PanelWindow {
 | 
			
		||||
    anchors {
 | 
			
		||||
      top: true
 | 
			
		||||
      left: true
 | 
			
		||||
      right: true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    height: 30
 | 
			
		||||
 | 
			
		||||
    Text {
 | 
			
		||||
      // center the bar in its parent component (the window)
 | 
			
		||||
      anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
      text: "hello world"
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The above example creates a bar/panel on your currently focused monitor with
 | 
			
		||||
a centered piece of [text](https://doc.qt.io/qt-6/qml-qtquick-text.html). It will also reserve space for itself on your monitor.
 | 
			
		||||
 | 
			
		||||
More information about available properties is available in the [type reference](/docs/types/quickshell/panelwindow).
 | 
			
		||||
 | 
			
		||||
## Running a process
 | 
			
		||||
 | 
			
		||||
Now that we have a piece of text, what if it did something useful?
 | 
			
		||||
To start with lets make a clock. To get the time we'll use the `date` command.
 | 
			
		||||
 | 
			
		||||
We can use a [Process](/docs/types/quickshell.io/process) object to run commands
 | 
			
		||||
and return their results.
 | 
			
		||||
 | 
			
		||||
We'll listen to the [DataStreamParser.read](/docs/types/quickshell.io/datastreamparser/#signal.read)
 | 
			
		||||
[signal](/docs/configuration/qml-overview/#signals) emitted by
 | 
			
		||||
[SplitParser](/docs/types/quickshell.io/splitparser/) using a
 | 
			
		||||
[signal handler](/docs/configuration/qml-overview/#signal-handlers)
 | 
			
		||||
to update the text on the clock.
 | 
			
		||||
 | 
			
		||||
{{< callout type="info" >}}
 | 
			
		||||
Note: Quickshell live-reloads your code. You can leave it open and edit the
 | 
			
		||||
original file. The panel will reload when you save it.
 | 
			
		||||
{{< /callout >}}
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Io // for Process
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
  PanelWindow {
 | 
			
		||||
    anchors {
 | 
			
		||||
      top: true
 | 
			
		||||
      left: true
 | 
			
		||||
      right: true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    height: 30
 | 
			
		||||
 | 
			
		||||
    Text {
 | 
			
		||||
      // give the text an ID we can refer to elsewhere in the file
 | 
			
		||||
      id: clock
 | 
			
		||||
 | 
			
		||||
      anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
      // create a process management object
 | 
			
		||||
      Process {
 | 
			
		||||
        // the command it will run, every argument is its own string
 | 
			
		||||
        command: ["date"]
 | 
			
		||||
 | 
			
		||||
        // run the command immediately
 | 
			
		||||
        running: true
 | 
			
		||||
 | 
			
		||||
        // process the stdout stream using a SplitParser
 | 
			
		||||
        // which returns chunks of output after a delimiter
 | 
			
		||||
        stdout: SplitParser {
 | 
			
		||||
          // listen for the read signal, which returns the data that was read
 | 
			
		||||
          // from stdout, then write that data to the clock's text property
 | 
			
		||||
          onRead: data => clock.text = data
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Running code at an interval
 | 
			
		||||
With the above example, your bar should now display the time, but it isn't updating!
 | 
			
		||||
Let's use a [Timer](https://doc.qt.io/qt-6/qml-qtqml-timer.html) fix that.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
  PanelWindow {
 | 
			
		||||
    anchors {
 | 
			
		||||
      top: true
 | 
			
		||||
      left: true
 | 
			
		||||
      right: true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    height: 30
 | 
			
		||||
 | 
			
		||||
    Text {
 | 
			
		||||
      id: clock
 | 
			
		||||
      anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
      Process {
 | 
			
		||||
        // give the process object an id so we can talk
 | 
			
		||||
        // about it from the timer
 | 
			
		||||
        id: dateProc
 | 
			
		||||
 | 
			
		||||
        command: ["date"]
 | 
			
		||||
        running: true
 | 
			
		||||
 | 
			
		||||
        stdout: SplitParser {
 | 
			
		||||
          onRead: data => clock.text = data
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // use a timer to rerun the process at an interval
 | 
			
		||||
      Timer {
 | 
			
		||||
        // 1000 milliseconds is 1 second
 | 
			
		||||
        interval: 1000
 | 
			
		||||
 | 
			
		||||
        // start the timer immediately
 | 
			
		||||
        running: true
 | 
			
		||||
 | 
			
		||||
        // run the timer again when it ends
 | 
			
		||||
        repeat: true
 | 
			
		||||
 | 
			
		||||
        // when the timer is triggered, set the running property of the
 | 
			
		||||
        // process to true, which reruns it if stopped.
 | 
			
		||||
        onTriggered: dateProc.running = true
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Reuseable components
 | 
			
		||||
 | 
			
		||||
If you have multiple monitors you might have noticed that your bar
 | 
			
		||||
is only on one of them. If not, you'll still want to **follow this section
 | 
			
		||||
to make sure your bar dosen't disappear if your monitor disconnects**.
 | 
			
		||||
 | 
			
		||||
We can use a [Variants](http://localhost:1313/docs/types/quickshell/variants/)
 | 
			
		||||
object to create instances of *non widget items*.
 | 
			
		||||
(See [Repeater](https://doc.qt.io/qt-6/qml-qtquick-repeater.html) for doing
 | 
			
		||||
something similar with visual items.)
 | 
			
		||||
 | 
			
		||||
The `Variants` type creates instances of a
 | 
			
		||||
[Component](https://doc.qt.io/qt-6/qml-qtqml-component.html) based on a data model
 | 
			
		||||
you supply. (A component is a re-usable tree of objects.)
 | 
			
		||||
 | 
			
		||||
The most common use of `Variants` in a shell is to create instances of
 | 
			
		||||
a window (your bar) based on your monitor list (the data model).
 | 
			
		||||
 | 
			
		||||
Variants will inject the properties in the data model directly into the component,
 | 
			
		||||
meaning we can easily set the screen property of our bar
 | 
			
		||||
(See [Window.screen](/docs/types/quickshell/qswindow/#prop.screen).)
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
  Variants {
 | 
			
		||||
    variants: {
 | 
			
		||||
      // get the list of screens from the Quickshell singleton
 | 
			
		||||
      const screens = Quickshell.screens;
 | 
			
		||||
 | 
			
		||||
      // transform the screen list into a list of objects with
 | 
			
		||||
      // screen variables, which will be set for each created object
 | 
			
		||||
      const variants = screens.map(screen => {
 | 
			
		||||
        return { screen: screen };
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      return variants;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    component: Component {
 | 
			
		||||
      PanelWindow {
 | 
			
		||||
        // the screen property will be injected into the window,
 | 
			
		||||
        // so each bar displays on the right monitor
 | 
			
		||||
 | 
			
		||||
        anchors {
 | 
			
		||||
          top: true
 | 
			
		||||
          left: true
 | 
			
		||||
          right: true
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        height: 30
 | 
			
		||||
 | 
			
		||||
        Text {
 | 
			
		||||
          id: clock
 | 
			
		||||
          anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
          Process {
 | 
			
		||||
            id: dateProc
 | 
			
		||||
            command: ["date"]
 | 
			
		||||
            running: true
 | 
			
		||||
 | 
			
		||||
            stdout: SplitParser {
 | 
			
		||||
              onRead: data => clock.text = data
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          Timer {
 | 
			
		||||
            interval: 1000
 | 
			
		||||
            running: true
 | 
			
		||||
            repeat: true
 | 
			
		||||
            onTriggered: dateProc.running = true
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<span class="small">See also:
 | 
			
		||||
[Property Bindings](/docs/configuration/qml-overview/#property-bindings),
 | 
			
		||||
[Variants.component](/docs/types/quickshell/variants/#prop.component),
 | 
			
		||||
[Quickshell.screens](/docs/types/quickshell/quickshell/#prop.screens),
 | 
			
		||||
[Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
 | 
			
		||||
</span>
 | 
			
		||||
 | 
			
		||||
With this example, bars will be created and destroyed as you plug and unplug them,
 | 
			
		||||
due to the reactive nature of the
 | 
			
		||||
[Quickshell.screens](/docs/types/quickshell/quickshell/#prop.screens) property.
 | 
			
		||||
(See: [Reactive Bindings](/docs/configuration/qml-overview/#reactive-bindings).)
 | 
			
		||||
 | 
			
		||||
Now there's an important problem you might have noticed: when the window
 | 
			
		||||
is created multiple times we also make a new Process and Timer. We can fix
 | 
			
		||||
this by moving the Process and Timer outside of the window.
 | 
			
		||||
 | 
			
		||||
{{< callout type="error" >}}
 | 
			
		||||
This code will not work correctly.
 | 
			
		||||
{{< /callout >}}
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
  Variants {
 | 
			
		||||
    variants: Quickshell.screens.map(screen => ({ screen }))
 | 
			
		||||
 | 
			
		||||
    component: Component {
 | 
			
		||||
      PanelWindow {
 | 
			
		||||
        anchors {
 | 
			
		||||
          top: true
 | 
			
		||||
          left: true
 | 
			
		||||
          right: true
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        height: 30
 | 
			
		||||
 | 
			
		||||
        Text {
 | 
			
		||||
          id: clock
 | 
			
		||||
          anchors.centerIn: parent
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: SplitParser {
 | 
			
		||||
      onRead: data => clock.text = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
    onTriggered: dateProc.running = true
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
However there is a problem with naively moving the Process and Timer
 | 
			
		||||
out of the component.
 | 
			
		||||
*What about the `clock` that the process references?*
 | 
			
		||||
 | 
			
		||||
If you run the above example you'll see something like this in the console every second:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined
 | 
			
		||||
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined
 | 
			
		||||
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined
 | 
			
		||||
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined
 | 
			
		||||
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This is because the `clock` object, even though it has an ID, cannot be referenced
 | 
			
		||||
outside of its component. Remember, components can be created *any number of times*,
 | 
			
		||||
including zero, so `clock` may not exist or there may be more than one, meaning
 | 
			
		||||
there isn't an object to refer to from here.
 | 
			
		||||
 | 
			
		||||
We can fix it with a [Property Definition](/docs/configuration/qml-overview/#property-definitions).
 | 
			
		||||
 | 
			
		||||
We can define a property inside of the ShellRoot and reference it from the clock
 | 
			
		||||
text instead. Due to QML's [Reactive Bindings](/docs/configuration/qml-overview/#reactive-bindings),
 | 
			
		||||
the clock text will be updated when we update the property for every clock that
 | 
			
		||||
currently exists.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
  id: root
 | 
			
		||||
 | 
			
		||||
  // add a property in the root
 | 
			
		||||
  property string time;
 | 
			
		||||
 | 
			
		||||
  Variants {
 | 
			
		||||
    variants: Quickshell.screens.map(screen => ({ screen }))
 | 
			
		||||
 | 
			
		||||
    component: Component {
 | 
			
		||||
      PanelWindow {
 | 
			
		||||
        anchors {
 | 
			
		||||
          top: true
 | 
			
		||||
          left: true
 | 
			
		||||
          right: true
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        height: 30
 | 
			
		||||
 | 
			
		||||
        Text {
 | 
			
		||||
          // remove the id as we don't need it anymore
 | 
			
		||||
 | 
			
		||||
          anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
          // bind the text to the root's time property
 | 
			
		||||
          text: root.time
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: SplitParser {
 | 
			
		||||
      // update the property instead of the clock directly
 | 
			
		||||
      onRead: data => root.time = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
    onTriggered: dateProc.running = true
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Now we've fixed the problem so there's nothing actually wrong with the
 | 
			
		||||
above code, but we can make it more concise:
 | 
			
		||||
 | 
			
		||||
1. `Component`s can be defined implicitly, meaning we can remove the
 | 
			
		||||
component wrapping the window and place the window directly into the
 | 
			
		||||
`component` property.
 | 
			
		||||
2. The [Variants.component](/docs/types/quickshell/variants/#prop.component)
 | 
			
		||||
property is a [Default Property](/docs/configuration/qml-overview/#the-default-property),
 | 
			
		||||
which means we can skip the `component: ` part of the assignment.
 | 
			
		||||
We're already using [ShellRoot](/docs/types/quickshell/shellroot/)'s
 | 
			
		||||
default property to store our Variants, Process, and Timer components
 | 
			
		||||
among other things.
 | 
			
		||||
3. The ShellRoot dosen't actually need an `id` property to talk about
 | 
			
		||||
the time property, as it is the outermost object in the file which
 | 
			
		||||
has [special scoping rules](/docs/configuration/qml-overview/#property-access-scopes).
 | 
			
		||||
 | 
			
		||||
This is what our shell looks like with the above (optional) cleanup:
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
import Quickshell
 | 
			
		||||
import Quickshell.Io
 | 
			
		||||
import QtQuick
 | 
			
		||||
 | 
			
		||||
ShellRoot {
 | 
			
		||||
  property string time;
 | 
			
		||||
 | 
			
		||||
  Variants {
 | 
			
		||||
    variants: Quickshell.screens.map(screen => ({ screen }))
 | 
			
		||||
 | 
			
		||||
    PanelWindow {
 | 
			
		||||
      anchors {
 | 
			
		||||
        top: true
 | 
			
		||||
        left: true
 | 
			
		||||
        right: true
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      height: 30
 | 
			
		||||
 | 
			
		||||
      Text {
 | 
			
		||||
        anchors.centerIn: parent
 | 
			
		||||
 | 
			
		||||
        // now just time instead of root.time
 | 
			
		||||
        text: time
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Process {
 | 
			
		||||
    id: dateProc
 | 
			
		||||
    command: ["date"]
 | 
			
		||||
    running: true
 | 
			
		||||
 | 
			
		||||
    stdout: SplitParser {
 | 
			
		||||
      // now just time instead of root.time
 | 
			
		||||
      onRead: data => time = data
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Timer {
 | 
			
		||||
    interval: 1000
 | 
			
		||||
    running: true
 | 
			
		||||
    repeat: true
 | 
			
		||||
    onTriggered: dateProc.running = true
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +141,7 @@ specifying a version at least when importing quickshell modules.
 | 
			
		|||
 | 
			
		||||
#### Implicit imports
 | 
			
		||||
 | 
			
		||||
The QML engine will automatically import any [types](#types) in neighboring files
 | 
			
		||||
The QML engine will automatically import any [types](#creating-types) in neighboring files
 | 
			
		||||
with names that start with an uppercase letter.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			@ -222,10 +222,9 @@ Properties can be defined inside of objects with the following syntax:
 | 
			
		|||
[required] [readonly] [default] property <type> <name>[: binding]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- `required` forces users of this type to assign this property. See [Types](#types) for details.
 | 
			
		||||
- `required` forces users of this type to assign this property. See [Creating Types](#creating-types) for details.
 | 
			
		||||
- `readonly` makes the property not assignable. Its binding will still be [reactive](#reactive-bindings).
 | 
			
		||||
- `default` makes the property the default property of this type. See [Types](#types)
 | 
			
		||||
for details.
 | 
			
		||||
- `default` makes the property the [default property](#the-default-property) of this type.
 | 
			
		||||
- `type` is the type of the property. You can use `var` if you don't know or don't care but be aware that `var` will
 | 
			
		||||
allow any value type.
 | 
			
		||||
- `name` is the name that the property is known as. It cannot start with an uppercase letter.
 | 
			
		||||
| 
						 | 
				
			
			@ -247,6 +246,39 @@ Item {
 | 
			
		|||
Defining a property with the same name as one provided by the current object will override
 | 
			
		||||
the property of the type it is derived from in the current context.
 | 
			
		||||
 | 
			
		||||
##### The default property
 | 
			
		||||
 | 
			
		||||
Types can have a *default property* which must accept either an object or a list of objects.
 | 
			
		||||
 | 
			
		||||
The default property will allow you to assign a value to it without using the name of the property:
 | 
			
		||||
```qml
 | 
			
		||||
Item {
 | 
			
		||||
  // normal property
 | 
			
		||||
  foo: 3
 | 
			
		||||
 | 
			
		||||
  // this item is assigned to the outer object's default property
 | 
			
		||||
  Item {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If the default property is a list, you can put multiple objects into it the same way as you
 | 
			
		||||
would put a single object in:
 | 
			
		||||
```qml
 | 
			
		||||
Item {
 | 
			
		||||
  // normal property
 | 
			
		||||
  foo: 3
 | 
			
		||||
 | 
			
		||||
  // this item is assigned to the outer object's default property
 | 
			
		||||
  Item {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // this one is too
 | 
			
		||||
  Item {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### The `id` property
 | 
			
		||||
 | 
			
		||||
Every object has a special property called `id` that can be assigned to give
 | 
			
		||||
| 
						 | 
				
			
			@ -642,6 +674,22 @@ Item {
 | 
			
		|||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### Singletons
 | 
			
		||||
QML Types can be easily made into a singleton, meaning there is only one instance
 | 
			
		||||
of the type.
 | 
			
		||||
 | 
			
		||||
To make a type a singleton, put `pragma Singleton` at the top of the file.
 | 
			
		||||
 | 
			
		||||
```qml
 | 
			
		||||
pragma Singleton
 | 
			
		||||
import ...
 | 
			
		||||
 | 
			
		||||
Item { ... }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
once a type is a singleton, its members can be accessed by name from neighboring
 | 
			
		||||
files.
 | 
			
		||||
 | 
			
		||||
## Concepts
 | 
			
		||||
 | 
			
		||||
### Reactive bindings
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue