dock
This commit is contained in:
+2
-1
@@ -160,7 +160,8 @@ Singleton {
|
|||||||
hoverRegionHeight: dock.hoverRegionHeight,
|
hoverRegionHeight: dock.hoverRegionHeight,
|
||||||
hoverToReveal: dock.hoverToReveal,
|
hoverToReveal: dock.hoverToReveal,
|
||||||
pinnedApps: dock.pinnedApps,
|
pinnedApps: dock.pinnedApps,
|
||||||
pinnedOnStartup: dock.pinnedOnStartup
|
pinnedOnStartup: dock.pinnedOnStartup,
|
||||||
|
ignoredAppRegexes: dock.ignoredAppRegexes
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ JsonObject {
|
|||||||
property real height: 60
|
property real height: 60
|
||||||
property real hoverRegionHeight: 2
|
property real hoverRegionHeight: 2
|
||||||
property bool hoverToReveal: true
|
property bool hoverToReveal: true
|
||||||
|
property list<string> ignoredAppRegexes: []
|
||||||
property list<string> pinnedApps: ["org.kde.dolphin", "kitty",]
|
property list<string> pinnedApps: ["org.kde.dolphin", "kitty",]
|
||||||
property bool pinnedOnStartup: false
|
property bool pinnedOnStartup: false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import qs.Modules.Launcher as Launcher
|
|||||||
import qs.Modules.Resources as Resources
|
import qs.Modules.Resources as Resources
|
||||||
import qs.Modules.Drawing as Drawing
|
import qs.Modules.Drawing as Drawing
|
||||||
import qs.Modules.Settings as Settings
|
import qs.Modules.Settings as Settings
|
||||||
|
import qs.Modules.Dock as Dock
|
||||||
|
|
||||||
Shape {
|
Shape {
|
||||||
id: root
|
id: root
|
||||||
@@ -24,6 +25,7 @@ Shape {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Config.barConfig.border
|
anchors.margins: Config.barConfig.border
|
||||||
anchors.topMargin: bar.implicitHeight
|
anchors.topMargin: bar.implicitHeight
|
||||||
|
asynchronous: true
|
||||||
preferredRendererType: Shape.CurveRenderer
|
preferredRendererType: Shape.CurveRenderer
|
||||||
|
|
||||||
Drawing.Background {
|
Drawing.Background {
|
||||||
@@ -93,4 +95,12 @@ Shape {
|
|||||||
startY: 0
|
startY: 0
|
||||||
wrapper: root.panels.settings
|
wrapper: root.panels.settings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dock.Background {
|
||||||
|
id: dock
|
||||||
|
|
||||||
|
startX: (root.width - wrapper.width) / 2 - rounding
|
||||||
|
startY: root.height
|
||||||
|
wrapper: root.panels.dock
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ CustomMouseArea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!visibilities.dock && !visibilities.launcher && inBottomPanel(panels.dock, x, y))
|
||||||
|
visibilities.dock = true;
|
||||||
|
|
||||||
if (y < root.bar.implicitHeight) {
|
if (y < root.bar.implicitHeight) {
|
||||||
root.bar.checkPopout(x);
|
root.bar.checkPopout(x);
|
||||||
}
|
}
|
||||||
@@ -145,6 +148,9 @@ CustomMouseArea {
|
|||||||
root.panels.osd.hovered = false;
|
root.panels.osd.hovered = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (root.visibilities.launcher)
|
||||||
|
root.visibilities.dock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onOsdChanged() {
|
function onOsdChanged() {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import qs.Modules.Launcher as Launcher
|
|||||||
import qs.Modules.Resources as Resources
|
import qs.Modules.Resources as Resources
|
||||||
import qs.Modules.Settings as Settings
|
import qs.Modules.Settings as Settings
|
||||||
import qs.Modules.Drawing as Drawing
|
import qs.Modules.Drawing as Drawing
|
||||||
|
import qs.Modules.Dock as Dock
|
||||||
import qs.Config
|
import qs.Config
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -19,6 +20,7 @@ Item {
|
|||||||
|
|
||||||
required property Item bar
|
required property Item bar
|
||||||
readonly property alias dashboard: dashboard
|
readonly property alias dashboard: dashboard
|
||||||
|
readonly property alias dock: dock
|
||||||
readonly property alias drawing: drawing
|
readonly property alias drawing: drawing
|
||||||
required property Canvas drawingItem
|
required property Canvas drawingItem
|
||||||
readonly property alias launcher: launcher
|
readonly property alias launcher: launcher
|
||||||
@@ -143,4 +145,14 @@ Item {
|
|||||||
panels: root
|
panels: root
|
||||||
visibilities: root.visibilities
|
visibilities: root.visibilities
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dock.Wrapper {
|
||||||
|
id: dock
|
||||||
|
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
panels: root
|
||||||
|
screen: root.screen
|
||||||
|
visibilities: root.visibilities
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -33,7 +33,7 @@ Variants {
|
|||||||
property var root: Quickshell.shellDir
|
property var root: Quickshell.shellDir
|
||||||
|
|
||||||
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||||
WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || visibilities.resources ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: visibilities.dock || visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || visibilities.resources ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
contentItem.focus: true
|
contentItem.focus: true
|
||||||
mask: visibilities.isDrawing ? null : region
|
mask: visibilities.isDrawing ? null : region
|
||||||
@@ -94,7 +94,7 @@ Variants {
|
|||||||
HyprlandFocusGrab {
|
HyprlandFocusGrab {
|
||||||
id: focusGrab
|
id: focusGrab
|
||||||
|
|
||||||
active: visibilities.resources || visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || (panels.popouts.hasCurrent && panels.popouts.currentName.startsWith("traymenu"))
|
active: visibilities.dock || visibilities.resources || visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || (panels.popouts.hasCurrent && panels.popouts.currentName.startsWith("traymenu"))
|
||||||
windows: [win]
|
windows: [win]
|
||||||
|
|
||||||
onCleared: {
|
onCleared: {
|
||||||
@@ -104,6 +104,7 @@ Variants {
|
|||||||
visibilities.osd = false;
|
visibilities.osd = false;
|
||||||
visibilities.settings = false;
|
visibilities.settings = false;
|
||||||
visibilities.resources = false;
|
visibilities.resources = false;
|
||||||
|
visibilities.dock = false;
|
||||||
panels.popouts.hasCurrent = false;
|
panels.popouts.hasCurrent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,6 +114,7 @@ Variants {
|
|||||||
|
|
||||||
property bool bar
|
property bool bar
|
||||||
property bool dashboard
|
property bool dashboard
|
||||||
|
property bool dock
|
||||||
property bool isDrawing
|
property bool isDrawing
|
||||||
property bool launcher
|
property bool launcher
|
||||||
property bool notif: NotifServer.popups.length > 0
|
property bool notif: NotifServer.popups.length > 0
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property list<var> apps: {
|
||||||
|
var map = new Map();
|
||||||
|
|
||||||
|
// Pinned apps
|
||||||
|
const pinnedApps = Config.dock.pinnedApps ?? [];
|
||||||
|
for (const appId of pinnedApps) {
|
||||||
|
if (!map.has(appId.toLowerCase()))
|
||||||
|
map.set(appId.toLowerCase(), ({
|
||||||
|
pinned: true,
|
||||||
|
toplevels: []
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Separator
|
||||||
|
if (pinnedApps.length > 0) {
|
||||||
|
map.set("SEPARATOR", {
|
||||||
|
pinned: false,
|
||||||
|
toplevels: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignored apps
|
||||||
|
const ignoredRegexStrings = Config.dock.ignoredAppRegexes ?? [];
|
||||||
|
const ignoredRegexes = ignoredRegexStrings.map(pattern => new RegExp(pattern, "i"));
|
||||||
|
// Open windows
|
||||||
|
for (const toplevel of ToplevelManager.toplevels.values) {
|
||||||
|
if (ignoredRegexes.some(re => re.test(toplevel.appId)))
|
||||||
|
continue;
|
||||||
|
if (!map.has(toplevel.appId.toLowerCase()))
|
||||||
|
map.set(toplevel.appId.toLowerCase(), ({
|
||||||
|
pinned: false,
|
||||||
|
toplevels: []
|
||||||
|
}));
|
||||||
|
map.get(toplevel.appId.toLowerCase()).toplevels.push(toplevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
var values = [];
|
||||||
|
|
||||||
|
for (const [key, value] of map) {
|
||||||
|
values.push(appEntryComp.createObject(null, {
|
||||||
|
appId: key,
|
||||||
|
toplevels: value.toplevels,
|
||||||
|
pinned: value.pinned
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPinned(appId) {
|
||||||
|
return Config.dock.pinnedApps.indexOf(appId) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePin(appId) {
|
||||||
|
if (root.isPinned(appId)) {
|
||||||
|
Config.dock.pinnedApps = Config.dock.pinnedApps.filter(id => id !== appId);
|
||||||
|
} else {
|
||||||
|
Config.dock.pinnedApps = Config.dock.pinnedApps.concat([appId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: appEntryComp
|
||||||
|
|
||||||
|
TaskbarAppEntry {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component TaskbarAppEntry: QtObject {
|
||||||
|
id: wrapper
|
||||||
|
|
||||||
|
required property string appId
|
||||||
|
required property bool pinned
|
||||||
|
required property list<var> toplevels
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import qs.Modules.Dock.Parts
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
import qs.Config
|
import qs.Config
|
||||||
@@ -17,12 +18,29 @@ Item {
|
|||||||
implicitHeight: Config.dock.height + root.padding * 2
|
implicitHeight: Config.dock.height + root.padding * 2
|
||||||
implicitWidth: dockRow.implicitWidth + root.padding * 2
|
implicitWidth: dockRow.implicitWidth + root.padding * 2
|
||||||
|
|
||||||
RowLayout {
|
CustomListView {
|
||||||
id: dockRow
|
id: dockRow
|
||||||
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.centerIn: parent
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
implicitHeight: Config.dock.height
|
||||||
anchors.top: parent.top
|
implicitWidth: contentWidth
|
||||||
spacing: Appearance.spacing.small
|
orientation: ListView.Horizontal
|
||||||
|
spacing: Appearance.padding.smaller
|
||||||
|
|
||||||
|
delegate: DockAppButton {
|
||||||
|
required property var modelData
|
||||||
|
|
||||||
|
appListRoot: root
|
||||||
|
appToplevel: modelData
|
||||||
|
visibilities: root.visibilities
|
||||||
|
}
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model: ScriptModel {
|
||||||
|
objectProp: "appId"
|
||||||
|
values: TaskbarApps.apps
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import qs.Components
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool appIsActive: appToplevel.toplevels.find(t => (t.activated == true)) !== undefined
|
||||||
|
property var appListRoot
|
||||||
|
property var appToplevel
|
||||||
|
property real countDotHeight: 4
|
||||||
|
property real countDotWidth: 10
|
||||||
|
property var desktopEntry: DesktopEntries.heuristicLookup(appToplevel.appId)
|
||||||
|
property real iconSize: implicitHeight - 20
|
||||||
|
readonly property bool isSeparator: appToplevel.appId === "SEPARATOR"
|
||||||
|
property int lastFocused: -1
|
||||||
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
|
implicitHeight: Config.dock.height
|
||||||
|
implicitWidth: isSeparator ? 1 : implicitHeight
|
||||||
|
radius: Appearance.rounding.normal - Appearance.padding.small
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: !isSeparator
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
sourceComponent: ColumnLayout {
|
||||||
|
IconImage {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
implicitSize: root.iconSize
|
||||||
|
source: Quickshell.iconPath(AppSearch.guessIcon(appToplevel.appId), "image-missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 3
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: Math.min(appToplevel.toplevels.length, 3)
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
required property int index
|
||||||
|
|
||||||
|
color: appIsActive ? DynamicColors.palette.m3primary : DynamicColors.tPalette.m3primary
|
||||||
|
implicitHeight: root.countDotHeight
|
||||||
|
implicitWidth: (appToplevel.toplevels.length <= 3) ? root.countDotWidth : root.countDotHeight // Circles when too many
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
onClicked: {
|
||||||
|
if (appToplevel.toplevels.length === 0) {
|
||||||
|
root.desktopEntry?.execute();
|
||||||
|
root.visibilities.dock = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastFocused = (lastFocused + 1) % appToplevel.toplevels.length;
|
||||||
|
appToplevel.toplevels[lastFocused].activate();
|
||||||
|
root.visibilities.dock = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
function onApplicationsChanged() {
|
||||||
|
root.desktopEntry = DesktopEntries.heuristicLookup(appToplevel.appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
target: DesktopEntries
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
active: isSeparator
|
||||||
|
|
||||||
|
sourceComponent: DockSeparator {
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Components
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
Layout.bottomMargin: dockRow.padding + Appearance.rounding.normal
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.topMargin: dockRow.padding + Appearance.rounding.normal
|
||||||
|
color: DynamicColors.palette.m3outlineVariant
|
||||||
|
implicitWidth: 1
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user