add quicklaunch (Dolphin, Firefox)
This commit is contained in:
@@ -5,7 +5,7 @@ A bottom desktop-environment panel for wlroots-based compositors, built on
|
|||||||
|
|
||||||
| Section | Contents |
|
| Section | Contents |
|
||||||
| ------- | ----------------------------------------------------------------- |
|
| ------- | ----------------------------------------------------------------- |
|
||||||
| Left | Application menu built from `.desktop` entries, with search |
|
| Left | Application menu built from `.desktop` entries, with search, and pinned quick-launch icons |
|
||||||
| Middle | Open windows (task list), click to focus, middle-click to close |
|
| Middle | Open windows (task list), click to focus, middle-click to close |
|
||||||
| Right | On-screen keyboard, wifi, bluetooth, and a session menu: log out, suspend, restart, shut down |
|
| Right | On-screen keyboard, wifi, bluetooth, and a session menu: log out, suspend, restart, shut down |
|
||||||
|
|
||||||
@@ -122,6 +122,12 @@ The launcher is a full-screen overlay layer surface rather than an
|
|||||||
`xdg-popup`, which is what makes click-away dismissal and keyboard focus work on
|
`xdg-popup`, which is what makes click-away dismissal and keyboard focus work on
|
||||||
any wlroots compositor without compositor-specific focus grabs.
|
any wlroots compositor without compositor-specific focus grabs.
|
||||||
|
|
||||||
|
**Quick launch.** The ids in `quickLaunch` are pinned as icons next to the app
|
||||||
|
menu, in the order listed, and clicking one launches that entry exactly as the
|
||||||
|
menu would — field codes stripped, `Terminal=true` honoured, and its own systemd
|
||||||
|
scope when the panel is a unit. An id that is not installed is skipped rather
|
||||||
|
than left as a dead button, so the same list can be carried between machines.
|
||||||
|
|
||||||
**On-screen keyboard.** One button shows squeekboard, another click hides it,
|
**On-screen keyboard.** One button shows squeekboard, another click hides it,
|
||||||
and the button is accented while the keyboard is up. squeekboard runs as a
|
and the button is accented while the keyboard is up. squeekboard runs as a
|
||||||
systemd user unit (`oskUnit`, `squeekboard.service` by default): showing starts
|
systemd user unit (`oskUnit`, `squeekboard.service` by default): showing starts
|
||||||
@@ -196,6 +202,9 @@ running with `qs --path .`).
|
|||||||
small output still gets a usable menu.
|
small output still gets a usable menu.
|
||||||
- `terminal` — argv prefix for entries with `Terminal=true`. Honours
|
- `terminal` — argv prefix for entries with `Terminal=true`. Honours
|
||||||
`$TERMINAL`; otherwise change the `["foot"]` fallback to your terminal.
|
`$TERMINAL`; otherwise change the `["foot"]` fallback to your terminal.
|
||||||
|
- `quickLaunch` — desktop entry ids pinned next to the app menu, in order.
|
||||||
|
Defaults to `["firefox", "org.kde.dolphin"]`; set `[]` for none. The ids are
|
||||||
|
desktop file names without the extension (`ls /usr/share/applications`).
|
||||||
- `showOsk` — set `false` to drop the on-screen keyboard button entirely.
|
- `showOsk` — set `false` to drop the on-screen keyboard button entirely.
|
||||||
- `oskUnit` — the systemd user unit squeekboard runs as.
|
- `oskUnit` — the systemd user unit squeekboard runs as.
|
||||||
- `showWifi` — set `false` to drop the wifi button entirely.
|
- `showWifi` — set `false` to drop the wifi button entirely.
|
||||||
@@ -223,6 +232,7 @@ modules/Bar.qml The panel window and its three sections
|
|||||||
modules/AppMenu.qml Left: launcher button
|
modules/AppMenu.qml Left: launcher button
|
||||||
modules/Launcher.qml The application menu overlay
|
modules/Launcher.qml The application menu overlay
|
||||||
modules/AppEntry.qml One row in the menu
|
modules/AppEntry.qml One row in the menu
|
||||||
|
modules/QuickLaunch.qml Left: pinned app icons
|
||||||
modules/WindowList.qml Middle: task list
|
modules/WindowList.qml Middle: task list
|
||||||
modules/WindowButton.qml One task button
|
modules/WindowButton.qml One task button
|
||||||
modules/OskMenu.qml Right: on-screen keyboard button
|
modules/OskMenu.qml Right: on-screen keyboard button
|
||||||
@@ -287,6 +297,11 @@ components/ToggleSwitch.qml On/off switch
|
|||||||
how the panel notices squeekboard going away, since it does not announce that
|
how the panel notices squeekboard going away, since it does not announce that
|
||||||
itself — would never arrive. Showing retries the call for a few seconds
|
itself — would never arrive. Showing retries the call for a few seconds
|
||||||
because the unit goes active a moment before squeekboard claims its name.
|
because the unit goes active a moment before squeekboard claims its name.
|
||||||
|
- The quick-launch icons resolve their ids by scanning `DesktopEntries` rather
|
||||||
|
than calling `byId`. A function call in a binding creates no dependency on the
|
||||||
|
model, so it would be evaluated once against a still-empty entry list and stay
|
||||||
|
empty; scanning `applications.values` makes the binding re-run when the scan
|
||||||
|
finishes, and when an app is installed or removed later.
|
||||||
- `qs ipc call` cannot reach a handler function named `show`: the name collides
|
- `qs ipc call` cannot reach a handler function named `show`: the name collides
|
||||||
with the `ipc show` subcommand and the call silently turns into a listing. The
|
with the `ipc show` subcommand and the call silently turns into a listing. The
|
||||||
`osk` target uses `open` and `close` instead, which matches the menu targets
|
`osk` target uses `open` and `close` instead, which matches the menu targets
|
||||||
|
|||||||
@@ -57,6 +57,14 @@ Singleton {
|
|||||||
// is not already up; hiding it leaves the unit running.
|
// is not already up; hiding it leaves the unit running.
|
||||||
readonly property string oskUnit: "squeekboard.service"
|
readonly property string oskUnit: "squeekboard.service"
|
||||||
|
|
||||||
|
// ---- Quick launch ----------------------------------------------------
|
||||||
|
|
||||||
|
// Desktop entry ids pinned next to the app menu, in the order given. An id
|
||||||
|
// this machine does not have installed is skipped rather than left as a
|
||||||
|
// dead button, so one list can be carried between machines. A trailing
|
||||||
|
// ".desktop" is accepted.
|
||||||
|
readonly property var quickLaunch: ["firefox", "org.kde.dolphin"]
|
||||||
|
|
||||||
// ---- Wifi ------------------------------------------------------------
|
// ---- Wifi ------------------------------------------------------------
|
||||||
|
|
||||||
// Set false to drop the wifi button. It also hides itself where there is no
|
// Set false to drop the wifi button. It also hides itself where there is no
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ PanelWindow {
|
|||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QuickLaunch {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
|
||||||
WindowList {
|
WindowList {
|
||||||
bar: bar
|
bar: bar
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
import qs.config
|
||||||
|
import qs.components
|
||||||
|
import qs.services
|
||||||
|
|
||||||
|
// Left section, right of the app menu: one icon per pinned desktop entry.
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
// Resolved from the ids in Config.quickLaunch, in the order given, minus
|
||||||
|
// whatever this machine does not have installed.
|
||||||
|
//
|
||||||
|
// A scan rather than DesktopEntries.byId: the binding then depends on the
|
||||||
|
// model itself, so the icons appear when the initial scan finishes and
|
||||||
|
// follow an app being installed or removed. A function call would be
|
||||||
|
// evaluated once against an empty model and stay that way.
|
||||||
|
readonly property var entries: {
|
||||||
|
const apps = [...DesktopEntries.applications.values];
|
||||||
|
|
||||||
|
return Config.quickLaunch.map(id => {
|
||||||
|
const wanted = id.replace(/\.desktop$/, "").toLowerCase();
|
||||||
|
return apps.find(e => (e.id || "").toLowerCase() === wanted) ?? null;
|
||||||
|
}).filter(e => e !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
visible: root.entries.length > 0
|
||||||
|
implicitWidth: row.implicitWidth
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: row
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacing
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.entries
|
||||||
|
|
||||||
|
PanelButton {
|
||||||
|
id: button
|
||||||
|
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
height: root.height - Theme.spacing
|
||||||
|
minContentWidth: Theme.iconSize
|
||||||
|
|
||||||
|
onClicked: AppLauncher.launch(button.modelData)
|
||||||
|
|
||||||
|
// Content is reparented into the button's holder, so the entry
|
||||||
|
// is reached through the button's id rather than `parent`.
|
||||||
|
AppIcon {
|
||||||
|
icon: button.modelData.icon
|
||||||
|
fallbackLabel: button.modelData.name
|
||||||
|
size: Theme.iconSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user