Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 33746fca04 | |||
| 853b683962 | |||
| b1bfcb3ed0 | |||
| b8af60008d | |||
| b8524ff621 | |||
| ffde4063a0 |
@@ -80,10 +80,32 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function reloadHyprRules(): void {
|
function reloadHyprRules(): void {
|
||||||
const barStr = Hyprland.usingLua ? `eval 'hl.layer_rule({ match = { namespace = "ZShell-Bar" }, %1 = true, %2 = true })'` : "keyword layerrule %1 %2, match:namespace ZShell-Bar";
|
const blur = transparency.enabled ? 1 : 0;
|
||||||
const authStr = Hyprland.usingLua ? `eval 'hl.layer_rule({ match = { namespace = "ZShell-Auth" }, %1 = true, %2 = true })'` : "keyword layerrule %1 %2, match:namespace ZShell-Auth";
|
const alpha = transparency.base - 0.03;
|
||||||
Hypr.extras.batchMessage([barStr.arg("blur").arg(transparency.enabled ? 1 : 0), barStr.arg("ignore_alpha").arg(transparency.base - 0.03)]);
|
|
||||||
Hypr.extras.batchMessage([authStr.arg("blur").arg(transparency.enabled ? 1 : 0), authStr.arg("ignore_alpha").arg(transparency.base - 0.03)]);
|
const rules = `
|
||||||
|
hl.layer_rule({
|
||||||
|
match = { namespace = "ZShell-Bar" },
|
||||||
|
blur = ${blur}
|
||||||
|
})
|
||||||
|
|
||||||
|
hl.layer_rule({
|
||||||
|
match = { namespace = "ZShell-Bar" },
|
||||||
|
ignore_alpha = ${alpha}
|
||||||
|
})
|
||||||
|
|
||||||
|
hl.layer_rule({
|
||||||
|
match = { namespace = "ZShell-Auth" },
|
||||||
|
blur = ${blur}
|
||||||
|
})
|
||||||
|
|
||||||
|
hl.layer_rule({
|
||||||
|
match = { namespace = "ZShell-Auth" },
|
||||||
|
ignore_alpha = ${alpha}
|
||||||
|
})
|
||||||
|
`;
|
||||||
|
|
||||||
|
Hypr.extras.message(`eval ${rules}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setMode(mode: string): void {
|
function setMode(mode: string): void {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ 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.Modules.Dock as Dock
|
||||||
|
import qs.Modules.SysTray.Popouts as SysPopouts
|
||||||
import qs.Config
|
import qs.Config
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -37,6 +38,7 @@ Item {
|
|||||||
readonly property alias settingsWrapper: settingsWrapper
|
readonly property alias settingsWrapper: settingsWrapper
|
||||||
readonly property alias sidebar: sidebar
|
readonly property alias sidebar: sidebar
|
||||||
readonly property alias toasts: toasts
|
readonly property alias toasts: toasts
|
||||||
|
readonly property alias traySubmenus: traySubmenus
|
||||||
readonly property alias utilities: utilities
|
readonly property alias utilities: utilities
|
||||||
required property PersistentProperties visibilities
|
required property PersistentProperties visibilities
|
||||||
|
|
||||||
@@ -93,6 +95,79 @@ Item {
|
|||||||
visibilities: root.visibilities
|
visibilities: root.visibilities
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: traySubmenus
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: popouts.content.state.submenus
|
||||||
|
|
||||||
|
CustomClippingRect {
|
||||||
|
id: subMenuWrapper
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
required property var modelData
|
||||||
|
property real targetX: 0
|
||||||
|
property real targetY: 0
|
||||||
|
|
||||||
|
function updatePosition() {
|
||||||
|
let sourceItem = modelData.sourceItem;
|
||||||
|
if (!sourceItem || !sourceItem.parent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let mapped = sourceItem.mapToItem(root, 0, -Appearance.padding.small);
|
||||||
|
|
||||||
|
let rightX = mapped.x + modelData.sourceWidth + Config.barConfig.border;
|
||||||
|
let leftX = mapped.x - implicitWidth - Config.barConfig.border;
|
||||||
|
|
||||||
|
if (rightX + implicitWidth > root.width) {
|
||||||
|
targetX = leftX;
|
||||||
|
} else {
|
||||||
|
targetX = rightX;
|
||||||
|
}
|
||||||
|
|
||||||
|
targetY = mapped.y;
|
||||||
|
|
||||||
|
if (targetY + implicitHeight > root.height) {
|
||||||
|
targetY = root.height - implicitHeight;
|
||||||
|
}
|
||||||
|
if (targetY < 0)
|
||||||
|
targetY = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitHeight: subMenuContent.implicitHeight + Appearance.padding.small * 2
|
||||||
|
implicitWidth: subMenuContent.implicitWidth + Appearance.padding.small * 2
|
||||||
|
radius: Appearance.rounding.normal
|
||||||
|
x: targetX
|
||||||
|
y: targetY
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on implicitWidth {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
updatePosition();
|
||||||
|
}
|
||||||
|
onImplicitHeightChanged: updatePosition()
|
||||||
|
onImplicitWidthChanged: updatePosition()
|
||||||
|
|
||||||
|
SysPopouts.SubMenu {
|
||||||
|
id: subMenuContent
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
handle: subMenuWrapper.modelData.handle
|
||||||
|
level: subMenuWrapper.index + 1
|
||||||
|
popouts: root.popouts.state
|
||||||
|
screen: root.screen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Modules.ClipWrapper {
|
Modules.ClipWrapper {
|
||||||
id: popouts
|
id: popouts
|
||||||
|
|
||||||
|
|||||||
+35
-7
@@ -64,7 +64,7 @@ Variants {
|
|||||||
|
|
||||||
height: win.height - bar.implicitHeight - Config.barConfig.border
|
height: win.height - bar.implicitHeight - Config.barConfig.border
|
||||||
intersection: Intersection.Xor
|
intersection: Intersection.Xor
|
||||||
regions: popoutRegions.instances
|
regions: [...popoutRegions.instances, ...subMenuRegions.instances]
|
||||||
width: win.width - Config.barConfig.border * 2
|
width: win.width - Config.barConfig.border * 2
|
||||||
x: Config.barConfig.border
|
x: Config.barConfig.border
|
||||||
y: bar.implicitHeight
|
y: bar.implicitHeight
|
||||||
@@ -93,6 +93,22 @@ Variants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
id: subMenuRegions
|
||||||
|
|
||||||
|
model: panels.traySubmenus.children
|
||||||
|
|
||||||
|
Region {
|
||||||
|
required property Item modelData
|
||||||
|
|
||||||
|
height: modelData.height
|
||||||
|
intersection: Intersection.Subtract
|
||||||
|
width: modelData.width
|
||||||
|
x: modelData.x + panels.traySubmenus.x + Config.barConfig.border
|
||||||
|
y: modelData.y + panels.traySubmenus.y + bar.implicitHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HyprlandFocusGrab {
|
HyprlandFocusGrab {
|
||||||
id: focusGrab
|
id: focusGrab
|
||||||
|
|
||||||
@@ -182,7 +198,7 @@ Variants {
|
|||||||
|
|
||||||
property real extraHeight: 0.2
|
property real extraHeight: 0.2
|
||||||
|
|
||||||
deformAmount: 0.08
|
deformAmount: 0.06
|
||||||
implicitHeight: panels.dashboard.height * (1 + extraHeight)
|
implicitHeight: panels.dashboard.height * (1 + extraHeight)
|
||||||
implicitWidth: panels.dashboard.width
|
implicitWidth: panels.dashboard.width
|
||||||
panel: panels.dashboardWrapper
|
panel: panels.dashboardWrapper
|
||||||
@@ -196,7 +212,7 @@ Variants {
|
|||||||
|
|
||||||
property real extraHeight: 0.2
|
property real extraHeight: 0.2
|
||||||
|
|
||||||
deformAmount: 0.08
|
deformAmount: 0.06
|
||||||
implicitHeight: panels.launcher.height * (1 + extraHeight)
|
implicitHeight: panels.launcher.height * (1 + extraHeight)
|
||||||
panel: panels.launcher
|
panel: panels.launcher
|
||||||
radius: Appearance.rounding.smallest + 5
|
radius: Appearance.rounding.smallest + 5
|
||||||
@@ -207,7 +223,7 @@ Variants {
|
|||||||
id: sidebarBg
|
id: sidebarBg
|
||||||
|
|
||||||
bottomLeftRadius: 0
|
bottomLeftRadius: 0
|
||||||
deformAmount: 0.08
|
deformAmount: 0.04
|
||||||
exclude: panels.sidebar.offsetScale > 0.08 ? [] : [utilsBg]
|
exclude: panels.sidebar.offsetScale > 0.08 ? [] : [utilsBg]
|
||||||
implicitHeight: panel.height * (1 / rawDeformMatrix.m22) + 2
|
implicitHeight: panel.height * (1 / rawDeformMatrix.m22) + 2
|
||||||
panel: panels.sidebar
|
panel: panels.sidebar
|
||||||
@@ -262,7 +278,7 @@ Variants {
|
|||||||
PanelBg {
|
PanelBg {
|
||||||
id: resourcesBg
|
id: resourcesBg
|
||||||
|
|
||||||
deformAmount: 0.08
|
deformAmount: 0.05
|
||||||
implicitHeight: panels.resources.height
|
implicitHeight: panels.resources.height
|
||||||
implicitWidth: panels.resources.width
|
implicitWidth: panels.resources.width
|
||||||
panel: panels.resourcesWrapper
|
panel: panels.resourcesWrapper
|
||||||
@@ -276,10 +292,10 @@ Variants {
|
|||||||
|
|
||||||
property real extraHeight: 0.2
|
property real extraHeight: 0.2
|
||||||
|
|
||||||
deformAmount: 0.08
|
deformAmount: 0.03
|
||||||
implicitHeight: panels.settings.height * (1 + extraHeight)
|
implicitHeight: panels.settings.height * (1 + extraHeight)
|
||||||
implicitWidth: panels.settings.width
|
implicitWidth: panels.settings.width
|
||||||
panel: panels.settingsWrapper
|
panel: panels.settings
|
||||||
radius: Appearance.rounding.large
|
radius: Appearance.rounding.large
|
||||||
topLeftRadius: Appearance.rounding.large + Appearance.padding.smaller
|
topLeftRadius: Appearance.rounding.large + Appearance.padding.smaller
|
||||||
topRightRadius: Appearance.rounding.large + Appearance.padding.smaller
|
topRightRadius: Appearance.rounding.large + Appearance.padding.smaller
|
||||||
@@ -302,6 +318,18 @@ Variants {
|
|||||||
panel: panels.drawing
|
panel: panels.drawing
|
||||||
radius: Appearance.rounding.normal
|
radius: Appearance.rounding.normal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: panels.traySubmenus.children
|
||||||
|
|
||||||
|
PanelBg {
|
||||||
|
required property Item modelData
|
||||||
|
|
||||||
|
deformAmount: 0.1
|
||||||
|
panel: modelData
|
||||||
|
radius: 20 * Appearance.rounding.scale
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Drawing {
|
Drawing {
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ Singleton {
|
|||||||
|
|
||||||
function setHyprConf(): void {
|
function setHyprConf(): void {
|
||||||
Hypr.extras.applyOptions({
|
Hypr.extras.applyOptions({
|
||||||
"animations:enabled": 0,
|
"animations.enabled": 0,
|
||||||
"decoration:shadow:enabled": 0,
|
"decoration.shadow.enabled": 0,
|
||||||
"decoration:blur:enabled": 0,
|
"decoration.blur.enabled": 0,
|
||||||
"general:border_size": 0,
|
"general.border_size": 0,
|
||||||
"decoration:rounding": 0
|
"decoration.rounding": 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Item {
|
|||||||
readonly property Item current: currentPopout?.item ?? null
|
readonly property Item current: currentPopout?.item ?? null
|
||||||
readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null
|
readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null
|
||||||
required property PopoutState popouts
|
required property PopoutState popouts
|
||||||
|
required property ShellScreen screen
|
||||||
|
|
||||||
implicitHeight: (currentPopout?.implicitHeight ?? 0) + 5 * 2
|
implicitHeight: (currentPopout?.implicitHeight ?? 0) + 5 * 2
|
||||||
implicitWidth: (currentPopout?.implicitWidth ?? 0) + 5 * 2
|
implicitWidth: (currentPopout?.implicitWidth ?? 0) + 5 * 2
|
||||||
@@ -63,6 +64,7 @@ Item {
|
|||||||
|
|
||||||
TrayMenuPopout {
|
TrayMenuPopout {
|
||||||
popouts: root.popouts
|
popouts: root.popouts
|
||||||
|
screen: root.screen
|
||||||
trayItem: trayMenu.modelData.menu
|
trayItem: trayMenu.modelData.menu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,36 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
|
id: root
|
||||||
|
|
||||||
property string currentName
|
property string currentName
|
||||||
property bool hasCurrent
|
property bool hasCurrent
|
||||||
|
property var submenus: []
|
||||||
|
|
||||||
signal detachRequested(mode: string)
|
signal detachRequested(mode: string)
|
||||||
|
|
||||||
|
function clearSubmenus(): void {
|
||||||
|
submenus = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeSubmenus(level: int): void {
|
||||||
|
submenus = submenus.slice(0, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushSubmenu(level: int, handle: var, sourceItem: var, sourceWidth: int): void {
|
||||||
|
let newSubmenus = submenus.slice(0, level);
|
||||||
|
newSubmenus.push({
|
||||||
|
"handle": handle,
|
||||||
|
"sourceItem": sourceItem,
|
||||||
|
"sourceWidth": sourceWidth
|
||||||
|
});
|
||||||
|
submenus = newSubmenus;
|
||||||
|
}
|
||||||
|
|
||||||
|
onCurrentNameChanged: {
|
||||||
|
root.clearSubmenus();
|
||||||
|
}
|
||||||
|
onHasCurrentChanged: {
|
||||||
|
root.clearSubmenus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Effects
|
||||||
|
import qs.Components
|
||||||
|
import qs.Modules
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: menu
|
||||||
|
|
||||||
|
property int biggestWidth: 0
|
||||||
|
required property QsMenuHandle handle
|
||||||
|
required property int level
|
||||||
|
required property PopoutState popouts
|
||||||
|
required property ShellScreen screen
|
||||||
|
property bool shown: true
|
||||||
|
|
||||||
|
height: childrenRect.height
|
||||||
|
opacity: shown ? 1 : 0
|
||||||
|
padding: 0
|
||||||
|
scale: shown ? 1 : 0.8
|
||||||
|
spacing: 4
|
||||||
|
width: biggestWidth
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Behavior on scale {
|
||||||
|
Anim {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QsMenuOpener {
|
||||||
|
id: menuOpener
|
||||||
|
|
||||||
|
menu: menu.handle
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: menuOpener.children
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: item
|
||||||
|
|
||||||
|
required property int index
|
||||||
|
required property QsMenuEntry modelData
|
||||||
|
|
||||||
|
color: modelData.isSeparator ? DynamicColors.palette.m3outlineVariant : "transparent"
|
||||||
|
implicitHeight: modelData.isSeparator ? 1 : children.implicitHeight
|
||||||
|
implicitWidth: menu.biggestWidth
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
visible: index !== (menuOpener.children.values.length - 1) ? true : (modelData.isSeparator ? false : true)
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: children
|
||||||
|
|
||||||
|
active: !item.modelData.isSeparator
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
sourceComponent: Item {
|
||||||
|
implicitHeight: 30
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
function onClicked(): void {
|
||||||
|
const entry = item.modelData;
|
||||||
|
if (entry.hasChildren) {
|
||||||
|
menu.popouts.pushSubmenu(menu.level, entry, item, menu.biggestWidth);
|
||||||
|
} else {
|
||||||
|
entry.triggered();
|
||||||
|
menu.popouts.hasCurrent = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disabled: !item.modelData.enabled
|
||||||
|
radius: item.radius
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: icon
|
||||||
|
|
||||||
|
active: item.modelData.icon !== ""
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
sourceComponent: Item {
|
||||||
|
implicitHeight: label.implicitHeight
|
||||||
|
implicitWidth: label.implicitHeight
|
||||||
|
|
||||||
|
IconImage {
|
||||||
|
id: iconImage
|
||||||
|
|
||||||
|
implicitSize: parent.implicitHeight
|
||||||
|
source: item.modelData.icon
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiEffect {
|
||||||
|
anchors.fill: iconImage
|
||||||
|
colorization: 1.0
|
||||||
|
colorizationColor: item.modelData.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3outline
|
||||||
|
source: iconImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: label
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: item.modelData.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3outline
|
||||||
|
text: labelMetrics.elidedText
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMetrics {
|
||||||
|
id: labelMetrics
|
||||||
|
|
||||||
|
font.family: label.font.family
|
||||||
|
font.pointSize: label.font.pointSize
|
||||||
|
text: item.modelData.text
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
var biggestWidth = menu.biggestWidth;
|
||||||
|
var currentWidth = labelMetrics.width + (item.modelData.icon ?? "" ? 30 : 0) + (item.modelData.hasChildren ? 30 : 0) + 20;
|
||||||
|
if (currentWidth > biggestWidth) {
|
||||||
|
menu.biggestWidth = currentWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: expand
|
||||||
|
|
||||||
|
active: item.modelData.hasChildren
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
|
sourceComponent: MaterialIcon {
|
||||||
|
color: item.modelData.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3outline
|
||||||
|
text: "chevron_right"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,251 +1,16 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Widgets
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Effects
|
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Modules
|
import qs.Modules
|
||||||
import qs.Config
|
import qs.Config
|
||||||
|
|
||||||
StackView {
|
SubMenu {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property int biggestWidth: 0
|
handle: trayItem
|
||||||
required property PopoutState popouts
|
level: 0
|
||||||
property int rootWidth: 0
|
|
||||||
required property QsMenuHandle trayItem
|
required property QsMenuHandle trayItem
|
||||||
|
}
|
||||||
implicitHeight: currentItem.implicitHeight
|
|
||||||
implicitWidth: currentItem.implicitWidth
|
|
||||||
|
|
||||||
initialItem: SubMenu {
|
|
||||||
handle: root.trayItem
|
|
||||||
}
|
|
||||||
popEnter: NoAnim {
|
|
||||||
}
|
|
||||||
popExit: NoAnim {
|
|
||||||
}
|
|
||||||
pushEnter: NoAnim {
|
|
||||||
}
|
|
||||||
pushExit: NoAnim {
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: subMenuComp
|
|
||||||
|
|
||||||
SubMenu {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
component NoAnim: Transition {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
component SubMenu: Column {
|
|
||||||
id: menu
|
|
||||||
|
|
||||||
required property QsMenuHandle handle
|
|
||||||
property bool isSubMenu
|
|
||||||
property bool shown
|
|
||||||
|
|
||||||
opacity: shown ? 1 : 0
|
|
||||||
padding: 0
|
|
||||||
scale: shown ? 1 : 0.8
|
|
||||||
spacing: 4
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
Anim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Behavior on scale {
|
|
||||||
Anim {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: shown = true
|
|
||||||
StackView.onActivating: shown = true
|
|
||||||
StackView.onDeactivating: shown = false
|
|
||||||
StackView.onRemoved: destroy()
|
|
||||||
|
|
||||||
QsMenuOpener {
|
|
||||||
id: menuOpener
|
|
||||||
|
|
||||||
menu: menu.handle
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: menuOpener.children
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
id: item
|
|
||||||
|
|
||||||
required property int index
|
|
||||||
required property QsMenuEntry modelData
|
|
||||||
|
|
||||||
color: modelData.isSeparator ? DynamicColors.palette.m3outlineVariant : "transparent"
|
|
||||||
implicitHeight: modelData.isSeparator ? 1 : children.implicitHeight
|
|
||||||
implicitWidth: root.biggestWidth
|
|
||||||
radius: Appearance.rounding.full
|
|
||||||
visible: index !== (menuOpener.children.values.length - 1) ? true : (modelData.isSeparator ? false : true)
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: children
|
|
||||||
|
|
||||||
active: !item.modelData.isSeparator
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
asynchronous: true
|
|
||||||
|
|
||||||
sourceComponent: Item {
|
|
||||||
implicitHeight: 30
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
function onClicked(): void {
|
|
||||||
const entry = item.modelData;
|
|
||||||
if (entry.hasChildren) {
|
|
||||||
root.rootWidth = root.biggestWidth;
|
|
||||||
root.biggestWidth = 0;
|
|
||||||
root.push(subMenuComp.createObject(null, {
|
|
||||||
handle: entry,
|
|
||||||
isSubMenu: true
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
item.modelData.triggered();
|
|
||||||
root.popouts.hasCurrent = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
disabled: !item.modelData.enabled
|
|
||||||
radius: item.radius
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: icon
|
|
||||||
|
|
||||||
active: item.modelData.icon !== ""
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 10
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
asynchronous: true
|
|
||||||
|
|
||||||
sourceComponent: Item {
|
|
||||||
implicitHeight: label.implicitHeight
|
|
||||||
implicitWidth: label.implicitHeight
|
|
||||||
|
|
||||||
IconImage {
|
|
||||||
id: iconImage
|
|
||||||
|
|
||||||
implicitSize: parent.implicitHeight
|
|
||||||
source: item.modelData.icon
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiEffect {
|
|
||||||
anchors.fill: iconImage
|
|
||||||
colorization: 1.0
|
|
||||||
colorizationColor: item.modelData.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3outline
|
|
||||||
source: iconImage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
id: label
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 10
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
color: item.modelData.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3outline
|
|
||||||
text: labelMetrics.elidedText
|
|
||||||
}
|
|
||||||
|
|
||||||
TextMetrics {
|
|
||||||
id: labelMetrics
|
|
||||||
|
|
||||||
font.family: label.font.family
|
|
||||||
font.pointSize: label.font.pointSize
|
|
||||||
text: item.modelData.text
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
var biggestWidth = root.biggestWidth;
|
|
||||||
var currentWidth = labelMetrics.width + (item.modelData.icon ?? "" ? 30 : 0) + (item.modelData.hasChildren ? 30 : 0) + 20;
|
|
||||||
if (currentWidth > biggestWidth) {
|
|
||||||
root.biggestWidth = currentWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: expand
|
|
||||||
|
|
||||||
active: item.modelData.hasChildren
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
asynchronous: true
|
|
||||||
|
|
||||||
sourceComponent: MaterialIcon {
|
|
||||||
color: item.modelData.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3outline
|
|
||||||
text: "chevron_right"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: loader
|
|
||||||
|
|
||||||
active: menu.isSubMenu
|
|
||||||
asynchronous: true
|
|
||||||
|
|
||||||
sourceComponent: Item {
|
|
||||||
implicitHeight: 30
|
|
||||||
implicitWidth: back.implicitWidth
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
implicitHeight: 30
|
|
||||||
implicitWidth: root.biggestWidth
|
|
||||||
|
|
||||||
CustomRect {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: DynamicColors.palette.m3secondaryContainer
|
|
||||||
radius: Appearance.rounding.full
|
|
||||||
|
|
||||||
StateLayer {
|
|
||||||
function onClicked(): void {
|
|
||||||
root.pop();
|
|
||||||
root.biggestWidth = root.rootWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
color: DynamicColors.palette.m3onSecondaryContainer
|
|
||||||
radius: parent.radius
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: back
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
color: DynamicColors.palette.m3onSecondaryContainer
|
|
||||||
text: "chevron_left"
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomText {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
color: DynamicColors.palette.m3onSecondaryContainer
|
|
||||||
text: qsTr("Back")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+3
-1
@@ -15,13 +15,14 @@ Item {
|
|||||||
property real currentCenter
|
property real currentCenter
|
||||||
property alias currentName: popoutState.currentName
|
property alias currentName: popoutState.currentName
|
||||||
property string detachedMode
|
property string detachedMode
|
||||||
readonly property bool isDetached: detachedMode.length > 0
|
|
||||||
property alias hasCurrent: popoutState.hasCurrent
|
property alias hasCurrent: popoutState.hasCurrent
|
||||||
|
readonly property bool isDetached: detachedMode.length > 0
|
||||||
readonly property real nonAnimHeight: children.find(c => c.shouldBeActive)?.implicitHeight ?? content.implicitHeight
|
readonly property real nonAnimHeight: children.find(c => c.shouldBeActive)?.implicitHeight ?? content.implicitHeight
|
||||||
readonly property real nonAnimWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth
|
readonly property real nonAnimWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth
|
||||||
required property real offsetScale
|
required property real offsetScale
|
||||||
property string queuedMode
|
property string queuedMode
|
||||||
required property ShellScreen screen
|
required property ShellScreen screen
|
||||||
|
property alias state: popoutState
|
||||||
|
|
||||||
function close(): void {
|
function close(): void {
|
||||||
hasCurrent = false;
|
hasCurrent = false;
|
||||||
@@ -79,6 +80,7 @@ Item {
|
|||||||
|
|
||||||
sourceComponent: Content {
|
sourceComponent: Content {
|
||||||
popouts: popoutState
|
popouts: popoutState
|
||||||
|
screen: root.screen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,166 @@
|
|||||||
#include <qjsonarray.h>
|
#include <qjsonarray.h>
|
||||||
#include <qlocalsocket.h>
|
#include <qlocalsocket.h>
|
||||||
#include <qloggingcategory.h>
|
#include <qloggingcategory.h>
|
||||||
|
#include <qmetatype.h>
|
||||||
|
#include <qregularexpression.h>
|
||||||
#include <qvariant.h>
|
#include <qvariant.h>
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(lcHypr, "ZShell.internal.hypr", QtInfoMsg)
|
Q_LOGGING_CATEGORY(lcHypr, "ZShell.internal.hypr", QtInfoMsg)
|
||||||
|
|
||||||
namespace ZShell::internal::hypr {
|
namespace ZShell::internal::hypr {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static QString luaEscapeString(const QString& s) {
|
||||||
|
QString out;
|
||||||
|
out.reserve(s.size() + 2);
|
||||||
|
out += QLatin1Char('"');
|
||||||
|
|
||||||
|
for (const QChar c : s) {
|
||||||
|
switch (c.unicode()) {
|
||||||
|
case '\\':
|
||||||
|
out += QLatin1String(R"(\\)");
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
out += QLatin1String(R"(\")");
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
out += QLatin1String(R"(\n)");
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
out += QLatin1String(R"(\r)");
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
out += QLatin1String(R"(\t)");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out += c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out += QLatin1Char('"');
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString luaValue(const QVariant& v);
|
||||||
|
|
||||||
|
static QString luaArray(const QVariantList& list) {
|
||||||
|
QStringList parts;
|
||||||
|
parts.reserve(list.size());
|
||||||
|
|
||||||
|
for (const auto& item : list) {
|
||||||
|
parts << luaValue(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + QLatin1String(" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString luaArray(const QStringList& list) {
|
||||||
|
QStringList parts;
|
||||||
|
parts.reserve(list.size());
|
||||||
|
|
||||||
|
for (const auto& item : list) {
|
||||||
|
parts << luaEscapeString(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + QLatin1String(" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString luaMapFromHash(const QVariantHash& hash) {
|
||||||
|
QStringList parts;
|
||||||
|
parts.reserve(hash.size());
|
||||||
|
|
||||||
|
for (auto it = hash.cbegin(); it != hash.cend(); ++it) {
|
||||||
|
parts << luaEscapeString(it.key()) + QLatin1String(" = ") + luaValue(it.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + QLatin1String(" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString luaMap(const QVariantMap& map) {
|
||||||
|
QStringList parts;
|
||||||
|
parts.reserve(map.size());
|
||||||
|
|
||||||
|
for (auto it = map.cbegin(); it != map.cend(); ++it) {
|
||||||
|
parts << luaEscapeString(it.key()) + QLatin1String(" = ") + luaValue(it.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
return QLatin1String("{ ") + parts.join(QLatin1String(", ")) + QLatin1String(" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString luaValue(const QVariant& v) {
|
||||||
|
if (!v.isValid() || v.isNull()) {
|
||||||
|
return QLatin1String("nil");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (v.metaType().id()) {
|
||||||
|
case QMetaType::Bool:
|
||||||
|
return v.toBool() ? QLatin1String("true") : QLatin1String("false");
|
||||||
|
|
||||||
|
case QMetaType::Int:
|
||||||
|
case QMetaType::UInt:
|
||||||
|
case QMetaType::LongLong:
|
||||||
|
case QMetaType::ULongLong:
|
||||||
|
case QMetaType::Double:
|
||||||
|
return v.toString();
|
||||||
|
|
||||||
|
case QMetaType::QString:
|
||||||
|
return luaEscapeString(v.toString());
|
||||||
|
|
||||||
|
case QMetaType::QStringList:
|
||||||
|
return luaArray(v.toStringList());
|
||||||
|
|
||||||
|
case QMetaType::QVariantList:
|
||||||
|
return luaArray(v.toList());
|
||||||
|
|
||||||
|
case QMetaType::QVariantMap:
|
||||||
|
return luaMap(v.toMap());
|
||||||
|
|
||||||
|
case QMetaType::QVariantHash:
|
||||||
|
return luaMapFromHash(v.toHash());
|
||||||
|
|
||||||
|
default:
|
||||||
|
return luaEscapeString(v.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString normalizeOptionPath(QString key) {
|
||||||
|
key = key.trimmed();
|
||||||
|
key.replace(QLatin1Char(':'), QLatin1Char('.'));
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString buildHlConfigCall(const QString& key, const QVariant& value) {
|
||||||
|
const auto parts = normalizeOptionPath(key).split(QLatin1Char('.'), Qt::SkipEmptyParts);
|
||||||
|
if (parts.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QString out;
|
||||||
|
out.reserve(32 + key.size() + value.toString().size());
|
||||||
|
out += QLatin1String("hl.config({ ");
|
||||||
|
|
||||||
|
for (int i = 0; i < parts.size(); ++i) {
|
||||||
|
out += parts.at(i);
|
||||||
|
out += QLatin1String(" = ");
|
||||||
|
if (i + 1 < parts.size()) {
|
||||||
|
out += QLatin1String("{ ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out += luaValue(value);
|
||||||
|
|
||||||
|
for (int i = 0; i + 1 < parts.size(); ++i) {
|
||||||
|
out += QLatin1String(" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
out += QLatin1String(" })");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
HyprExtras::HyprExtras(QObject* parent)
|
HyprExtras::HyprExtras(QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_requestSocket("")
|
, m_requestSocket("")
|
||||||
@@ -26,7 +180,7 @@ HyprExtras::HyprExtras(QObject* parent)
|
|||||||
|
|
||||||
auto hyprDir = QString("%1/hypr/%2").arg(qEnvironmentVariable("XDG_RUNTIME_DIR"), his);
|
auto hyprDir = QString("%1/hypr/%2").arg(qEnvironmentVariable("XDG_RUNTIME_DIR"), his);
|
||||||
if (!QDir(hyprDir).exists()) {
|
if (!QDir(hyprDir).exists()) {
|
||||||
hyprDir = "/tmp/hypr/" + his;
|
hyprDir = QStringLiteral("/tmp/hypr/") + his;
|
||||||
|
|
||||||
if (!QDir(hyprDir).exists()) {
|
if (!QDir(hyprDir).exists()) {
|
||||||
qCWarning(lcHypr) << "Hyprland socket directory does not exist. Unable to connect to Hyprland socket.";
|
qCWarning(lcHypr) << "Hyprland socket directory does not exist. Unable to connect to Hyprland socket.";
|
||||||
@@ -34,8 +188,8 @@ HyprExtras::HyprExtras(QObject* parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_requestSocket = hyprDir + "/.socket.sock";
|
m_requestSocket = hyprDir + QStringLiteral("/.socket.sock");
|
||||||
m_eventSocket = hyprDir + "/.socket2.sock";
|
m_eventSocket = hyprDir + QStringLiteral("/.socket2.sock");
|
||||||
|
|
||||||
refreshOptions();
|
refreshOptions();
|
||||||
refreshDevices();
|
refreshDevices();
|
||||||
@@ -74,7 +228,8 @@ void HyprExtras::batchMessage(const QStringList& messages) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
makeRequest("[[BATCH]]" + messages.join(";"), [](bool success, const QByteArray& res) {
|
makeRequest(QStringLiteral("[[BATCH]]") + messages.join(QLatin1Char(';')),
|
||||||
|
[](bool success, const QByteArray& res) {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
qCWarning(lcHypr) << "batchMessage: request error:" << QString::fromUtf8(res);
|
qCWarning(lcHypr) << "batchMessage: request error:" << QString::fromUtf8(res);
|
||||||
}
|
}
|
||||||
@@ -86,14 +241,21 @@ void HyprExtras::applyOptions(const QVariantHash& options) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString request;
|
QStringList calls;
|
||||||
request.reserve(12 + options.size() * 40);
|
calls.reserve(options.size());
|
||||||
request += QLatin1String("[[BATCH]]");
|
|
||||||
for (auto it = options.constBegin(); it != options.constEnd(); ++it) {
|
for (auto it = options.constBegin(); it != options.constEnd(); ++it) {
|
||||||
request += QLatin1String("keyword ") + it.key() + QLatin1Char(' ') + it.value().toString() + QLatin1Char(';');
|
const auto call = buildHlConfigCall(it.key(), it.value());
|
||||||
|
if (!call.isEmpty()) {
|
||||||
|
calls << call;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
makeRequest(request, [this](bool success, const QByteArray& res) {
|
if (calls.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
makeRequest(QStringLiteral("eval ") + calls.join(QLatin1String("; ")), [this](bool success, const QByteArray& res) {
|
||||||
if (success) {
|
if (success) {
|
||||||
refreshOptions();
|
refreshOptions();
|
||||||
} else {
|
} else {
|
||||||
@@ -107,7 +269,7 @@ void HyprExtras::refreshOptions() {
|
|||||||
m_optionsRefresh->close();
|
m_optionsRefresh->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_optionsRefresh = makeRequestJson("descriptions", [this](bool success, const QJsonDocument& response) {
|
m_optionsRefresh = makeRequestJson(QStringLiteral("descriptions"), [this](bool success, const QJsonDocument& response) {
|
||||||
m_optionsRefresh.reset();
|
m_optionsRefresh.reset();
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return;
|
return;
|
||||||
@@ -118,8 +280,9 @@ void HyprExtras::refreshOptions() {
|
|||||||
|
|
||||||
for (const auto& o : std::as_const(options)) {
|
for (const auto& o : std::as_const(options)) {
|
||||||
const auto obj = o.toObject();
|
const auto obj = o.toObject();
|
||||||
const auto key = obj.value("value").toString();
|
const auto key = obj.value(QStringLiteral("value")).toString();
|
||||||
const auto value = obj.value("data").toObject().value("current").toVariant();
|
const auto value = obj.value(QStringLiteral("data")).toObject().value(QStringLiteral("current")).toVariant();
|
||||||
|
|
||||||
if (m_options.value(key) != value) {
|
if (m_options.value(key) != value) {
|
||||||
dirty = true;
|
dirty = true;
|
||||||
m_options.insert(key, value);
|
m_options.insert(key, value);
|
||||||
@@ -137,7 +300,7 @@ void HyprExtras::refreshDevices() {
|
|||||||
m_devicesRefresh->close();
|
m_devicesRefresh->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_devicesRefresh = makeRequestJson("devices", [this](bool success, const QJsonDocument& response) {
|
m_devicesRefresh = makeRequestJson(QStringLiteral("devices"), [this](bool success, const QJsonDocument& response) {
|
||||||
m_devicesRefresh.reset();
|
m_devicesRefresh.reset();
|
||||||
if (success) {
|
if (success) {
|
||||||
m_devices->updateLastIpcObject(response.object());
|
m_devices->updateLastIpcObject(response.object());
|
||||||
@@ -167,23 +330,23 @@ void HyprExtras::readEvent() {
|
|||||||
if (rawEvent.isEmpty()) {
|
if (rawEvent.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rawEvent.truncate(rawEvent.length() - 1); // Remove trailing \n
|
rawEvent.truncate(rawEvent.length() - 1);
|
||||||
const auto event = QByteArrayView(rawEvent.data(), rawEvent.indexOf(">>"));
|
const auto event = QByteArrayView(rawEvent.data(), rawEvent.indexOf(">>"));
|
||||||
handleEvent(QString::fromUtf8(event));
|
handleEvent(QString::fromUtf8(event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyprExtras::handleEvent(const QString& event) {
|
void HyprExtras::handleEvent(const QString& event) {
|
||||||
if (event == "configreloaded") {
|
if (event == QStringLiteral("configreloaded")) {
|
||||||
refreshOptions();
|
refreshOptions();
|
||||||
} else if (event == "activelayout") {
|
} else if (event == QStringLiteral("activelayout")) {
|
||||||
refreshDevices();
|
refreshDevices();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HyprExtras::SocketPtr HyprExtras::makeRequestJson(
|
HyprExtras::SocketPtr HyprExtras::makeRequestJson(
|
||||||
const QString& request, const std::function<void(bool, QJsonDocument)>& callback) {
|
const QString& request, const std::function<void(bool, QJsonDocument)>& callback) {
|
||||||
return makeRequest("j/" + request, [callback](bool success, const QByteArray& response) {
|
return makeRequest(QStringLiteral("j/") + request, [callback](bool success, const QByteArray& response) {
|
||||||
callback(success, QJsonDocument::fromJson(response));
|
callback(success, QJsonDocument::fromJson(response));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user