Compare commits

...

6 commits

Author SHA1 Message Date
b69c1336c9
add about page 2025-06-08 01:53:24 -07:00
8fb7df4d6a
faq: add icon fallback 2025-06-07 21:31:31 -07:00
f0e3b46627
document inline components
Also remove MD_Title elements
2025-06-07 21:12:20 -07:00
7fd6f30fc2
add faq entries 2025-06-07 20:56:56 -07:00
d826bce7b3
modernize introduction somewhat
At least it no longer recommends deprecated types.
2025-06-07 17:23:18 -07:00
12f0b899d2
set up caddy redirects 2025-06-07 13:44:23 -07:00
11 changed files with 384 additions and 240 deletions

View file

@ -75,5 +75,9 @@ in {
HOME=$(pwd)/garbage-tooling yarn build HOME=$(pwd)/garbage-tooling yarn build
''; '';
installPhase = "mv dist $out"; installPhase = ''
mkdir -p $out
mv redirects.caddy $out
mv dist $out/site
'';
}) })

5
redirects.caddyfile Normal file
View file

@ -0,0 +1,5 @@
redir /docs/configuration/getting-started* /docs/guide/install-setup permanent
redir /docs/configuration/intro* /docs/guide/introduction permanent
redir /docs/configuration/positioning* /docs/guide/size-position permanent
redir /docs/configuration/qml-overview* /docs/guide/qml-language permanent
redir /docs/configuration* /docs/guide permanent

View file

