proofreading and tweaks

This commit is contained in:
starchglazer 2025-06-18 21:17:00 +08:00 committed by outfoxxed
parent 58eba03e3f
commit 403dc6d424
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
7 changed files with 206 additions and 194 deletions

View file

@ -6,12 +6,15 @@ If you plan to distribute your configuration to a lot of users, you should keep
a couple things in mind: a couple things in mind:
### API Breaks ### API Breaks
Quickshell will have API breaks in future versions. As Quickshell is still in a somewhat early stage of development, Quickshell will
You should have a way to track specific revisions with your distribution have API breaks for future versions.
to avoid breakage if a user updates quickshell before you can update your configuration.
With Nix this should be as simple as tracking a specific revision. You should have a way to track specific revisions to avoid breakage if a user
For Arch, and other distributions without a mechanism to do this, you may updates Quickshell before you can update your configuration.
With Nix, this should be as simple as tracking a specific revision.
For Arch, or any other distributions without a mechanism to do this, you may
want to include a package that builds a specific Quickshell revision with want to include a package that builds a specific Quickshell revision with
your configuration. your configuration.
@ -20,13 +23,14 @@ Quickshell can load configurations from a number of different paths.
The ideal path depends on how you distribute your config. The ideal path depends on how you distribute your config.
#### As dotfiles #### As dotfiles
If you distribute your config as a set of dotfiles, you should place If you distribute your config as a set of dotfiles, you should place it in
the config in `$XDG_CONFIG_HOME/quickshell/<name>` (usually `~/.config/quickshell/<name>`). `$XDG_CONFIG_HOME/quickshell/<name>` (usually `~/.config/quickshell/<name>`).
Named configurations can be used in the quickshell command by specifying `--config` or `-c`
(`qs -c <name>`).
You should not use the bare `$XDG_CONFIG_HOME/quickshell` directory as that will You should name your config and refrain from using the bare `$XDG_CONFIG_HOME/quickshell`
make it harder for users to have any other configuration. directory, as that will make it harder for users to have any other configuration.
Any directory in the `$XDG_CONFIG_HOME/quickshell` can be used using the Quickshell command
by specifying `--config` or `-c`, like so: `qs -c <name>`.
#### As a package #### As a package
Some configurations are distributed as distro packages. These packages should use a Some configurations are distributed as distro packages. These packages should use a

View file

