forked from Shinonome/dots-hyprland
add overlay
This commit is contained in:
@@ -33,7 +33,7 @@ bindd = Super, N, Toggle right sidebar, global, quickshell:sidebarRightToggle #
|
||||
bindd = Super, Slash, Toggle cheatsheet, global, quickshell:cheatsheetToggle # Toggle cheatsheet
|
||||
bindd = Super, K, Toggle on-screen keyboard, global, quickshell:oskToggle # Toggle on-screen keyboard
|
||||
bindd = Super, M, Toggle media controls, global, quickshell:mediaControlsToggle # Toggle media controls
|
||||
bind = Super, G, global, quickshell:crosshairToggle # Toggle crosshair
|
||||
bind = Super, G, global, quickshell:overlayToggle # Toggle overlay
|
||||
bindd = Ctrl+Alt, Delete, Toggle session menu, global, quickshell:sessionToggle # Toggle session menu
|
||||
bindd = Super, J, Toggle bar, global, quickshell:barToggle # Toggle bar
|
||||
bind = Ctrl+Alt, Delete, exec, qs -c $qsConfig ipc call TEST_ALIVE || pkill wlogout || wlogout -p layer-shell # [hidden] Session menu (fallback)
|
||||
|
||||
@@ -134,11 +134,11 @@ layerrule = blur, quickshell:.*
|
||||
layerrule = ignorealpha 0.79, quickshell:.*
|
||||
layerrule = animation slide, quickshell:bar
|
||||
layerrule = animation slide bottom, quickshell:cheatsheet
|
||||
layerrule = noanim, quickshell:crosshair
|
||||
layerrule = animation slide bottom, quickshell:dock
|
||||
layerrule = animation popin 120%, quickshell:screenCorners
|
||||
layerrule = noanim, quickshell:lockWindowPusher
|
||||
layerrule = animation fade, quickshell:notificationPopup
|
||||
layerrule = noanim, quickshell:overlay
|
||||
layerrule = noanim, quickshell:overview
|
||||
layerrule = animation slide bottom, quickshell:osk
|
||||
layerrule = noanim, quickshell:polkit
|
||||
|
||||
@@ -17,6 +17,7 @@ Singleton {
|
||||
property bool osdBrightnessOpen: false
|
||||
property bool osdVolumeOpen: false
|
||||
property bool oskOpen: false
|
||||
property bool overlayOpen: false
|
||||
property bool overviewOpen: false
|
||||
property bool regionSelectorOpen: false
|
||||
property bool screenLocked: false
|
||||
|
||||
@@ -35,9 +35,9 @@ AbstractWidget {
|
||||
draggable: placementStrategy === "free"
|
||||
onReleased: {
|
||||
root.targetX = root.x;
|
||||
root.targetY = root.y;
|
||||
root.targetY = root.y;
|
||||
configEntry.x = root.targetX;
|
||||
configEntry.y = root.targetY ;
|
||||
configEntry.y = root.targetY;
|
||||
}
|
||||
|
||||
property bool needsColText: false
|
||||
|
||||
@@ -79,6 +79,22 @@ Singleton {
|
||||
property bool inhibit: false
|
||||
}
|
||||
|
||||
property JsonObject overlay: JsonObject {
|
||||
property list<string> open: ["crosshair"]
|
||||
property JsonObject crosshair: JsonObject {
|
||||
property bool pinned: false
|
||||
property bool clickthrough: true
|
||||
property real x: 100
|
||||
property real y: 100
|
||||
}
|
||||
property JsonObject volumeMixer: JsonObject {
|
||||
property bool pinned: false
|
||||
property bool clickthrough: false
|
||||
property real x: 55
|
||||
property real y: 188
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject timer: JsonObject {
|
||||
property JsonObject pomodoro: JsonObject {
|
||||
property bool running: false
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.modules.common
|
||||
|
||||
/*
|
||||
* Abstract widgets for an overlay. Doesn't contain any visuals.
|
||||
*/
|
||||
AbstractWidget {
|
||||
id: root
|
||||
|
||||
property bool pinned: false // Whether to stay visible when the overlay is dismissed
|
||||
property bool clickthrough: true // When pinned, whether to allow clicks go through
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
MouseArea {
|
||||
id: root
|
||||
|
||||
// uh this is stupid turns out we don't need anything here
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
|
||||
Loader {
|
||||
id: crosshairLoader
|
||||
active: GlobalStates.crosshairOpen
|
||||
sourceComponent: PanelWindow {
|
||||
id: crosshairWindow
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.namespace: "quickshell:crosshair"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
visible: true
|
||||
color: "transparent"
|
||||
|
||||
mask: Region { // Crosshair should not block mouse input
|
||||
item: null
|
||||
}
|
||||
|
||||
implicitWidth: crosshairContent.implicitWidth
|
||||
implicitHeight: crosshairContent.implicitHeight
|
||||
|
||||
CrosshairContent {
|
||||
id: crosshairContent
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "crosshair"
|
||||
|
||||
function toggle(): void {
|
||||
GlobalStates.crosshairOpen = !GlobalStates.crosshairOpen;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "crosshairToggle"
|
||||
description: "Toggles crosshair on press"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.crosshairOpen = !GlobalStates.crosshairOpen;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.services
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
|
||||
property Component regionComponent: Component {
|
||||
Region {}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: overlayLoader
|
||||
active: GlobalStates.overlayOpen || OverlayContext.hasPinnedWidgets
|
||||
sourceComponent: PanelWindow {
|
||||
id: overlayWindow
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
WlrLayershell.namespace: "quickshell:overlay"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
|
||||
visible: true
|
||||
color: "transparent"
|
||||
|
||||
mask: Region {
|
||||
item: GlobalStates.overlayOpen ? overlayContent : null
|
||||
regions: OverlayContext.clickableWidgets.map((widget) => regionComponent.createObject(this, {
|
||||
item: widget
|
||||
}));
|
||||
}
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
bottom: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
OverlayContent {
|
||||
id: overlayContent
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "overlay"
|
||||
|
||||
function toggle(): void {
|
||||
GlobalStates.overlayOpen = !GlobalStates.overlayOpen;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "overlayToggle"
|
||||
description: "Toggles overlay on press"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.overlayOpen = !GlobalStates.overlayOpen;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.widgets.widgetCanvas
|
||||
|
||||
import qs.modules.overlay.crosshair
|
||||
|
||||
Item {
|
||||
id: root
|
||||
readonly property bool usePasswordChars: !PolkitService.flow?.responseVisible ?? true
|
||||
|
||||
Keys.onPressed: (event) => { // Esc to close
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
GlobalStates.overlayOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
property real initScale: 1.08
|
||||
scale: initScale
|
||||
Component.onCompleted: {
|
||||
scale = 1
|
||||
}
|
||||
Behavior on scale {
|
||||
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: bg
|
||||
anchors.fill: parent
|
||||
color: Appearance.colors.colScrim
|
||||
opacity: (GlobalStates.overlayOpen && root.scale !== initScale) ? 1 : 0
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
|
||||
WidgetCanvas {
|
||||
anchors.fill: parent
|
||||
onClicked: GlobalStates.overlayOpen = false
|
||||
|
||||
OverlayTaskbar {
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
top: parent.top
|
||||
topMargin: 50
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: Persistent.states.overlay.open.map(identifier => {
|
||||
return OverlayContext.availableWidgets.find(w => w.identifier === identifier);
|
||||
})
|
||||
objectProp: "identifier"
|
||||
}
|
||||
delegate: OverlayWidgetDelegateChooser {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
import Quickshell
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property list<var> availableWidgets: [
|
||||
{ identifier: "crosshair", materialSymbol: "point_scan" },
|
||||
{ identifier: "volumeMixer", materialSymbol: "volume_up" }
|
||||
]
|
||||
|
||||
readonly property bool hasPinnedWidgets: root.pinnedWidgetIdentifiers.length > 0
|
||||
|
||||
property list<string> pinnedWidgetIdentifiers: []
|
||||
property list<var> clickableWidgets: []
|
||||
|
||||
function pin(identifier: string, pin = true) {
|
||||
if (pin) {
|
||||
if (!root.pinnedWidgetIdentifiers.includes(identifier)) {
|
||||
root.pinnedWidgetIdentifiers.push(identifier)
|
||||
}
|
||||
} else {
|
||||
root.pinnedWidgetIdentifiers = root.pinnedWidgetIdentifiers.filter(id => id !== identifier)
|
||||
}
|
||||
}
|
||||
|
||||
function registerClickableWidget(widget: var, clickable = true) {
|
||||
if (clickable) {
|
||||
if (!root.clickableWidgets.includes(widget)) {
|
||||
root.clickableWidgets.push(widget)
|
||||
}
|
||||
} else {
|
||||
root.clickableWidgets = root.clickableWidgets.filter(w => w !== widget)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.widgets.widgetCanvas
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property real padding: 8
|
||||
|
||||
opacity: GlobalStates.overlayOpen ? 1 : 0
|
||||
implicitWidth: contentRow.implicitWidth + (padding * 2)
|
||||
implicitHeight: contentRow.implicitHeight + (padding * 2)
|
||||
color: Appearance.m3colors.m3surfaceContainer
|
||||
radius: Appearance.rounding.large
|
||||
border.color: Appearance.colors.colOutlineVariant
|
||||
border.width: 1
|
||||
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: contentRow
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: root.padding
|
||||
}
|
||||
spacing: 6
|
||||
|
||||
Row {
|
||||
spacing: 4
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: OverlayContext.availableWidgets
|
||||
}
|
||||
delegate: WidgetButton {
|
||||
required property var modelData
|
||||
identifier: modelData.identifier
|
||||
materialSymbol: modelData.materialSymbol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Separator {}
|
||||
|
||||
TimeWidget {}
|
||||
}
|
||||
|
||||
component Separator: Rectangle {
|
||||
implicitWidth: 1
|
||||
color: Appearance.colors.colOutlineVariant
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: 10
|
||||
Layout.bottomMargin: 10
|
||||
}
|
||||
|
||||
component TimeWidget: StyledText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.leftMargin: 8
|
||||
Layout.rightMargin: 6
|
||||
|
||||
text: DateTime.time
|
||||
font {
|
||||
family: Appearance.font.family.numbers
|
||||
variableAxes: Appearance.font.variableAxes.numbers
|
||||
pixelSize: 22
|
||||
}
|
||||
}
|
||||
|
||||
component WidgetButton: RippleButton {
|
||||
id: widgetButton
|
||||
required property string identifier
|
||||
required property string materialSymbol
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
toggled: Persistent.states.overlay.open.includes(identifier)
|
||||
onClicked: {
|
||||
if (widgetButton.toggled) {
|
||||
Persistent.states.overlay.open = Persistent.states.overlay.open.filter(type => type !== identifier);
|
||||
} else {
|
||||
Persistent.states.overlay.open.push(identifier);
|
||||
}
|
||||
}
|
||||
implicitWidth: implicitHeight
|
||||
|
||||
colBackgroundToggled: Appearance.colors.colSecondaryContainer
|
||||
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
|
||||
colRippleToggled: Appearance.colors.colSecondaryContainerActive
|
||||
|
||||
buttonRadius: root.radius - (root.height - height) / 2
|
||||
|
||||
contentItem: Item {
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
MaterialSymbol {
|
||||
id: iconWidget
|
||||
anchors.centerIn: parent
|
||||
iconSize: 24
|
||||
text: widgetButton.materialSymbol
|
||||
color: widgetButton.toggled ? Appearance.colors.colOnSecondaryContainer : Appearance.colors.colOnSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Bluetooth
|
||||
import qs.modules.overlay.crosshair
|
||||
import qs.modules.overlay.volumeMixer
|
||||
|
||||
DelegateChooser {
|
||||
id: root
|
||||
role: "identifier"
|
||||
|
||||
DelegateChoice { roleValue: "crosshair"; Crosshair {} }
|
||||
DelegateChoice { roleValue: "volumeMixer"; VolumeMixer {} }
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.widgets.widgetCanvas
|
||||
|
||||
/*
|
||||
* To make an overlay widget:
|
||||
* 1. Create a modules/overlay/<yourWidget>/<YourWidget>.qml, using this as the base class
|
||||
* 2. Add an entry to OverlayContext.availableWidgets with identifier=<yourWidgetIdentifier>
|
||||
* 3. Add an entry in Persistent.states.overlay.<yourWidgetIdentifier> with x, y, pinned, clickthrough properties set to reasonable defaults
|
||||
* 4. Add an entry in OverlayWidgetDelegateChooser with roleValue=<yourWidgetIdentifier> and Declare your widget in there
|
||||
* Use existing entries as reference.
|
||||
*/
|
||||
AbstractOverlayWidget {
|
||||
id: root
|
||||
|
||||
required property var modelData
|
||||
required property Item contentItem
|
||||
|
||||
readonly property string identifier: modelData.identifier
|
||||
readonly property string materialSymbol: modelData.materialSymbol ?? "widgets"
|
||||
property string title: identifier.replace(/([A-Z])/g, " $1").replace(/^./, function(str){ return str.toUpperCase(); })
|
||||
property var persistentStateEntry: Persistent.states.overlay[identifier]
|
||||
property real radius: Appearance.rounding.windowRounding
|
||||
property real minWidth: 250
|
||||
|
||||
draggable: GlobalStates.overlayOpen
|
||||
x: Math.round(persistentStateEntry.x) // Round or it'll be blurry
|
||||
y: Math.round(persistentStateEntry.y) // Round or it'll be blurry
|
||||
pinned: persistentStateEntry.pinned
|
||||
clickthrough: persistentStateEntry.clickthrough
|
||||
drag {
|
||||
minimumX: 0
|
||||
minimumY: 0
|
||||
maximumX: root.parent.width - root.width
|
||||
maximumY: root.parent.height - root.height
|
||||
}
|
||||
|
||||
// Guarded states & registration funcs
|
||||
property bool open: Persistent.states.overlay.open
|
||||
property bool actuallyPinned: pinned && open
|
||||
property bool actuallyClickable: !clickthrough && actuallyPinned && open
|
||||
onActuallyPinnedChanged: reportPinnedState();
|
||||
onActuallyClickableChanged: reportClickableState();
|
||||
function reportPinnedState() {
|
||||
OverlayContext.pin(identifier, actuallyPinned);
|
||||
}
|
||||
function reportClickableState() {
|
||||
OverlayContext.registerClickableWidget(contentItem, actuallyClickable);
|
||||
}
|
||||
|
||||
// Self-registeration with OverlayContext
|
||||
Component.onCompleted: {
|
||||
reportPinnedState();
|
||||
reportClickableState();
|
||||
}
|
||||
|
||||
// Hooks
|
||||
onReleased: savePosition();
|
||||
|
||||
function close() {
|
||||
Persistent.states.overlay.open = Persistent.states.overlay.open.filter(type => type !== root.identifier);
|
||||
}
|
||||
|
||||
function togglePinned() {
|
||||
persistentStateEntry.pinned = !persistentStateEntry.pinned;
|
||||
}
|
||||
|
||||
function toggleClickthrough() {
|
||||
persistentStateEntry.clickthrough = !persistentStateEntry.clickthrough;
|
||||
}
|
||||
|
||||
function savePosition(xPos = root.x, yPos = root.y) {
|
||||
persistentStateEntry.x = xPos;
|
||||
persistentStateEntry.y = yPos;
|
||||
}
|
||||
|
||||
function center() {
|
||||
const targetX = (root.parent.width - contentColumn.width) / 2
|
||||
const targetY = (root.parent.height - contentItem.height) / 2 - titleBar.implicitHeight
|
||||
root.x = targetX
|
||||
root.y = targetY
|
||||
root.savePosition(targetX, targetY)
|
||||
}
|
||||
|
||||
visible: GlobalStates.overlayOpen || actuallyPinned
|
||||
implicitWidth: Math.max(contentColumn.implicitWidth, minWidth)
|
||||
implicitHeight: contentColumn.implicitHeight
|
||||
|
||||
Rectangle {
|
||||
id: border
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
radius: root.radius
|
||||
border.color: ColorUtils.transparentize(Appearance.colors.colOutlineVariant, GlobalStates.overlayOpen ? 0 : 1)
|
||||
border.width: 1
|
||||
|
||||
layer.enabled: GlobalStates.overlayOpen
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Rectangle {
|
||||
width: border.width
|
||||
height: border.height
|
||||
radius: root.radius
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: contentColumn
|
||||
z: -1
|
||||
anchors.fill: parent
|
||||
|
||||
// Title bar
|
||||
Rectangle {
|
||||
id: titleBar
|
||||
opacity: GlobalStates.overlayOpen ? 1 : 0
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
property real padding: 2
|
||||
implicitWidth: titleBarRow.implicitWidth + padding * 2
|
||||
implicitHeight: titleBarRow.implicitHeight + padding * 2
|
||||
color: Appearance.m3colors.m3surfaceContainer
|
||||
border.color: Appearance.colors.colOutlineVariant
|
||||
border.width: 1
|
||||
|
||||
RowLayout {
|
||||
id: titleBarRow
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: titleBar.padding
|
||||
leftMargin: titleBar.padding + 8
|
||||
}
|
||||
spacing: 0
|
||||
|
||||
MaterialSymbol {
|
||||
text: root.materialSymbol
|
||||
iconSize: 20
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.rightMargin: 4
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.title
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
TitlebarButton {
|
||||
materialSymbol: "recenter"
|
||||
onClicked: root.center()
|
||||
StyledToolTip {
|
||||
text: "Center"
|
||||
}
|
||||
}
|
||||
|
||||
TitlebarButton {
|
||||
materialSymbol: "mouse"
|
||||
toggled: !root.clickthrough
|
||||
onClicked: root.toggleClickthrough()
|
||||
StyledToolTip {
|
||||
text: "Clickable when pinned"
|
||||
}
|
||||
}
|
||||
|
||||
TitlebarButton {
|
||||
materialSymbol: "keep"
|
||||
toggled: root.pinned
|
||||
onClicked: root.togglePinned()
|
||||
StyledToolTip {
|
||||
text: "Pin"
|
||||
}
|
||||
}
|
||||
|
||||
TitlebarButton {
|
||||
materialSymbol: "close"
|
||||
onClicked: root.close()
|
||||
StyledToolTip {
|
||||
text: "Close"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Content
|
||||
Item {
|
||||
id: contentContainer
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
implicitWidth: root.contentItem.implicitWidth
|
||||
implicitHeight: root.contentItem.implicitHeight
|
||||
children: [root.contentItem]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
component TitlebarButton: RippleButton {
|
||||
id: titlebarButton
|
||||
required property string materialSymbol
|
||||
buttonRadius: height / 2
|
||||
implicitHeight: contentItem.implicitHeight
|
||||
implicitWidth: implicitHeight
|
||||
padding: 0
|
||||
|
||||
colBackgroundToggled: Appearance.colors.colSecondaryContainer
|
||||
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
|
||||
colRippleToggled: Appearance.colors.colSecondaryContainerActive
|
||||
|
||||
contentItem: Item {
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: 30
|
||||
implicitHeight: 30
|
||||
|
||||
MaterialSymbol {
|
||||
id: iconWidget
|
||||
anchors.centerIn: parent
|
||||
iconSize: 20
|
||||
text: titlebarButton.materialSymbol
|
||||
fill: titlebarButton.toggled
|
||||
color: titlebarButton.toggled ? Appearance.colors.colOnSecondaryContainer : Appearance.colors.colOnSurface
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.modules.common
|
||||
import qs.modules.overlay
|
||||
|
||||
StyledOverlayWidget {
|
||||
id: root
|
||||
contentItem: CrosshairContent {}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.modules.common
|
||||
import qs.modules.overlay
|
||||
import qs.modules.sidebarRight.volumeMixer
|
||||
|
||||
StyledOverlayWidget {
|
||||
id: root
|
||||
contentItem: Rectangle {
|
||||
anchors.centerIn: parent
|
||||
color: Appearance.m3colors.m3surfaceContainer
|
||||
property real padding: 16
|
||||
implicitHeight: 700
|
||||
implicitWidth: 400
|
||||
|
||||
VolumeDialogContent {
|
||||
anchors.fill: parent
|
||||
anchors.margins: parent.padding
|
||||
isSink: true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ ContentPage {
|
||||
Layout.leftMargin: 10
|
||||
color: Appearance.colors.colSubtext
|
||||
font.pixelSize: Appearance.font.pixelSize.smallie
|
||||
text: Translation.tr("Press Super+G to toggle appearance")
|
||||
text: Translation.tr("Press Super+G to open the overlay and pin the crosshair")
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -11,7 +11,6 @@ import qs.modules.common
|
||||
import qs.modules.background
|
||||
import qs.modules.bar
|
||||
import qs.modules.cheatsheet
|
||||
import qs.modules.crosshair
|
||||
import qs.modules.dock
|
||||
import qs.modules.lock
|
||||
import qs.modules.mediaControls
|
||||
@@ -25,6 +24,7 @@ import qs.modules.screenCorners
|
||||
import qs.modules.sessionScreen
|
||||
import qs.modules.sidebarLeft
|
||||
import qs.modules.sidebarRight
|
||||
import qs.modules.overlay
|
||||
import qs.modules.verticalBar
|
||||
import qs.modules.wallpaperSelector
|
||||
|
||||
@@ -39,7 +39,6 @@ ShellRoot {
|
||||
property bool enableBar: true
|
||||
property bool enableBackground: true
|
||||
property bool enableCheatsheet: true
|
||||
property bool enableCrosshair: true
|
||||
property bool enableDock: true
|
||||
property bool enableLock: true
|
||||
property bool enableMediaControls: true
|
||||
@@ -47,6 +46,7 @@ ShellRoot {
|
||||
property bool enablePolkit: true
|
||||
property bool enableOnScreenDisplay: true
|
||||
property bool enableOnScreenKeyboard: true
|
||||
property bool enableOverlay: true
|
||||
property bool enableOverview: true
|
||||
property bool enableRegionSelector: true
|
||||
property bool enableReloadPopup: true
|
||||
@@ -70,13 +70,13 @@ ShellRoot {
|
||||
LazyLoader { active: enableBar && Config.ready && !Config.options.bar.vertical; component: Bar {} }
|
||||
LazyLoader { active: enableBackground; component: Background {} }
|
||||
LazyLoader { active: enableCheatsheet; component: Cheatsheet {} }
|
||||
LazyLoader { active: enableCrosshair; component: Crosshair {} }
|
||||
LazyLoader { active: enableDock && Config.options.dock.enable; component: Dock {} }
|
||||
LazyLoader { active: enableLock; component: Lock {} }
|
||||
LazyLoader { active: enableMediaControls; component: MediaControls {} }
|
||||
LazyLoader { active: enableNotificationPopup; component: NotificationPopup {} }
|
||||
LazyLoader { active: enableOnScreenDisplay; component: OnScreenDisplay {} }
|
||||
LazyLoader { active: enableOnScreenKeyboard; component: OnScreenKeyboard {} }
|
||||
LazyLoader { active: enableOverlay; component: Overlay {} }
|
||||
LazyLoader { active: enableOverview; component: Overview {} }
|
||||
LazyLoader { active: enablePolkit; component: Polkit {} }
|
||||
LazyLoader { active: enableRegionSelector; component: RegionSelector {} }
|
||||
|
||||
Reference in New Issue
Block a user