@ -1,8 +1,8 @@
--- ---
export interface Props { export interface Props {
currentRoute: string; currentRoute?: string;
currentModule: string; currentModule?: string;
currentClass: string; currentClass?: string;
} }
const { currentRoute, currentModule, currentClass } = Astro.props; const { currentRoute, currentModule, currentClass } = Astro.props;
@ -36,14 +36,14 @@ function genGuideNav(base: string): TreeEntry[] | undefined {
const guide = { const guide = {
title: "Usage Guide", title: "Usage Guide",
link: "/docs/guide", link: "/docs/guide",
current: currentRoute.startsWith("guide"), current: currentRoute?.startsWith("guide") ?? false,
entries: genGuideNav(""), entries: genGuideNav(""),
} }
const types = { const types = {
title: "Quickshell Types", title: "Quickshell Types",
link: "/docs/types", link: "/docs/types",
current: currentRoute.startsWith("types"), current: currentRoute?.startsWith("types") ?? false,
entries: Object.entries(groupedRoutes.types).map( entries: Object.entries(groupedRoutes.types).map(
([module, items]) => ({ ([module, items]) => ({
title: module, title: module,
@ -59,6 +59,11 @@ const types = {
}; };
--- ---
<nav class="navtree"> <nav class="navtree">
<Link
title="About Quickshell"
link="/docs/about"
current={currentRoute === "about"}
/>
<Tree {...guide}/> <Tree {...guide}/>
<Tree {...types}/> <Tree {...types}/>
<Link <Link

View file

@ -32,7 +32,7 @@ const remarkParseAtTypes: RemarkPlugin<[]> = () => {
const node = rawNode as Md.Literal; const node = rawNode as Md.Literal;
node.value = node.value.replace( node.value = node.value.replace(
/@@((?<module>([A-Z]\w*\.)*)(?<type>([A-Z]\w*))\.?)?((?<member>[a-z]\w*)((?<function>\(\))|(?<signal>\(s\)))?)?(?=[$.,;:)\s]|$)/g, /@@((?<module>([A-Z]\w*\.)*)(?<type>([A-Z]\w*))(\.(?!\s|$))?)?((?<member>[a-z]\w*)((?<function>\(\))|(?<signal>\(s\)))?)?(?=[$.,;:)\s]|$)/g,
(_full, ...args) => { (_full, ...args) => {
type Capture = { type Capture = {
module: string | undefined; module: string | undefined;

View file

@ -12,6 +12,28 @@ Make sure to also read the [Item Size and Position](/docs/guide/size-position) a
## How do I ## How do I
### Reduce memory usage
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,
and destroy them when not needed.
- Use @@QtQuick.Loader when the component being loaded inherits from @@QtQuick.Item.
- Use @@Quickshell.LazyLoader in other cases.
### Show widgets conditionally
The @@QtQuick.Item.visible property can be used to change the visibility of an
Item conditionally, as well as Loaders.
Note that you can change out a loader's component conditionally:
```qml
@@QtQuick.Loader {
readonly property Component thing1: ...
readonly property Component thing2: ...
sourceComponent: condition ? thing1 : thing2
}
```
### 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 ones with a rounded rectangle
inside of them. inside of them.
@ -29,3 +51,30 @@ inside of them.
} }
} }
``` ```
### Get rid of the purple/black icons
The @@Quickshell.Quickshell.iconPath() function has three variants:
- One draws a purple/black square if the icon is missing.
- One allows you to specify a fallback icon if the desired one is missing.
- One returns an empty string if the icon is missing.
Either of the last two variants can be used to avoid the purple/black square.
## Something is broken
### There is a hole in my window
If you set a Rectangle's color to `"transparent"` and touch its `border` property,
you'll hit [QTBUG-137166](https://bugreports.qt.io/browse/QTBUG-137166), which
causes everything under the transparent rectangle to become invisible.
Adding a definition like `border.width: 0` seems to work around it, especially
if the only border property you wanted to set was radius.
### My window should not be opaque
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
the gpu must do to draw it. If you change the background color of your window
between opaque and transparent colors, this may affect you.
To tell Quickshell to always create a window capable of showing transparency,
use @@Quickshell.QsWindow.surfaceFormat to set `opaque` to false.

View file

@ -3,41 +3,27 @@ title: "Introduction"
index: 2 index: 2
--- ---
import Collapsible from "@components/Collapsible.astro";
# {frontmatter.title} # {frontmatter.title}
> [!NOTE]
> This guide was created a long time ago, and is somewhat outdated.
> Take a look at @@Quickshell.SystemClock after going through.
This page will walk you through the process of creating a simple bar/panel, and This page will walk you through the process of creating a simple bar/panel, and
introduce you to all the basic concepts involved. introduce you to all the basic concepts involved. You can use the
[QML Language Reference](/docs/guide/qml-language) to learn about the syntax
of the QML language.
There are many links to the [QML Overview](/docs/guide/qml-language) Note that all the <a>Green Links</a> in code blocks will take you to the documentation
and [Type Reference](/docs/types) which you should follow if you don't for their respective types.
fully understand the concepts involved.
## Shell Files ## Config Files
Quickshell searches the `quickshell` subfolder of every XDG standard config path
for configs. Usually this is `~/.config/quickshell`.
Every quickshell instance starts from a shell root file, conventionally named `shell.qml`. Each named subfolder containing a `shell.qml` file is considered to be a config.
The default path is `~/.config/quickshell/shell.qml`. If the base `quickshell` folder contains a shell.qml file, subfolders will not be
(where `~/.config` can be substituted with `$XDG_CONFIG_HOME` if present.) considered.
Each shell file starts with the shell root object. Only one may exist per configuration. A specific config can be picked using the `--config` or `-c` argument to Quickshell.
```qml Configs at other paths, including raw qml files can be run with `--path` or `-p`.
// ~/.config/quickshell/shell.qml
import Quickshell
@@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.
## Creating Windows ## Creating Windows
@ -48,11 +34,10 @@ Quickshell has two main window types available,
We'll start with an example: We'll start with an example:
```qml ```qml
import Quickshell // for ShellRoot and PanelWindow import Quickshell // for PanelWindow
import QtQuick // for Text import QtQuick // for Text
@@Quickshell.ShellRoot { @@Quickshell.PanelWindow {
@@Quickshell.PanelWindow {
anchors { anchors {
top: true top: true
left: true left: true
@ -67,20 +52,22 @@ import QtQuick // for Text
text: "hello world" text: "hello world"
} }
}
} }
``` ```
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 lets make a clock. To get the time we'll use the `date` command.
> [!note/Note]
> Quickshell can do more than just run processes. Read until the end for more information.
We can use a [Process](/docs/types/quickshell.io/process) object to run commands We can use a [Process](/docs/types/quickshell.io/process) object to run commands
and return their results. and return their results.
@ -98,8 +85,7 @@ import Quickshell
import Quickshell.Io // for Process import Quickshell.Io // for Process
import QtQuick import QtQuick
@@Quickshell.ShellRoot { @@Quickshell.PanelWindow {
@@Quickshell.PanelWindow {
anchors { anchors {
top: true top: true
left: true left: true
@ -131,7 +117,6 @@ import QtQuick
} }
} }
} }
}
} }
``` ```
@ -145,8 +130,7 @@ import Quickshell
import Quickshell.Io import Quickshell.Io
import QtQuick import QtQuick
@@Quickshell.ShellRoot { @@Quickshell.PanelWindow {
@@Quickshell.PanelWindow {
anchors { anchors {
top: true top: true
left: true left: true
@ -188,7 +172,6 @@ import QtQuick
onTriggered: dateProc.running = true onTriggered: dateProc.running = true
} }
} }
}
} }
``` ```
@ -217,8 +200,7 @@ import Quickshell
import Quickshell.Io import Quickshell.Io
import QtQuick import QtQuick
@@Quickshell.ShellRoot { @@Quickshell.Variants {
@@Quickshell.Variants {
model: Quickshell.screens; model: Quickshell.screens;
delegate: @@QtQml.Component { delegate: @@QtQml.Component {
@ -261,7 +243,6 @@ import QtQuick
} }
} }
} }
}
} }
``` ```
@ -276,8 +257,9 @@ due to the reactive nature of the
(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. We can fix is created multiple times we also make a new Process and Timer, which makes the
this by moving the Process and Timer outside of the window. bar less efficient than it could be. We can fix this by moving the
Process and Timer outside of the window using @@Quickshell.Scope.
> [!caution/Error] > [!caution/Error]
> This code will not work correctly. > This code will not work correctly.
@ -287,7 +269,7 @@ import Quickshell
import Quickshell.Io import Quickshell.Io
import QtQuick import QtQuick
@@Quickshell.ShellRoot { @@Quickshell.Scope {
@@Quickshell.Variants { @@Quickshell.Variants {
model: Quickshell.screens model: Quickshell.screens
@ -338,11 +320,11 @@ _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:
``` ```
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined WARN scene: **/shell.qml[36:-1]: ReferenceError: clock is not defined
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined WARN scene: **/shell.qml[36:-1]: ReferenceError: clock is not defined
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined WARN scene: **/shell.qml[36:-1]: ReferenceError: clock is not defined
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined WARN scene: **/shell.qml[36:-1]: ReferenceError: clock is not defined
file:///home/name/.config/quickshell/shell.qml:33: ReferenceError: clock is not defined WARN scene: **/shell.qml[36:-1]: ReferenceError: clock is not defined
``` ```
This is because the `clock` object, even though it has an ID, cannot be referenced This is because the `clock` object, even though it has an ID, cannot be referenced
@ -362,11 +344,11 @@ import Quickshell
import Quickshell.Io import Quickshell.Io
import QtQuick import QtQuick
@@Quickshell.ShellRoot { @@Quickshell.Scope {
id: root id: root
// add a property in the root // add a property in the root
property string time; property string time
@@Quickshell.Variants { @@Quickshell.Variants {
model: Quickshell.screens model: Quickshell.screens
@ -389,7 +371,7 @@ import QtQuick
anchors.centerIn: parent anchors.centerIn: parent
// bind the text to the root's time property // bind the text to the root object's time property
text: root.time text: root.time
} }
} }
@ -427,9 +409,6 @@ above code, but we can make it more concise:
which means we can skip the `delegate:` part of the assignment. which means we can skip the `delegate:` part of the assignment.
We're already using the default property of @@Quickshell.ShellRoot to store our We're already using the default property of @@Quickshell.ShellRoot to store our
Variants, Process, and Timer components among other things. Variants, Process, and Timer components among other things.
3. The ShellRoot doesn'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: This is what our shell looks like with the above (optional) cleanup:
@ -438,8 +417,9 @@ import Quickshell
import Quickshell.Io import Quickshell.Io
import QtQuick import QtQuick
@@Quickshell.ShellRoot { @@Quickshell.Scope {
property string time; id: root
property string time
@@Quickshell.Variants { @@Quickshell.Variants {
model: Quickshell.screens model: Quickshell.screens
@ -458,9 +438,7 @@ import QtQuick
@@QtQuick.Text { @@QtQuick.Text {
anchors.centerIn: parent anchors.centerIn: parent
text: root.time
// now just time instead of root.time
text: time
} }
} }
} }
@ -471,8 +449,7 @@ import QtQuick
running: true running: true
stdout: @@Quickshell.Io.SplitParser { stdout: @@Quickshell.Io.SplitParser {
// now just time instead of root.time onRead: data => root.time = data
onRead: data => time = data
} }
} }
@ -496,7 +473,7 @@ To start with, let's move the entire bar into a new file.
// shell.qml // shell.qml
import Quickshell import Quickshell
@@Quickshell.ShellRoot { @@Quickshell.Scope {
Bar {} Bar {}
} }
``` ```
@ -508,7 +485,8 @@ import Quickshell.Io
import QtQuick import QtQuick
@@Quickshell.Scope { @@Quickshell.Scope {
property string time; id: root
property string time
@@Quickshell.Variants { @@Quickshell.Variants {
model: Quickshell.screens model: Quickshell.screens
@ -527,9 +505,7 @@ import QtQuick
@@QtQuick.Text { @@QtQuick.Text {
anchors.centerIn: parent anchors.centerIn: parent
text: root.time
// now just time instead of root.time
text: time
} }
} }
} }
@ -540,8 +516,7 @@ import QtQuick
running: true running: true
stdout: @@Quickshell.Io.SplitParser { stdout: @@Quickshell.Io.SplitParser {
// now just time instead of root.time onRead: data => root.time = data
onRead: data => time = data
} }
} }
@ -589,7 +564,7 @@ import QtQuick
@@Quickshell.Scope { @@Quickshell.Scope {
id: root id: root
property string time; property string time
@@Quickshell.Variants { @@Quickshell.Variants {
model: Quickshell.screens model: Quickshell.screens
@ -609,7 +584,6 @@ import QtQuick
// the ClockWidget type we just created // the ClockWidget type we just created
ClockWidget { ClockWidget {
anchors.centerIn: parent anchors.centerIn: parent
// Warning: setting `time: time` will bind time to itself which is not what we want
time: root.time time: root.time
} }
} }
@ -621,7 +595,7 @@ import QtQuick
running: true running: true
stdout: @@Quickshell.Io.SplitParser { stdout: @@Quickshell.Io.SplitParser {
onRead: data => time = data onRead: data => root.time = data
} }
} }
@ -646,7 +620,8 @@ import Quickshell.Io
import QtQuick import QtQuick
@@Quickshell.Scope { @@Quickshell.Scope {
property string time; id: root
property string time
@@Quickshell.Io.Process { @@Quickshell.Io.Process {
id: dateProc id: dateProc
@ -654,7 +629,7 @@ import QtQuick
running: true running: true
stdout: @@Quickshell.Io.SplitParser { stdout: @@Quickshell.Io.SplitParser {
onRead: data => time = data onRead: data => root.time = data
} }
} }
@ -721,6 +696,7 @@ import QtQuick
// your singletons should always have Singleton as the type // your singletons should always have Singleton as the type
@@Quickshell.Singleton { @@Quickshell.Singleton {
id: root
property string time property string time
@@Quickshell.Io.Process { @@Quickshell.Io.Process {
@ -729,7 +705,7 @@ import QtQuick
running: true running: true
stdout: @@Quickshell.Io.SplitParser { stdout: @@Quickshell.Io.SplitParser {
onRead: data => time = data onRead: data => root.time = data
} }
} }
@ -786,31 +762,39 @@ import Quickshell
} }
``` ```
## JavaScript APIs ## Quickshell Support Libraries
In addition to calling external processes, Quickshell comes with a large set of support libraries
for common OS integrations and tasks. These libraries are indexed on the left sidebar.
In addition to calling external processes, a [limited set of javascript interfaces] is available. One of these integrations is @@Quickshell.SystemClock, which exposes the system time in an easy to
We can use this to improve our clock by using the [Date API] instead of calling `date`. use way.
[limited set of javascript interfaces]: https://doc.qt.io/qt-6/qtqml-javascript-functionlist.html We can use @@Quickshell.SystemClock.date to get a Date object to display. The
[Date API]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date @@QtQml.Qt.formatDateTime() function can be used to easily format the date
as shown below.
@@Quickshell.SystemClock.precision can be set to `Minutes` to improve battery life if you don't
show seconds on your clock, as Quickshell will have less work to do.
```qml ```qml
// Time.qml // Time.qml
pragma Singleton pragma Singleton
import Quickshell import Quickshell
import Quickshell.Io
import QtQuick import QtQuick
@@Quickshell.Singleton { @@Quickshell.Singleton {
property var date: new Date() id: root
property string time: date.toLocaleString(Qt.locale()) // an expression can be broken across multiple lines using {}
readonly property string time: {
// The passed format string matches the default output of
// the `date` command.
Qt.formatDateTime(clock.date, "ddd MMM d hh:mm:ss AP t yyyy")
}
@@QtQml.Timer { @@Quickshell.SystemClock {
interval: 1000 id: clock
running: true precision: SystemClock.Seconds
repeat: true
onTriggered: date = new Date()
} }
} }
``` ```

View file

@ -2,7 +2,6 @@
title: "QML Language" title: "QML Language"
index: 10 index: 10
--- ---
import MD_Title from "@components/MD_Title.tsx"
import Collapsible from "@components/Collapsible.astro"; import Collapsible from "@components/Collapsible.astro";
# {frontmatter.title} # {frontmatter.title}
@ -15,7 +14,7 @@ This page explains what you need to know about QML to start using quickshell.
Tutorial](https://doc.qt.io/qt-6/qml-tutorial.html) Tutorial](https://doc.qt.io/qt-6/qml-tutorial.html)
</span> </span>
## <MD_Title titleVar={2}> Structure </MD_Title> ## Structure
Below is a QML document showing most of the syntax. Below is a QML document showing most of the syntax.
Keep it in mind as you read the detailed descriptions below. Keep it in mind as you read the detailed descriptions below.
@ -87,12 +86,17 @@ import "myjs.js" as MyJs
function dub(x: int): int { function dub(x: int): int {
return x * 2 return x * 2
} }
// Inline component
component MyComponent: Object {
// ...
}
} }
``` ```
### <MD_Title titleVar={3}> Imports </MD_Title> ### Imports
#### <MD_Title titleVar={4}> Manual imports </MD_Title> #### Manual imports
Every QML File begins with a list of imports. Every QML File begins with a list of imports.
Import statements tell the QML engine where Import statements tell the QML engine where
@ -130,7 +134,7 @@ import "<filename>" as <Namespace>
Note: All _Module_ and _Namespace_ names must start with an uppercase letter. Note: All _Module_ and _Namespace_ names must start with an uppercase letter.
Attempting to use a lowercase namespace is an error. Attempting to use a lowercase namespace is an error.
##### <MD_Title titleVar={5}> Examples </MD_Title> ##### Examples
```qml ```qml
import QtQuick import QtQuick
@ -158,7 +162,7 @@ specifying a version at least when importing quickshell modules.
syntax](https://doc.qt.io/qt-6/qtqml-syntax-imports.html) syntax](https://doc.qt.io/qt-6/qtqml-syntax-imports.html)
</span> </span>
#### <MD_Title titleVar={4}> Implicit imports </MD_Title> #### Implicit imports
The QML engine will automatically import any [types](#creating-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. with names that start with an uppercase letter.
@ -172,7 +176,7 @@ root
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.
### <MD_Title titleVar={3}> Objects </MD_Title> ### Objects
Objects are instances of a type from an imported module. Objects are instances of a type from an imported module.
The name of an object must start with an uppercase letter. The name of an object must start with an uppercase letter.
@ -191,12 +195,12 @@ Every object can contain [properties](#properties), [functions](#functions),
and [signals](#signals). You can find out what properties are available for a type and [signals](#signals). You can find out what properties are available for a type
by looking it up in the [Type Reference](/docs/types/). by looking it up in the [Type Reference](/docs/types/).
#### <MD_Title titleVar={4}> Properties </MD_Title> #### Properties
Every object may have any number of property assignments (only one per specific property). Every object may have any number of property assignments (only one per specific property).
Each assignment binds the named property to the given expression. Each assignment binds the named property to the given expression.
##### <MD_Title titleVar={5}> Property bindings </MD_Title> ##### 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. The last (or only) line
can be the return value, or an explicit return statement (multiline expressions only) can be used. can be the return value, or an explicit return statement (multiline expressions only) can be used.
@ -235,7 +239,7 @@ on is updated, the expression is re-evaluated and the property is updated.
Note that it is an error to try to assign to a property that does not exist. Note that it is an error to try to assign to a property that does not exist.
(See: [property definitions](#property-definitions)) (See: [property definitions](#property-definitions))
##### <MD_Title titleVar={5}> Property definitions </MD_Title> ##### Property definitions
Properties can be defined inside of objects with the following syntax: Properties can be defined inside of objects with the following syntax:
@ -267,7 +271,7 @@ 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.
##### <MD_Title titleVar={5}> The default property </MD_Title> ##### 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.
@ -302,7 +306,7 @@ would put a single object in:
} }
``` ```
##### <MD_Title titleVar={5}> The `id` property </MD_Title> ##### 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 it can be referred to throughout the current file. The id must be lowercase.
@ -330,7 +334,7 @@ definition rules. The name `id` is always reserved for the id property.
</Collapsible> </Collapsible>
##### <MD_Title titleVar={5}> Property access scopes </MD_Title> ##### Property access scopes
Properties are "in scope" and usable in two cases. Properties are "in scope" and usable in two cases.
@ -343,6 +347,9 @@ or make sure the property you are accessing is from the current object using `th
The `parent` property is also defined for all objects, but may not always point to what it The `parent` property is also defined for all objects, but may not always point to what it
looks like it should. Use the `id` property if `parent` does not do what you want. looks like it should. Use the `id` property if `parent` does not do what you want.
In general, you should only access properties of the *current* object without an id. For
all other objects, you should refer to them by id when accessing properties.
```qml ```qml
@@QtQuick.Item { @@QtQuick.Item {
property string rootDefinition property string rootDefinition
@ -384,7 +391,7 @@ looks like it should. Use the `id` property if `parent` does not do what you wan
Resolution](https://doc.qt.io/qt-6/qtqml-documents-scope.html) Resolution](https://doc.qt.io/qt-6/qtqml-documents-scope.html)
</span> </span>
#### <MD_Title titleVar={4}> Functions </MD_Title> #### Functions
Functions in QML can be declared everywhere [properties](#properties) can, and follow Functions in QML can be declared everywhere [properties](#properties) can, and follow
the same [scoping rules](#property-access-scopes). the same [scoping rules](#property-access-scopes).
@ -424,7 +431,7 @@ 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 `clicks` is changed, which triggers a re-evaluation of `text` through
`makeClicksLabel`. `makeClicksLabel`.
##### <MD_Title titleVar={5}> Lambdas </MD_Title> ##### Lambdas
Functions can also be values, and you can assign them to properties or pass them to Functions can also be values, and you can assign them to properties or pass them to
other functions (callbacks). There is a shorter way to write these functions, known other functions (callbacks). There is a shorter way to write these functions, known
@ -485,7 +492,7 @@ An overcomplicated click counter using a lambda callback:
} }
``` ```
#### <MD_Title titleVar={4}> Signals </MD_Title> #### Signals
A signal is basically an event emitter you can connect to and receive updates from. A signal is basically an event emitter you can connect to and receive updates from.
They can be declared everywhere [properties](#properties) and [functions](#functions) They can be declared everywhere [properties](#properties) and [functions](#functions)
@ -496,7 +503,7 @@ can, and follow the same [scoping rules](#property-access-scopes).
System](https://doc.qt.io/qt-6/qtqml-syntax-signals.html) System](https://doc.qt.io/qt-6/qtqml-syntax-signals.html)
</span> </span>
##### <MD_Title titleVar={5}> Signal definitions </MD_Title> ##### Signal definitions
A signal can be explicitly defined with the following syntax: A signal can be explicitly defined with the following syntax:
@ -504,7 +511,7 @@ A signal can be explicitly defined with the following syntax:
signal <name>(<paramname>: <type>[, ...]) signal <name>(<paramname>: <type>[, ...])
``` ```
##### <MD_Title titleVar={5}> Making connections </MD_Title> ##### Making connections
Signals all have a `connect(<function>)` method which invokes the given function Signals all have a `connect(<function>)` method which invokes the given function
or signal when the signal is emitted. or signal when the signal is emitted.
@ -544,7 +551,7 @@ When the button is clicked, the button emits the @@QtQuick.Controls.Button.click
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.
##### <MD_Title titleVar={5}> Signal handlers </MD_Title> ##### 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 a connections, and prior examples have used them.
@ -576,7 +583,7 @@ this time using the implicit signal handler property to handle @@QtQuick.Control
} }
``` ```
##### <MD_Title titleVar={5}> Indirect signal handlers </MD_Title> ##### Indirect signal handlers
When it is not possible or not convenient to directly define a signal handler, before resorting When it is not possible or not convenient to directly define a signal handler, before resorting
to `.connect`ing the properties, a @@QtQml.Connections object can be used to access them. to `.connect`ing the properties, a @@QtQml.Connections object can be used to access them.
@ -600,7 +607,7 @@ This is especially useful to connect to signals of singletons.
} }
``` ```
##### <MD_Title titleVar={5}> Property change signals </MD_Title> ##### Property change signals
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.
@ -673,7 +680,7 @@ And the function can also be inlined to an expression:
You can also remove the return statement if you wish. You can also remove the return statement if you wish.
##### <MD_Title titleVar={5}> Attached objects </MD_Title> ##### Attached objects
Attached objects are additional objects that can be associated with an object Attached objects are additional objects that can be associated with an object
as decided by internal library code. The documentation for a type will as decided by internal library code. The documentation for a type will
@ -695,7 +702,7 @@ 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. In this example, the text property is set inside the `Component.onCompleted` attached signal handler.
#### <MD_Title titleVar={4}> Creating types </MD_Title> #### 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).)
@ -741,7 +748,35 @@ are not visible outside the file.
} }
``` ```
##### <MD_Title titleVar={5}> Singletons </MD_Title> ##### Inline Components
Inline components work the same as any other type, but are created inside
another QML file. These components only work within the file, and can reference
IDs inside the file.
While inline components can be created anywhere inside a QML file, they are
scoped to the file itself and cannot be nested.
Example of an inline component:
```qml
@@QtQuick.Layouts.ColumnLayout {
id: layout
property real textPointSize: 10
MyText { text: "Thing 1" }
MyText { text: "Thing 2" }
MyText { text: "Thing 3" }
component MyText: @@QtQuick.Text {
// applied to all MyText instances
color: "red"
// references an id outside of the component
font.pointSize: layout.textPointSize
}
}
```
##### 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.
@ -762,9 +797,9 @@ 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.
## <MD_Title titleVar={2}> Concepts </MD_Title> ## Concepts
### <MD_Title titleVar={3}> Reactive bindings </MD_Title> ### Reactive bindings
<span class="small"> <span class="small">
This section assumes knowledge of: [Properties](#properties), This section assumes knowledge of: [Properties](#properties),
@ -779,7 +814,7 @@ are then re-evaluated and so forth.
Bindings can be created in two different ways: Bindings can be created in two different ways:
##### <MD_Title titleVar={5}> Automatic bindings </MD_Title> ##### 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. .
@ -798,7 +833,7 @@ of another property. .
In this example, the button's @@QtQuick.Controls.Button.text property is re-evaluated In this example, the button's @@QtQuick.Controls.Button.text property is re-evaluated
every time the button is clicked, because the `clicks` property has changed. every time the button is clicked, because the `clicks` property has changed.
###### <MD_Title titleVar={6}> Avoiding creation </MD_Title> ###### Avoiding creation
To avoid creating a binding, do not use any other properties in the definition of a property. To avoid creating a binding, do not use any other properties in the definition of a property.
@ -816,7 +851,7 @@ as assignments to properties do not create binding.
} }
``` ```
##### <MD_Title titleVar={5}> Manual bindings </MD_Title> ##### Manual bindings
Sometimes (not often) you need to create a binding inside of a function, signal, or expression. Sometimes (not often) you need to create a binding 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
@ -848,7 +883,7 @@ In this example, `boundText`'s `text` property is bound to the button's pressed
when the button is first clicked. When you press or unpress the button the text will when the button is first clicked. When you press or unpress the button the text will
be updated. be updated.
##### <MD_Title titleVar={5}> Removing bindings </MD_Title> ##### Removing bindings
To remove a binding, just assign a new value to the property without using `Qt.binding`. To remove a binding, just assign a new value to the property without using `Qt.binding`.
@ -871,7 +906,7 @@ When the button is first pressed, the text will be updated, but once `onClicked`
the text will be unbound, and even though it contains a reference to the `pressed` property, the text will be unbound, and even though it contains a reference to the `pressed` property,
it will not be updated further by the binding. it will not be updated further by the binding.
### <MD_Title titleVar={3}> Lazy loading </MD_Title> ### 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 initializes every object in the scene before showing anything onscreen. engine initializes every object in the scene before showing anything onscreen.
@ -879,7 +914,7 @@ For parts of the interface you don't need to be immediately visible, load them
asynchronously using a @@Quickshell.LazyLoader. asynchronously using a @@Quickshell.LazyLoader.
See its documentation for more information. See its documentation for more information.
#### <MD_Title titleVar={4}> Components </MD_Title> #### Components
Another delayed loading mechanism is the @@QtQml.Component type. Another delayed loading mechanism is the @@QtQml.Component type.
This type can be used to create multiple instances of objects or lazily load them. It's used by types such This type can be used to create multiple instances of objects or lazily load them. It's used by types such

View file

@ -0,0 +1,25 @@
---
import DocsLayout from "@layouts/DocsLayout.astro";
import TOC from "@components/navigation/sidebars/TOC.astro";
import TOCIntersectionObserver from "@src/components/hooks/TOCIntersectionObserver.astro";
import type { ConfigHeading } from "@src/components/navigation/sidebars/types";
export interface Props {
headings: ConfigHeading[];
title: string;
description: string;
}
const { title, description, headings } = Astro.props;
---
<DocsLayout title={title} description={description} headings={headings}>
<div class="docs">
<div class="docs-content">
<hr>
<slot/>
</div>
<TOC mobile={false} headings={headings} data-pagefind-ignore/>
</div>
</DocsLayout>
<TOCIntersectionObserver/>

View file

@ -0,0 +1,17 @@
---
import GuideLayout from "@layouts/GuideLayout.astro";
import type { ConfigHeading } from "@src/components/navigation/sidebars/types";
export interface Props {
headings: ConfigHeading[];
frontmatter: {
title: string;
description?: string;
}
}
const { headings, frontmatter: { title, description } } = Astro.props;
---
<GuideLayout title={title} description={description ?? ""} headings={headings}>
<slot/>
</GuideLayout>

30
src/pages/docs/about.mdx Normal file
View file

@ -0,0 +1,30 @@
---
layout: "@layouts/GuideMdLayout.astro"
title: "About Quickshell"
---
# {frontmatter.title}
Quickshell is a toolkit for building a desktop shell, which is to say components
of your desktop like bars, widgets, lock screens, display managers, and the like.
Quickshell is based on QtQuick and configured with QML, the QtQuick interface
description language. It provides integrations for common shell functionality,
as well as support for hot reloading and tools to work with processes,
sockets, files, and more.
Built-in integrations are currently provided for:
- Wayland and X11 for windowing
- Wayland for window management and screen recording
- Workspace management in Hyprland, I3, and Sway
- Pipewire for audio controls
- Pam for authentication and building lockscreens
- Greetd for building a display manager
- UPower for monitoring battery statistics
- Power Profiles Daemon
- MPRIS compatible media players
- StatusNotifierItem compatible system tray clients
Quickshell is actively developed and will still receive breaking changes.
A tagged release is planned soon, however there will be breakage before
that point.
See the [Usage Guide](/docs/guide) to learn how to set up and use Quickshell

View file

@ -1,7 +1,5 @@
--- ---
import DocsLayout from "@layouts/DocsLayout.astro"; import GuideLayout from "@layouts/GuideLayout.astro";
import TOC from "@components/navigation/sidebars/TOC.astro";
import TOCIntersectionObserver from "@src/components/hooks/TOCIntersectionObserver.astro";
import { getCollection, render } from "astro:content"; import { getCollection, render } from "astro:content";
@ -17,14 +15,6 @@ export async function getStaticPaths() {
const { page } = Astro.props; const { page } = Astro.props;
const { Content, headings } = await render(page); const { Content, headings } = await render(page);
--- ---
<DocsLayout title={page.data.title} description="" headings={headings}> <GuideLayout title={page.data.title} description="" headings={headings}>
<div class="docs">
<div class="docs-content">
<hr>
<Content/> <Content/>
</div> </GuideLayout>
<TOC mobile={false} headings={headings} data-pagefind-ignore/>
</div>
</DocsLayout>
<TOCIntersectionObserver/>