@ -3,10 +3,13 @@ title: "FAQ"
description: "Frequently Asked Questions" description: "Frequently Asked Questions"
index: 1000 index: 1000
--- ---
This page is being actively expanded as common questions come up again.
Make sure to also read the [Item Size and Position](/docs/guide/size-position) and > [!NOTE]
[QML Language](/docs/guide/qml-language) pages for questions related to > This page is being actively expanded upon as more common questions come up.
>
> Make sure to also read the [Item Size and Position](/docs/guide/size-position) and
> [QML Language](/docs/guide/qml-language) pages for questions related to
> item sizing/positioning and QML in general.
## Misc ## Misc
@ -16,7 +19,7 @@ span the APIs exposed by Quickshell, as well as best practice across all
APIs, but will not change the language syntax or anything exposed by Qt. APIs, but will not change the language syntax or anything exposed by Qt.
Most changes will be relatively trivial, though you may have to make the same Most changes will be relatively trivial, though you may have to make the same
trivial change a great number of times if you have a large configuration. trivial change a considerable amount of times if you have a large configuration.
Migration guides will be provided between each release version. Migration guides will be provided between each release version.
@ -27,7 +30,7 @@ single process.
## How do I ## How do I
### Make a rounded window ### Make a rounded window
Rounded windows are simply transparent square ones with a rounded rectangle Rounded windows are simply transparent, square windows, with a rounded rectangle
inside of them. inside of them.
```qml ```qml
@ -46,11 +49,11 @@ inside of them.
### Make a list of widgets ### Make a list of widgets
If you have a short list of items to display, such as a list of active music If you have a short list of items to display, such as a list of active music
players or system tray items, you want a @@QtQuick.Repeater, usually combined players or system tray items, you want a @@QtQuick.Repeater, which is
with a @@QtQuick.Layouts.RowLayout or @@QtQuick.Layouts.ColumnLayout. usually combined with a @@QtQuick.Layouts.RowLayout or @@QtQuick.Layouts.ColumnLayout.
If you have a longer list, such as a list of entries in an application launcher, If you have a longer list, such as a list of entries in an application launcher
or a list that needs to scroll, you may want a @@QtQuick.ListView instead. or a list that needs to be scrolled, you want a @@QtQuick.ListView instead.
### Run a program or script ### Run a program or script
Use @@Quickshell.Io.Process. Use @@Quickshell.Io.Process.
@ -63,10 +66,15 @@ e.g. a command that listens to window manager IPC commands, use
@@Quickshell.Io.SplitParser to return each datum as it arrives. @@Quickshell.Io.SplitParser to return each datum as it arrives.
### Show widgets conditionally ### Show widgets conditionally
The @@QtQuick.Item.visible property can be used to change the visibility of an Conditionally showing widgets can be done in two ways, simply using the @@QtQuick.Item.visible property,
Item conditionally, as well as Loaders. or by using a @@QtQuick.Loader.
Depending on your use case, both the @@QtQuick.Loader and the @@QtQuick.Item.visible property
may make sense at equal complexity. If you want to unload a widget tree to save memory or
speed up load times, then you should use Loaders.
Note that you can also change out a Loader's component conditionally:
Note that you can change out a loader's component conditionally:
```qml ```qml
@@QtQuick.Loader { @@QtQuick.Loader {
readonly property Component thing1: ... readonly property Component thing1: ...
@ -77,9 +85,9 @@ Note that you can change out a loader's component conditionally:
``` ```
### Round an image ### Round an image
The easiest way to round an image is with @@Quickshell.Widgets.ClippingWrapperRectangle. The easiest way to round an image is with @@Quickshell.Widgets.ClippingWrapperRectangle,
ClippingWrapperRectangle is a [MarginWrapper] component, which will attempt to match which is a [MarginWrapper] component. This component will attempt to match the size of
the size of its contained item. its contained item.
```qml ```qml
@@Quickshell.Widgets.ClippingWrapperRectangle { @@Quickshell.Widgets.ClippingWrapperRectangle {
@ -97,7 +105,7 @@ the size of its contained item.
### Reference images and resources ### Reference images and resources
By default, paths passed to components such as @@QtQuick.Image or By default, paths passed to components such as @@QtQuick.Image or
@@Quickshell.Io.FileView as strings are relative to Quickshell's working @@Quickshell.Io.FileView as strings are relative to Quickshell's working
directory. Usually this is not the desired behavior. directory. Usually, this is not the desired behavior.
To get a file path relative to the current QML file, you can use @@QtQml.Qt.resolvedUrl(). To get a file path relative to the current QML file, you can use @@QtQml.Qt.resolvedUrl().
@ -106,12 +114,12 @@ you can use @@Quickshell.Quickshell.cachePath(), @@Quickshell.Quickshell.dataPat
@@Quickshell.Quickshell.statePath(), @@Quickshell.Quickshell.statePath(),
### Add a drop-shadow ### Add a drop-shadow
If you want a *rectangular*, *round rectangular*, or *circular* drop shadow, Use @@QtQuick.Effects.RectangularShadow if you want a *rectangular*, *round rectangular*,
use @@QtQuick.Effects.RectangularShadow. or *circular* drop shadow.
For any other shape, you will have to use a @@QtQuick.Effects.MultiEffect.
When using a MultiEffect, set @@QtQuick.Effects.MultiEffect.shadowEnabled, For any other shape, you will have to use a @@QtQuick.Effects.MultiEffect and set
as well as its other shadow and blur related properties. @@QtQuick.Effects.MultiEffect.shadowEnabled, as well as its other shadow and blur
related properties.
### Get rid of the purple/black icons ### Get rid of the purple/black icons
The @@Quickshell.Quickshell.iconPath() function has three variants: The @@Quickshell.Quickshell.iconPath() function has three variants:
@ -127,19 +135,20 @@ however you can implement your own using @@Quickshell.Io.Socket or @@Quickshell.
which can be used to parse and send IPC messages. which can be used to parse and send IPC messages.
### Open/close windows with commands ### Open/close windows with commands
Quickshell doesn't come with a command to open or close a window, however you can Quickshell doesn't come with a command to open or close a window; however, you can
make your own using @@Quickshell.Io.IpcHandler, which allows you to call functions make your own using @@Quickshell.Io.IpcHandler, allowing you to call functions
inside of Quickshell with a command. Said functions can change the inside of Quickshell with a command. Said functions can change the
@@Quickshell.QsWindow.visible property of a window, or load/unload it using a @@Quickshell.QsWindow.visible property of a window, or load/unload it using a
@@Quickshell.LazyLoader. @@Quickshell.LazyLoader.
### Reduce memory usage ### Reduce memory usage
The main thing you can do to reduce the memory usage of a given configuration The main thing you can do to reduce the memory usage of a given configuration
is to use loaders. Loaders can be used to create objects only when needed, is to use Loaders.
and destroy them when not needed.
- Use @@QtQuick.Loader when the component being loaded inherits from @@QtQuick.Item. Loaders can be used to create objects only when needed, and destroy them when not needed.
- Use @@Quickshell.LazyLoader in other cases.
@@QtQuick.Loader should be used if the component being loaded inherits from @@QtQuick.Item,
otherwise, a @@Quickshell.LazyLoader should be used.
## Something is broken ## Something is broken
@ -153,9 +162,11 @@ if the only border property you wanted to set was radius.
### My window should not be opaque ### My window should not be opaque
If a window is created with an opaque background color, Quickshell will use If a window is created with an opaque background color, Quickshell will use
a window surface format that is opaque, which reduces the amount of processing a window surface format that is opaque. This is done to reduce the amount of
the gpu must do to draw it. If you change the background color of your window processing the gpu must do to draw it.
between opaque and transparent colors, this may affect you.
To tell Quickshell to always create a window capable of showing transparency, If you change the background color of your window between opaque and transparent colors,
then this may affect you.
To tell Quickshell that you want to create a window capable of showing transparency,
use @@Quickshell.QsWindow.surfaceFormat to set `opaque` to false. use @@Quickshell.QsWindow.surfaceFormat to set `opaque` to false.

View file

@ -6,12 +6,12 @@ index: -1
See the [Installation and Setup](/docs/guide/install-setup) page to get started. See the [Installation and Setup](/docs/guide/install-setup) page to get started.
To write a Quickshell config, start by following the To write a Quickshell config, start by following the
[Guided Introduction](/docs/guide/introduction) and skimming the [Guided Introduction](/docs/guide/introduction), and skimming the
[QML Language Overview](/docs/guide/qml-language). [QML Language Overview](/docs/guide/qml-language).
Before continuing on your own, read the [Item Size and Position](/docs/guide/size-position) After that, read the [Item Size and Position](/docs/guide/size-position) page before
page to learn how to lay out elements in QML. This is significantly different continuing on your own to learn how to lay out elements in QML. Laying out elements
from many other layout systems such as CSS. in QML is significantly different from many other layout systems such as CSS.
To learn what features Quickshell offers and how to use them, use the To learn what features Quickshell offers and how to use them, use the
left sidebar and click through the `Quickshell Types` pages. The sidebar left sidebar and click through the `Quickshell Types` pages. The sidebar

View file

@ -8,7 +8,8 @@ index: 0
## Installation ## Installation
All packages currently track quickshell's master branch. This may change in the future. Since Quickshell 0.1, you can now choose whether to install by tracking the master branch,
or install by latest release.
Note that you may want to install some additional packages (names vary by distro): Note that you may want to install some additional packages (names vary by distro):
- `qtsvg`: support for SVG image loading (bundled with most packages) - `qtsvg`: support for SVG image loading (bundled with most packages)
@ -17,12 +18,13 @@ Note that you may want to install some additional packages (names vary by distro
- `qt5compat`: extra visual effects, notably gaussian blur. @@QtQuick.Effects.MultiEffect is usually preferable - `qt5compat`: extra visual effects, notably gaussian blur. @@QtQuick.Effects.MultiEffect is usually preferable
### Nix ### Nix
Quickshell releases are packaged in nixpkgs as `quickshell`. The Quickshell repo has an embedded flake. You can use either of the two:
The Quickshell repo also has an embedded flake. - `git+https://git.outfoxxed.me/outfoxxed/quickshell`
You can use either `git+https://git.outfoxxed.me/outfoxxed/quickshell` - `github:quickshell-mirror/quickshell`
or `github:quickshell-mirror/quickshell`. Use `?ref=` to specify a tag
if you want a tagged release. > [!NOTE]
> You can use `?ref=` to specify a tag if you want a tagged release.
```nix ```nix
{ {
@ -41,20 +43,19 @@ if you want a tagged release.
} }
``` ```
The package is available as `quickshell.packages.<system>.default`, which you can add to The package is available as `quickshell.packages.<system>.default`, which can be added to
`environment.systemPackages` or `home.packages` if you use home-manager. your `environment.systemPackages` or `home.packages` if you use home-manager.
### Arch ### Arch
Quickshell is available from the aur under Quickshell is available from the aur under:
the [quickshell](https://aur.archlinux.org/packages/quickshell) package for the latest release, - the [quickshell](https://aur.archlinux.org/packages/quickshell) package for the latest release
or the [quickshell-git](https://aur.archlinux.org/packages/quickshell-git) package - the [quickshell-git](https://aur.archlinux.org/packages/quickshell-git) package that tracks the master branch
which tracks the master branch.
> [!WARNING] > [!WARNING]
> When using an AUR package, quickshell may break any time Qt is updated. > When using an AUR package, Quickshell may break whenever Qt is updated.
> The AUR gives us no way to actually fix this, but Quickshell will attempt to > The AUR gives us no way to actually fix this, but Quickshell will attempt to
> warn you if it detects a breakage when updating. If warned of a breakage, > warn you if it detects a breakage when updating. If warned of a breakage,
> please reinstall the package > please reinstall the package.
Install using the command below: Install using the command below:
```sh ```sh
@ -65,9 +66,9 @@ yay -S quickshell-git
(or your AUR helper of choice) (or your AUR helper of choice)
### Fedora ### Fedora
Quickshell is available from the [errornointernet/quickshell] COPR, as either Quickshell is available from the [errornointernet/quickshell] COPR, as either:
`quickshell` which tracks the latest release or `quickshell-git` which tracks - `quickshell` that tracks the latest release
the master branch. - `quickshell-git` that tracks the master branch
[errornointernet/quickshell]: https://copr.fedorainfracloud.org/coprs/errornointernet/quickshell [errornointernet/quickshell]: https://copr.fedorainfracloud.org/coprs/errornointernet/quickshell
@ -90,7 +91,8 @@ Quickshell's source repository works as a channel. Add the following to your cha
(branch "master")) (branch "master"))
``` ```
Then, you can install the package via `guix install quickshell-git` or by adding `quickshell-git` to your system or home definition. Then, you can install the package via `guix install quickshell-git` or by adding `quickshell-git`
to your system or home definition.
You can also clone the repository and use `guix shell -f quickshell.scm` to try out the package. You can also clone the repository and use `guix shell -f quickshell.scm` to try out the package.
@ -172,13 +174,13 @@ We are aware of the following issues:
- Qmlls does not work well when a file is not correctly structured. - Qmlls does not work well when a file is not correctly structured.
This means that completions and lints won't work unless braces are closed This means that completions and lints won't work unless braces are closed
correctly and such. correctly and such.
- Qmlls cannot handle quickshell's singletons. This means you won't see - Qmlls cannot handle Quickshell's Singleton, which means you won't see completions,
completions, and usages of singleton members may show a warning. and usages of Singleton members may show a warning. We're still investigating
We're still investigating this problem and how to fix it. this problem and how to fix it.
- The LSP cannot provide any documentation for Quickshell types. - The LSP cannot provide any documentation for Quickshell types.
Keeping in mind the above caveats, qmlls should be able to guide you towards Keeping in mind the above caveats, qmlls should be able to guide you towards a
more correct code should you chose to use it. more correct code should you choose to use it.
> [!NOTE] > [!NOTE]
> Nix users should note that qmlls will not be able to pick up qml modules > Nix users should note that qmlls will not be able to pick up qml modules

View file

@ -7,25 +7,28 @@ introduce you to all the basic concepts involved. You can use the
[QML Language Reference](/docs/guide/qml-language) to learn about the syntax [QML Language Reference](/docs/guide/qml-language) to learn about the syntax
of the QML language. of the QML language.
Note that all the <a>Green Links</a> in code blocks will take you to the documentation > [!NOTE]
for their respective types. > All the <a>Green Links</a> in code blocks will take you to the documentation,
> listing their respective types.
## Config Files ## Config Files
Quickshell searches the `quickshell` subfolder of every XDG standard config path Quickshell searches the `quickshell` subfolder of every XDG standard config path
for configs. Usually this is `~/.config/quickshell`. for configs. Usually, this is `~/.config/quickshell`.
Each named subfolder containing a `shell.qml` file is considered to be a config. Each named subfolder containing a `shell.qml` file is considered to be a config.
If the base `quickshell` folder contains a shell.qml file, subfolders will not be If the base `quickshell` folder contains a `shell.qml` file, subfolders will
considered. not be considered.
A specific config can be picked using the `--config` or `-c` argument to Quickshell. A specific configuration can be picked using the `--config` or `-c` argument to Quickshell.
Configs at other paths, including raw qml files can be run with `--path` or `-p`. Configs located at other paths outside XDG standard, including raw qml files,
can be run with `--path` or `-p`.
## Creating Windows ## Creating Windows
Quickshell has two main window types available, @@Quickshell.PanelWindow for bars Quickshell has two main window types available:
and widgets, and @@Quickshell.FloatingWindow for standard desktop windows. - @@Quickshell.PanelWindow for bars, widgets, and overlays
- @@Quickshell.FloatingWindow for standard desktop windows
We'll start with an example: We'll start with an example:
@ -52,14 +55,15 @@ import QtQuick // for Text
``` ```
The above example creates a bar/panel on your currently focused monitor with 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. 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). More information about available properties is available in the [type reference](/docs/types/Quickshell/PanelWindow).
## Running a process ## Running a process
Now that we have a piece of text, what if it did something useful? 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. To start with, let's make a clock. To get the time, we'll use the `date` command.
> [!note/Note] > [!note/Note]
> Quickshell can do more than just run processes. Read until the end for more information. > Quickshell can do more than just run processes. Read until the end for more information.
@ -173,13 +177,12 @@ import QtQuick
## Reusable components ## Reusable components
If you have multiple monitors you might have noticed that your bar 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 is only on one of them. If not, you'll still want to **follow this section
to make sure your bar doesn't disappear if your monitor disconnects**. to make sure your bar doesn't disappear if your monitor disconnects**.
We can use a @@Quickshell.Variants object to create instances of _non widget items_. We can use a @@Quickshell.Variants object to create instances of _non-widget items_.
(See @@QtQuick.Repeater for doing (See @@QtQuick.Repeater for doing something similar with visual items.)
something similar with visual items.)
The @@Quickshell.Variants type creates instances of a @@QtQml.Component based on The @@Quickshell.Variants type creates instances of a @@QtQml.Component based on
a data model you supply. (A component is a re-usable tree of objects.) a data model you supply. (A component is a re-usable tree of objects.)
@ -248,12 +251,11 @@ import QtQuick
</span> </span>
With this example, bars will be created and destroyed as you plug and unplug them, With this example, bars will be created and destroyed as you plug and unplug them,
due to the reactive nature of the due to the reactive nature of the @@Quickshell.Quickshell.screens property.
@@Quickshell.Quickshell.screens property.
(See: [Reactive Bindings](/docs/configuration/qml-overview/#reactive-bindings).) (See: [Reactive Bindings](/docs/configuration/qml-overview/#reactive-bindings).)
Now there's an important problem you might have noticed: when the window 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, which makes the is created multiple times, we also make a new Process and Timer, which makes the
bar less efficient than it could be. We can fix this by moving the bar less efficient than it could be. We can fix this by moving the
Process and Timer outside of the window using @@Quickshell.Scope. Process and Timer outside of the window using @@Quickshell.Scope.
@ -309,11 +311,10 @@ import QtQuick
} }
``` ```
However there is a problem with naively moving the Process and Timer However, there is a problem with naively moving the Process and Timer out of the component.
out of the component.
_What about the `clock` that the process references?_ _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: If you run the above example, you'll see something like this in the console every second:
``` ```
WARN scene: **/shell.qml[36:-1]: ReferenceError: clock is not defined WARN scene: **/shell.qml[36:-1]: ReferenceError: clock is not defined
@ -394,8 +395,8 @@ import QtQuick
} }
``` ```
Now we've fixed the problem so there's nothing actually wrong with the Now we've fixed the problem, so there's nothing actually wrong with the
above code, but we can make it more concise: above code; however, we can make it more concise:
1. `Component`s can be defined implicitly, meaning we can remove the 1. `Component`s can be defined implicitly, meaning we can remove the
component wrapping the window and place the window directly into the component wrapping the window and place the window directly into the
@ -532,11 +533,11 @@ We can bring in other folders as well using
[import statements](/docs/configuration/qml-overview/#explicit-imports). [import statements](/docs/configuration/qml-overview/#explicit-imports).
Now what about breaking out the clock? This is a bit more complex because Now what about breaking out the clock? This is a bit more complex because
the clock component in the bar, as well as the process and timer that the clock component in the bar need to be dealt with, as well as the necessary
make up the actual clock, need to be dealt with. processes that make up the actual clock.
To start with, we can move the clock widget to a new file. For now it's just a To start with, we can move the clock widget to a new file. For now, it's just a
single @@QtQuick.Text object but the same concepts apply regardless of complexity. single @@QtQuick.Text object, but the same concepts apply regardless of complexity.
```qml ```qml
// ClockWidget.qml // ClockWidget.qml
@ -683,7 +684,7 @@ any scope.
```qml ```qml
// Time.qml // Time.qml
// with this line our type becomes a singleton // with this line our type becomes a Singleton
pragma Singleton pragma Singleton
import Quickshell import Quickshell

View file

@ -5,7 +5,7 @@ index: 10
import Collapsible from "@components/Collapsible.astro"; import Collapsible from "@components/Collapsible.astro";
Quickshell is configured using the Qt Modeling Language, or QML. Quickshell is configured using the Qt Modeling Language, or QML.
This page explains what you need to know about QML to start using quickshell. This page explains what you need to know about QML to start using Quickshell.
<span class="small"> <span class="small">
See also: [Qt Documentation: QML See also: [Qt Documentation: QML
@ -129,8 +129,9 @@ import "<filename>" as <Namespace>
- `Namespace` is the namespace functions and variables from the javascript - `Namespace` is the namespace functions and variables from the javascript
file will be made available under. file will be made available under.
Note: All _Module_ and _Namespace_ names must start with an uppercase letter. > [!NOTE]
Attempting to use a lowercase namespace is an error. > All _Module_ and _Namespace_ names must start with an uppercase letter.
> Attempting to use a lowercase namespace will result in an error.
##### Examples ##### Examples
@ -142,21 +143,8 @@ import QtQuick.Layouts 6.0 as L
import "jsfile.js" as JsFile import "jsfile.js" as JsFile
``` ```
<Collapsible title="When no module version">
By default, when no module version is requested, the QML engine will pick
the latest available version of the module. Requesting a specific version
can help ensure you get a specific version of the module's types, and as a
result your code doesn't break across Qt or quickshell updates.
While Qt's types usually don't majorly change across versions, quickshell's
are much more likely to break. To put off dealing with the breakage we suggest
specifying a version at least when importing quickshell modules.
</Collapsible>
<span class="small"> <span class="small">
[Qt Documentation: Import See also: [Qt Documentation: Import
syntax](https://doc.qt.io/qt-6/qtqml-syntax-imports.html) syntax](https://doc.qt.io/qt-6/qtqml-syntax-imports.html)
</span> </span>
@ -171,7 +159,7 @@ root
|-shell.qml |-shell.qml
``` ```
In this example, `MyButton` will automatically be imported as a type usable from shell.qml In this example, `MyButton` will automatically be imported as a type usable from `shell.qml`
or any other neighboring files. or any other neighboring files.
### Objects ### Objects
@ -195,13 +183,14 @@ by looking it up in the [Type Reference](/docs/types/).
#### Properties #### Properties
Every object may have any number of property assignments (only one per specific property). Every object may have any number of property assignment, with only one assignment per specific property.
Each assignment binds the named property to the given expression. Each assignment binds the named property to the given value/expression.
##### Property bindings ##### Property bindings
Expressions are snippets of javascript code assigned to a property. The last (or only) line Expressions are snippets of javascript code assigned to a property.
can be the return value, or an explicit return statement (multiline expressions only) can be used. The last line can serve as the return value.
Alternatively, an explicit return statement can also be used for multi-line expressions.
```qml ```qml
@@QtQuick.Item { @@QtQuick.Item {
@ -226,16 +215,14 @@ can be the return value, or an explicit return statement (multiline expressions
} }
``` ```
Semicolons are optional and allowed on any line of a single or multiline expression, Semicolons, while optional, can be included on any line of a single or multi-line expression,
including the last line. including the last line.
All property bindings are [_reactive_](#reactive-bindings), which means when any property the expression depends All property bindings are [_reactive_](#reactive-bindings). This means that whenever any
on is updated, the expression is re-evaluated and the property is updated. property the expression depends on is updated, the expression is re-evaluated and the property
is updated accordingly.
<span class="small">See: [Reactive bindings](#reactive-bindings)</span> <span class="small">See also [Reactive bindings](#reactive-bindings) for more information</span>
Note that it is an error to try to assign to a property that does not exist.
(See: [property definitions](#property-definitions))
##### Property definitions ##### Property definitions
@ -269,6 +256,8 @@ Properties can be defined inside of objects with the following syntax:
Defining a property with the same name as one provided by the current object will override 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 property of the type it is derived from in the current context.
Trying to assign to a property that does not exist is an error.
##### The default property ##### The default property
Types can have a _default property_ which must accept either an object or a list of objects. Types can have a _default property_ which must accept either an object or a list of objects.
@ -307,7 +296,8 @@ would put a single object in:
##### The `id` property ##### The `id` property
Every object has a special property called `id` that can be assigned to give Every object has a special property called `id` that can be assigned to give
the object a name it can be referred to throughout the current file. The id must be lowercase. the object a name that it can be referred to throughout the current file.
The id must be lowercase.
```qml ```qml
@@QtQuick.Layouts.ColumnLayout { @@QtQuick.Layouts.ColumnLayout {
@ -323,7 +313,7 @@ the object a name it can be referred to throughout the current file. The id must
} }
``` ```
<Collapsible title="The `id` property compared to normal properties"> <Collapsible title="How is the `id` property different from normal properties?">
The `id` property isn't really a property, and doesn't do anything other than The `id` property isn't really a property, and doesn't do anything other than
expose the object to the current file. It is only called a property because it expose the object to the current file. It is only called a property because it
@ -385,14 +375,14 @@ all other objects, you should refer to them by id when accessing properties.
``` ```
<span class="small"> <span class="small">
[Qt Documentation: Scope and Naming See also: [Qt Documentation: Scope and Naming
Resolution](https://doc.qt.io/qt-6/qtqml-documents-scope.html) Resolution](https://doc.qt.io/qt-6/qtqml-documents-scope.html)
</span> </span>
#### Functions #### Functions
Functions in QML can be declared everywhere [properties](#properties) can, and follow Functions in QML can be declared everywhere [properties](#properties),
the same [scoping rules](#property-access-scopes). and follow the same [scoping rules](#property-access-scopes).
Function definition syntax: Function definition syntax:
@ -426,7 +416,7 @@ every expression depending on the function is also re-evaluated.
``` ```
In this example, every time the button is clicked, the label's count increases In this example, every time the button is clicked, the label's count increases
by one, as `clicks` is changed, which triggers a re-evaluation of `text` through by one as the value of `clicks` is changed, triggering a re-evaluation of `text` through
`makeClicksLabel`. `makeClicksLabel`.
##### Lambdas ##### Lambdas
@ -497,7 +487,7 @@ They can be declared everywhere [properties](#properties) and [functions](#funct
can, and follow the same [scoping rules](#property-access-scopes). can, and follow the same [scoping rules](#property-access-scopes).
<span class="small"> <span class="small">
[Qt Documentation: Signal and Handler Event See also: [Qt Documentation: Signal and Handler Event
System](https://doc.qt.io/qt-6/qtqml-syntax-signals.html) System](https://doc.qt.io/qt-6/qtqml-syntax-signals.html)
</span> </span>
@ -541,24 +531,24 @@ or signal when the signal is emitted.
<span class="small"> <span class="small">
`Component.onCompleted` will be addressed later in [Attached `Component.onCompleted` will be addressed later in [Attached
Properties](#attached-properties) but for now just know that it runs Properties](#attached-properties), but for now, just know that it runs
immediately once the object is fully initialized. immediately once the object is fully initialized.
</span> </span>
When the button is clicked, the button emits the @@QtQuick.Controls.Button.clicked(s) When the button is clicked, the button emits the @@QtQuick.Controls.Button.clicked(s)
signal which we connected to `updateText`. The signal then invokes `updateText` signal, which we connected to `updateText`. The signal then invokes `updateText`,
which updates the counter and the text on the label. which updates the counter and the text on the label.
##### Signal handlers ##### Signal handlers
Signal handlers are a more concise way to make a connections, and prior examples have used them. Signal handlers are a more concise way to make connections, and prior examples have used them.
When creating an object, for every signal present on its type there is a corresponding `on<Signal>` When creating an object, there is a corresponding `on<Signal>` property implicitly defined for every
property implicitly defined which can be set to a function. (Note that the first letter of the signal present on its type, which can be set to a function. Do note that the first letter of the
signal's name it capitalized.) signal's name is capitalized.
Below is the same example as in [Making Connections](#making-connections), Below is the same example from [Making Connections](#making-connections), but this time,
this time using the implicit signal handler property to handle @@QtQuick.Controls.Button.clicked(s). using the implicit signal handler property to handle @@QtQuick.Controls.Button.clicked(s).
```qml ```qml
@@QtQuick.Layouts.ColumnLayout { @@QtQuick.Layouts.ColumnLayout {
@ -583,10 +573,10 @@ this time using the implicit signal handler property to handle @@QtQuick.Control
##### Indirect signal handlers ##### Indirect signal handlers
When it is not possible or not convenient to directly define a signal handler, before resorting Signal handlers should be preferred, but there are times where it is not possible or inconvenient to define one.
to `.connect`ing the properties, a @@QtQml.Connections object can be used to access them. In those cases, before resorting to `.connect`ing the properties, a @@QtQml.Connections object can be used to access them.
This is especially useful to connect to signals of singletons. This is especially useful to connect to signals of a Singleton.
```qml ```qml
@@QtQuick.Item { @@QtQuick.Item {
@ -610,8 +600,8 @@ This is especially useful to connect to signals of singletons.
Every property has an associated signal, which powers QML's [reactive bindings](#reactive-bindings). Every property has an associated signal, which powers QML's [reactive bindings](#reactive-bindings).
The signal is named `<propertyname>Changed` and works exactly the same as any other signal. The signal is named `<propertyname>Changed` and works exactly the same as any other signal.
Whenever the property is re-evaluated, its change signal is emitted. This is used internally When it is not possible or inconvenient to directly define a signal handler, before resorting
to update dependent properties, but can be directly used, usually with a signal handler. to `.connect`ing the properties, a @@QtQml.Connections object can be used to access them.
```qml ```qml
@@QtQuick.Layouts.ColumnLayout { @@QtQuick.Layouts.ColumnLayout {
@ -634,10 +624,10 @@ to update dependent properties, but can be directly used, usually with a signal
} }
``` ```
In this example we listen for changes to the @@QtQuick.Controls.CheckBox.checkState property of the CheckBox In this example, we listen for changes to the @@QtQuick.Controls.CheckBox.checkState property of the CheckBox
using its change signal, `checkStateChanged` with the signal handler `onCheckStateChanged`. using its change signal, `checkStateChanged` with the signal handler `onCheckStateChanged`.
Since text is also a property we can do the same thing more concisely: Since text is also a property, we can do the same thing more concisely:
```qml ```qml
@@QtQuick.Layouts.ColumnLayout { @@QtQuick.Layouts.ColumnLayout {
@ -690,6 +680,8 @@ properties, functions and signals.
A good example is the @@QtQml.Component type, A good example is the @@QtQml.Component type,
which is attached to every object and often used to run code when an object initializes. which is attached to every object and often used to run code when an object initializes.
In this example, the text property is set inside the `Component.onCompleted` attached signal handler.
```qml ```qml
@@QtQuick.Text { @@QtQuick.Text {
Component.onCompleted: { Component.onCompleted: {
@ -698,12 +690,10 @@ which is attached to every object and often used to run code when an object init
} }
``` ```
In this example, the text property is set inside the `Component.onCompleted` attached signal handler.
#### Creating types #### Creating types
Every QML file with an uppercase name is implicitly a type, and can be used from Every QML file with an uppercase name is implicitly a type, and can be used from
neighboring files or imported (See [Imports](#imports).) neighboring files or imported. (See [Imports](#imports).)
A type definition is just a normal object. All properties defined for the root object A type definition is just a normal object. All properties defined for the root object
are visible to the consumer of the type. Objects identified by [id properties](#the-id-property) are visible to the consumer of the type. Objects identified by [id properties](#the-id-property)
@ -776,11 +766,10 @@ Example of an inline component:
##### Singletons ##### Singletons
QML Types can be easily made into a singleton, meaning there is only one instance QML Types can be easily made into a Singleton, meaning there is only one instance of the type.
of the type.
To make a type a singleton, put `pragma Singleton` at the top of the file. To make a type of a Singleton, put `pragma Singleton` at the top of the file.
To ensure it behaves correctly with quickshell you should also make To ensure it behaves correctly with Quickshell, you should also make the
@@Quickshell.Singleton the root item of your type. @@Quickshell.Singleton the root item of your type.
```qml ```qml
@ -792,7 +781,7 @@ import ...
} }
``` ```
once a type is a singleton, its members can be accessed by name from neighboring Once a type is a Singleton, its members can be accessed by name from neighboring
files. files.
## Concepts ## Concepts
@ -815,7 +804,7 @@ Bindings can be created in two different ways:
##### Automatic bindings ##### Automatic bindings
A reactive binding occurs automatically when you use one or more properties in the definition A reactive binding occurs automatically when you use one or more properties in the definition
of another property. . of another property.
```qml ```qml
@@QtQuick.Item { @@QtQuick.Item {
@ -851,7 +840,7 @@ as assignments to properties do not create binding.
##### Manual bindings ##### Manual bindings
Sometimes (not often) you need to create a binding inside of a function, signal, or expression. Occasionally, a binding might need to be created inside of a function, signal, or expression.
If you need to change or attach a binding at runtime, the `Qt.binding` function can be used to If you need to change or attach a binding at runtime, the `Qt.binding` function can be used to
create one. create one.
@ -906,11 +895,10 @@ it will not be updated further by the binding.
### Lazy loading ### Lazy loading
Often not all of your interface needs to load immediately. By default the QML Often, not all of your interface needs to load immediately. By default, the QML engine
engine initializes every object in the scene before showing anything onscreen. initializes every object in the scene before showing anything onscreen. For parts of
For parts of the interface you don't need to be immediately visible, load them the interface you don't need to be immediately visible, load them asynchronously using
asynchronously using a @@Quickshell.LazyLoader. a @@Quickshell.LazyLoader. See its documentation for more information.
See its documentation for more information.
#### Components #### Components

View file

@ -3,40 +3,43 @@ title: "Item Size and Position"
index: 2 index: 2
--- ---
> [!TIP] > [!TIP]
> Read the entire page, understanding this is critical to building a well designed shell. > Read the entire page, as understanding this is critical to building a well designed shell.
@@QtQuick.Item has two sets of size properties, actual size (@@QtQuick.Item.width and @@QtQuick.Item.height) An @@QtQuick.Item (and its subclasses) has two sets of size properties:
and implicit / desired (@@QtQuick.Item.implicitWidth and @@QtQuick.Item.implicitHeight). - actual size (@@QtQuick.Item.width and @@QtQuick.Item.height)
- implicit/desired size (@@QtQuick.Item.implicitWidth and @@QtQuick.Item.implicitHeight)
Container items, such as layouts and wrappers, use the implicit size of their children to determine Container items, such as layouts and wrappers, use the implicit size of their children
their own implicit size, and their actual size to detetermine the actual size of their children. to determine their own implicit size. They use their actual size to determine the sizes
If managed by a container, an Item should not set its own size, and should instead allow of their children.
the container to determine it based on its implicit size.
Put simply, implicit size should flow from children to parents, while actual size should flow from If an Item is managed by a container, it should not set its own size. Instead, it should
parent to children. allow the container to determine its size based on its implicit size.
In addition to size, Items also have position properties (@@QtQuick.Item.x and @@QtQuick.Item.y). In other words, implicit size should flow from children to parent, while actual size
Similarly to actual size, (actual) position should not be set directly if your item is managed should flow from parent to children.
by a container, though there is no such thing as implicit position.
In addition to size, Items also have positional properties (@@QtQuick.Item.x and @@QtQuick.Item.y).
Similar to actual size, the actual position should not be set directly if the item is managed by
a container, though there is no such thing as implicit position.
> [!WARNING] > [!WARNING]
> Many QtQuick Items have *zero size* by default (both implicit and actual). > Many QtQuick Items have *zero size* by default (both implicit and actual).
> >
> An invisible zero sized item (usually a custom container without implicit size set) > An invisible, zero-sized item, which is usually a custom container without implicit size set,
> is a common bug and often manifests as an item being laid out as if it took no space. > is a common bug and often manifests as an item being laid out as if it took no space.
> >
> Quickshell will attempt to detect zero sized items when a window is initially made visible > Quickshell will attempt to detect zero-sized items when a window is initially made visible
> and log a warning, but it cannot detect all cases. Please be aware these exist. > and log a warning, but it cannot detect all cases. Please be aware that these exist.
## Container Items ## Container Items
Below is an example container which adds a margin to a rectangle, and interacts properly Below is an example container that adds a margin to its child rectangle and interacts properly
with other container types. with other container types.
```qml ```qml
@@QtQuick.Item { @@QtQuick.Item {
property real margin: 5 property real margin: 5
// Set the implicit size of the containing item to the size of // Set the implicit size of the containing item to the size of
// the contained item, plus the margin on each side. // the contained item, plus the margin on each side.
implicitWidth: child.implicitWidth + margin * 2 implicitWidth: child.implicitWidth + margin * 2
@ -53,7 +56,7 @@ with other container types.
y: parent.margin y: parent.margin
width: parent.width - parent.margin * 2 width: parent.width - parent.margin * 2
height: parent.height - parent.margin * 2 height: parent.height - parent.margin * 2
// The child's implicit / desired size, which will be respected // The child's implicit / desired size, which will be respected
// by the container item as long as it is not constrained // by the container item as long as it is not constrained
// or stretched. // or stretched.
@ -85,7 +88,10 @@ to control the child item's actual size and position.
@@QtQuick.Binding { wrapper.child.height: wrapper.height - wrapper.margin * 2 } @@QtQuick.Binding { wrapper.child.height: wrapper.height - wrapper.margin * 2 }
} }
``` ```
Note: @@Quickshell.Widgets.WrapperItem is a builtin component that adds margins similarly to this.
> [!TIP]
> Quickshell has a builtin component @@Quickshell.Widgets.WrapperItem
> that adds margins similar to the behavior above.
### Reducing boilerplate with Anchors ### Reducing boilerplate with Anchors
We can reduce the amount of boilerplate we have to write using We can reduce the amount of boilerplate we have to write using
@ -99,7 +105,7 @@ position and size directly. A similar change can be made to the `Binding` exampl
```qml ```qml
@@QtQuick.Item { @@QtQuick.Item {
property real margin: 5 property real margin: 5
implicitWidth: child.implicitWidth + margin * 2 implicitWidth: child.implicitWidth + margin * 2
implicitHeight: child.implicitHeight + margin * 2 implicitHeight: child.implicitHeight + margin * 2
@ -110,7 +116,7 @@ position and size directly. A similar change can be made to the `Binding` exampl
anchors.fill: parent anchors.fill: parent
// Add a margin to all anchored sides. // Add a margin to all anchored sides.
anchors.margins: parent.margin anchors.margins: parent.margin
implicitWidth: 50 implicitWidth: 50
implicitHeight: 50 implicitHeight: 50
} }
@ -125,7 +131,7 @@ to determine the size of a child item, such as in the example below:
@@QtQuick.Item { @@QtQuick.Item {
implicitWidth: childrenRect.width implicitWidth: childrenRect.width
implicitHeight: childrenRect.height implicitHeight: childrenRect.height
@@QtQuick.Rectangle { @@QtQuick.Rectangle {
anchors.fill: parent anchors.fill: parent
@ -139,11 +145,11 @@ While the snippet above might look like it should work, it is actually hiding a
As stated at the top of the page, an item's implicit size should be used to determine As stated at the top of the page, an item's implicit size should be used to determine
its parent's implicit size, and the parent's actual size should be used to determine its parent's implicit size, and the parent's actual size should be used to determine
the child's actual size. **`childrenRect` breaks this pattern.** the child's actual size. The **`childrenRect` breaks this pattern.**
`childrenRect` encompasses the geometry of all child items, meaning their *actual* geometry, The `childrenRect` property represents the *actual* geometry of all child items, not their
not their *implicit* geometry. This results in the container item's size having an indirect *implicit* geometry. This results in the container item's size having an indirect dependency
dependency on itself, in what is known as a *binding loop*. on itself, which is known as a *binding loop*.
If we were to try to figure out what implicitWidth is by hand, it would look something like this: If we were to try to figure out what implicitWidth is by hand, it would look something like this:
@ -153,7 +159,7 @@ If we were to try to figure out what implicitWidth is by hand, it would look som
which isn't a valid definition. which isn't a valid definition.
### MarginWrapper components ### MarginWrapper components
To solve the boilerplate problem that often leads users to `childrenRect`, Quickshell comes with To solve the boilerplate problem, which often leads users to use `childrenRect`, Quickshell comes with
@@Quickshell.Widgets.MarginWrapperManager and a set of components based on it. @@Quickshell.Widgets.MarginWrapperManager and a set of components based on it.
@@Quickshell.Widgets.MarginWrapperManager automatically handles the size and position relationship @@Quickshell.Widgets.MarginWrapperManager automatically handles the size and position relationship
@ -164,7 +170,7 @@ Rewriting the examples from the top of the page:
```qml ```qml
@@QtQuick.Item { @@QtQuick.Item {
@@Quickshell.Widgets.MarginWrapperManager { margin: 5 } @@Quickshell.Widgets.MarginWrapperManager { margin: 5 }
// Automatically detected by MarginWrapperManager as the // Automatically detected by MarginWrapperManager as the
// primary child of the container and sized accordingly. // primary child of the container and sized accordingly.
@@QtQuick.Rectangle { @@QtQuick.Rectangle {
@ -180,7 +186,7 @@ Or as a reusable component:
// A bidirectional binding to manager.margin, // A bidirectional binding to manager.margin,
// where the default value is set. // where the default value is set.
property alias margin: manager.margin property alias margin: manager.margin
// MarginWrapperManager tries to automatically detect // MarginWrapperManager tries to automatically detect
// the primary child of the container, but exposing the // the primary child of the container, but exposing the
// child property allows us to both access the child // child property allows us to both access the child
@ -207,8 +213,8 @@ to the example above:
QtQuick comes with a set of layout types in the QtQuick comes with a set of layout types in the
[QtQuick.Layouts](https://doc.qt.io/qt-6/qtquicklayouts-overview.html) module. [QtQuick.Layouts](https://doc.qt.io/qt-6/qtquicklayouts-overview.html) module.
Layouts, such as the Row, Column and Grid layout, are extremely useful for positioning Layouts, such as the Row, Column, and Grid layout, are extremely useful for positioning
items adjacent to eachother. See the linked qt documentation for more details. items adjacent to each other. See the linked Qt documentation for more details.
> [!NOTE] > [!NOTE]
> - Layouts have a default spacing of 5 pixels between items, not zero. > - Layouts have a default spacing of 5 pixels between items, not zero.