mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-03 20:32:07 -04:00
blur: add blur support with ext-bg-effect
This commit is contained in:
@@ -186,6 +186,14 @@ Singleton {
|
|||||||
onPopoutElevationEnabledChanged: saveSettings()
|
onPopoutElevationEnabledChanged: saveSettings()
|
||||||
property bool barElevationEnabled: true
|
property bool barElevationEnabled: true
|
||||||
onBarElevationEnabledChanged: saveSettings()
|
onBarElevationEnabledChanged: saveSettings()
|
||||||
|
property bool blurEnabled: false
|
||||||
|
onBlurEnabledChanged: saveSettings()
|
||||||
|
property string blurBorderColor: "outline"
|
||||||
|
onBlurBorderColorChanged: saveSettings()
|
||||||
|
property string blurBorderCustomColor: "#ffffff"
|
||||||
|
onBlurBorderCustomColorChanged: saveSettings()
|
||||||
|
property real blurBorderOpacity: 1.0
|
||||||
|
onBlurBorderOpacityChanged: saveSettings()
|
||||||
property string wallpaperFillMode: "Fill"
|
property string wallpaperFillMode: "Fill"
|
||||||
property bool blurredWallpaperLayer: false
|
property bool blurredWallpaperLayer: false
|
||||||
property bool blurWallpaperOnOverview: false
|
property bool blurWallpaperOnOverview: false
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ var SPEC = {
|
|||||||
modalElevationEnabled: { def: true },
|
modalElevationEnabled: { def: true },
|
||||||
popoutElevationEnabled: { def: true },
|
popoutElevationEnabled: { def: true },
|
||||||
barElevationEnabled: { def: true },
|
barElevationEnabled: { def: true },
|
||||||
|
blurEnabled: { def: false },
|
||||||
|
blurBorderColor: { def: "outline" },
|
||||||
|
blurBorderCustomColor: { def: "#ffffff" },
|
||||||
|
blurBorderOpacity: { def: 1.0, coerce: percentToUnit },
|
||||||
wallpaperFillMode: { def: "Fill" },
|
wallpaperFillMode: { def: "Fill" },
|
||||||
blurredWallpaperLayer: { def: false },
|
blurredWallpaperLayer: { def: false },
|
||||||
blurWallpaperOnOverview: { def: false },
|
blurWallpaperOnOverview: { def: false },
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import Quickshell
|
|||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -59,11 +60,25 @@ Item {
|
|||||||
function open() {
|
function open() {
|
||||||
closeTimer.stop();
|
closeTimer.stop();
|
||||||
const focusedScreen = CompositorService.getFocusedScreen();
|
const focusedScreen = CompositorService.getFocusedScreen();
|
||||||
|
const screenChanged = focusedScreen && contentWindow.screen !== focusedScreen;
|
||||||
if (focusedScreen) {
|
if (focusedScreen) {
|
||||||
|
if (screenChanged)
|
||||||
|
contentWindow.visible = false;
|
||||||
contentWindow.screen = focusedScreen;
|
contentWindow.screen = focusedScreen;
|
||||||
if (!useSingleWindow)
|
if (!useSingleWindow) {
|
||||||
|
if (screenChanged)
|
||||||
|
clickCatcher.visible = false;
|
||||||
clickCatcher.screen = focusedScreen;
|
clickCatcher.screen = focusedScreen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (screenChanged) {
|
||||||
|
Qt.callLater(() => root._finishOpen());
|
||||||
|
} else {
|
||||||
|
_finishOpen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _finishOpen() {
|
||||||
ModalManager.openModal(root);
|
ModalManager.openModal(root);
|
||||||
shouldBeVisible = true;
|
shouldBeVisible = true;
|
||||||
if (!useSingleWindow)
|
if (!useSingleWindow)
|
||||||
@@ -215,6 +230,16 @@ Item {
|
|||||||
visible: false
|
visible: false
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: contentWindow
|
||||||
|
readonly property real s: Math.min(1, modalContainer.scaleValue)
|
||||||
|
blurX: modalContainer.x + modalContainer.width * (1 - s) * 0.5 + Theme.snap(modalContainer.animX, root.dpr)
|
||||||
|
blurY: modalContainer.y + modalContainer.height * (1 - s) * 0.5 + Theme.snap(modalContainer.animY, root.dpr)
|
||||||
|
blurWidth: (shouldBeVisible && animatedContent.opacity > 0) ? modalContainer.width * s : 0
|
||||||
|
blurHeight: (shouldBeVisible && animatedContent.opacity > 0) ? modalContainer.height * s : 0
|
||||||
|
blurRadius: root.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
WlrLayershell.namespace: root.layerNamespace
|
WlrLayershell.namespace: root.layerNamespace
|
||||||
WlrLayershell.layer: {
|
WlrLayershell.layer: {
|
||||||
if (root.useOverlayLayer)
|
if (root.useOverlayLayer)
|
||||||
@@ -393,6 +418,15 @@ Item {
|
|||||||
shadowEnabled: root.enableShadow && Theme.elevationEnabled && SettingsData.modalElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
shadowEnabled: root.enableShadow && Theme.elevationEnabled && SettingsData.modalElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: root.cornerRadius
|
||||||
|
color: "transparent"
|
||||||
|
border.color: BlurService.borderColor
|
||||||
|
border.width: BlurService.borderWidth
|
||||||
|
z: 100
|
||||||
|
}
|
||||||
|
|
||||||
FocusScope {
|
FocusScope {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
focus: root.shouldBeVisible
|
focus: root.shouldBeVisible
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Quickshell.Wayland
|
|||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -134,40 +135,47 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function show() {
|
function _finishShow(query, mode) {
|
||||||
closeCleanupTimer.stop();
|
spotlightOpen = true;
|
||||||
isClosing = false;
|
isClosing = false;
|
||||||
openedFromOverview = false;
|
openedFromOverview = false;
|
||||||
|
|
||||||
var focusedScreen = CompositorService.getFocusedScreen();
|
|
||||||
if (focusedScreen)
|
|
||||||
launcherWindow.screen = focusedScreen;
|
|
||||||
|
|
||||||
spotlightOpen = true;
|
|
||||||
keyboardActive = true;
|
keyboardActive = true;
|
||||||
ModalManager.openModal(root);
|
ModalManager.openModal(root);
|
||||||
if (useHyprlandFocusGrab)
|
if (useHyprlandFocusGrab)
|
||||||
focusGrab.active = true;
|
focusGrab.active = true;
|
||||||
|
|
||||||
_ensureContentLoadedAndInitialize("", "");
|
_ensureContentLoadedAndInitialize(query || "", mode || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function show() {
|
||||||
|
closeCleanupTimer.stop();
|
||||||
|
|
||||||
|
var focusedScreen = CompositorService.getFocusedScreen();
|
||||||
|
if (focusedScreen && launcherWindow.screen !== focusedScreen) {
|
||||||
|
spotlightOpen = false;
|
||||||
|
isClosing = false;
|
||||||
|
launcherWindow.screen = focusedScreen;
|
||||||
|
Qt.callLater(() => root._finishShow("", ""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_finishShow("", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
function showWithQuery(query) {
|
function showWithQuery(query) {
|
||||||
closeCleanupTimer.stop();
|
closeCleanupTimer.stop();
|
||||||
isClosing = false;
|
|
||||||
openedFromOverview = false;
|
|
||||||
|
|
||||||
var focusedScreen = CompositorService.getFocusedScreen();
|
var focusedScreen = CompositorService.getFocusedScreen();
|
||||||
if (focusedScreen)
|
if (focusedScreen && launcherWindow.screen !== focusedScreen) {
|
||||||
|
spotlightOpen = false;
|
||||||
|
isClosing = false;
|
||||||
launcherWindow.screen = focusedScreen;
|
launcherWindow.screen = focusedScreen;
|
||||||
|
Qt.callLater(() => root._finishShow(query, ""));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
spotlightOpen = true;
|
_finishShow(query, "");
|
||||||
keyboardActive = true;
|
|
||||||
ModalManager.openModal(root);
|
|
||||||
if (useHyprlandFocusGrab)
|
|
||||||
focusGrab.active = true;
|
|
||||||
|
|
||||||
_ensureContentLoadedAndInitialize(query, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide() {
|
function hide() {
|
||||||
@@ -191,14 +199,20 @@ Item {
|
|||||||
|
|
||||||
function showWithMode(mode) {
|
function showWithMode(mode) {
|
||||||
closeCleanupTimer.stop();
|
closeCleanupTimer.stop();
|
||||||
|
|
||||||
|
var focusedScreen = CompositorService.getFocusedScreen();
|
||||||
|
if (focusedScreen && launcherWindow.screen !== focusedScreen) {
|
||||||
|
spotlightOpen = false;
|
||||||
|
isClosing = false;
|
||||||
|
launcherWindow.screen = focusedScreen;
|
||||||
|
Qt.callLater(() => root._finishShow("", mode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
spotlightOpen = true;
|
||||||
isClosing = false;
|
isClosing = false;
|
||||||
openedFromOverview = false;
|
openedFromOverview = false;
|
||||||
|
|
||||||
var focusedScreen = CompositorService.getFocusedScreen();
|
|
||||||
if (focusedScreen)
|
|
||||||
launcherWindow.screen = focusedScreen;
|
|
||||||
|
|
||||||
spotlightOpen = true;
|
|
||||||
keyboardActive = true;
|
keyboardActive = true;
|
||||||
ModalManager.openModal(root);
|
ModalManager.openModal(root);
|
||||||
if (useHyprlandFocusGrab)
|
if (useHyprlandFocusGrab)
|
||||||
@@ -295,6 +309,16 @@ Item {
|
|||||||
color: "transparent"
|
color: "transparent"
|
||||||
exclusionMode: ExclusionMode.Ignore
|
exclusionMode: ExclusionMode.Ignore
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: launcherWindow
|
||||||
|
readonly property real s: Math.min(1, modalContainer.scale)
|
||||||
|
blurX: root.modalX + root.modalWidth * (1 - s) * 0.5
|
||||||
|
blurY: root.modalY + root.modalHeight * (1 - s) * 0.5
|
||||||
|
blurWidth: (contentVisible && modalContainer.opacity > 0) ? root.modalWidth * s : 0
|
||||||
|
blurHeight: (contentVisible && modalContainer.opacity > 0) ? root.modalHeight * s : 0
|
||||||
|
blurRadius: root.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
WlrLayershell.namespace: "dms:spotlight"
|
WlrLayershell.namespace: "dms:spotlight"
|
||||||
WlrLayershell.layer: {
|
WlrLayershell.layer: {
|
||||||
switch (Quickshell.env("DMS_MODAL_LAYER")) {
|
switch (Quickshell.env("DMS_MODAL_LAYER")) {
|
||||||
@@ -428,6 +452,14 @@ Item {
|
|||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: root.cornerRadius
|
||||||
|
color: "transparent"
|
||||||
|
border.color: BlurService.borderColor
|
||||||
|
border.width: BlurService.borderWidth
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Item {
|
|||||||
property real barThickness: 48
|
property real barThickness: 48
|
||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
|
property var blurBarWindow: null
|
||||||
property bool overrideAxisLayout: false
|
property bool overrideAxisLayout: false
|
||||||
property bool forceVerticalLayout: false
|
property bool forceVerticalLayout: false
|
||||||
|
|
||||||
@@ -357,6 +358,7 @@ Item {
|
|||||||
barThickness: root.barThickness
|
barThickness: root.barThickness
|
||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
|
blurBarWindow: root.blurBarWindow
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === centerRepeater.count - 1
|
isLast: index === centerRepeater.count - 1
|
||||||
sectionSpacing: parent.itemSpacing
|
sectionSpacing: parent.itemSpacing
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ Item {
|
|||||||
required property var rootWindow
|
required property var rootWindow
|
||||||
required property var barConfig
|
required property var barConfig
|
||||||
|
|
||||||
|
readonly property var blurBarWindow: barWindow
|
||||||
|
|
||||||
property var leftWidgetsModel
|
property var leftWidgetsModel
|
||||||
property var centerWidgetsModel
|
property var centerWidgetsModel
|
||||||
property var rightWidgetsModel
|
property var rightWidgetsModel
|
||||||
@@ -408,6 +410,12 @@ Item {
|
|||||||
value: topBarContent.barConfig
|
value: topBarContent.barConfig
|
||||||
restoreMode: Binding.RestoreNone
|
restoreMode: Binding.RestoreNone
|
||||||
}
|
}
|
||||||
|
Binding {
|
||||||
|
target: hLeftSection
|
||||||
|
property: "blurBarWindow"
|
||||||
|
value: topBarContent.blurBarWindow
|
||||||
|
restoreMode: Binding.RestoreNone
|
||||||
|
}
|
||||||
|
|
||||||
RightSection {
|
RightSection {
|
||||||
id: hRightSection
|
id: hRightSection
|
||||||
@@ -434,6 +442,12 @@ Item {
|
|||||||
value: topBarContent.barConfig
|
value: topBarContent.barConfig
|
||||||
restoreMode: Binding.RestoreNone
|
restoreMode: Binding.RestoreNone
|
||||||
}
|
}
|
||||||
|
Binding {
|
||||||
|
target: hRightSection
|
||||||
|
property: "blurBarWindow"
|
||||||
|
value: topBarContent.blurBarWindow
|
||||||
|
restoreMode: Binding.RestoreNone
|
||||||
|
}
|
||||||
|
|
||||||
CenterSection {
|
CenterSection {
|
||||||
id: hCenterSection
|
id: hCenterSection
|
||||||
@@ -460,6 +474,12 @@ Item {
|
|||||||
value: topBarContent.barConfig
|
value: topBarContent.barConfig
|
||||||
restoreMode: Binding.RestoreNone
|
restoreMode: Binding.RestoreNone
|
||||||
}
|
}
|
||||||
|
Binding {
|
||||||
|
target: hCenterSection
|
||||||
|
property: "blurBarWindow"
|
||||||
|
value: topBarContent.blurBarWindow
|
||||||
|
restoreMode: Binding.RestoreNone
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -493,6 +513,12 @@ Item {
|
|||||||
value: topBarContent.barConfig
|
value: topBarContent.barConfig
|
||||||
restoreMode: Binding.RestoreNone
|
restoreMode: Binding.RestoreNone
|
||||||
}
|
}
|
||||||
|
Binding {
|
||||||
|
target: vLeftSection
|
||||||
|
property: "blurBarWindow"
|
||||||
|
value: topBarContent.blurBarWindow
|
||||||
|
restoreMode: Binding.RestoreNone
|
||||||
|
}
|
||||||
|
|
||||||
CenterSection {
|
CenterSection {
|
||||||
id: vCenterSection
|
id: vCenterSection
|
||||||
@@ -520,6 +546,12 @@ Item {
|
|||||||
value: topBarContent.barConfig
|
value: topBarContent.barConfig
|
||||||
restoreMode: Binding.RestoreNone
|
restoreMode: Binding.RestoreNone
|
||||||
}
|
}
|
||||||
|
Binding {
|
||||||
|
target: vCenterSection
|
||||||
|
property: "blurBarWindow"
|
||||||
|
value: topBarContent.blurBarWindow
|
||||||
|
restoreMode: Binding.RestoreNone
|
||||||
|
}
|
||||||
|
|
||||||
RightSection {
|
RightSection {
|
||||||
id: vRightSection
|
id: vRightSection
|
||||||
@@ -548,6 +580,12 @@ Item {
|
|||||||
value: topBarContent.barConfig
|
value: topBarContent.barConfig
|
||||||
restoreMode: Binding.RestoreNone
|
restoreMode: Binding.RestoreNone
|
||||||
}
|
}
|
||||||
|
Binding {
|
||||||
|
target: vRightSection
|
||||||
|
property: "blurBarWindow"
|
||||||
|
value: topBarContent.blurBarWindow
|
||||||
|
restoreMode: Binding.RestoreNone
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,112 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property var blurRegion: null
|
||||||
|
property var _blurWidgetItems: []
|
||||||
|
|
||||||
|
function registerBlurWidget(item) {
|
||||||
|
if (_blurWidgetItems.indexOf(item) >= 0)
|
||||||
|
return;
|
||||||
|
_blurWidgetItems = _blurWidgetItems.concat([item]);
|
||||||
|
_blurRebuildTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function unregisterBlurWidget(item) {
|
||||||
|
const idx = _blurWidgetItems.indexOf(item);
|
||||||
|
if (idx < 0)
|
||||||
|
return;
|
||||||
|
const arr = _blurWidgetItems.slice();
|
||||||
|
arr.splice(idx, 1);
|
||||||
|
_blurWidgetItems = arr;
|
||||||
|
_blurRebuildTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: _blurRebuildTimer
|
||||||
|
interval: 1
|
||||||
|
onTriggered: barBlur.rebuild()
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: barBlur
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
readonly property bool barHasTransparency: barWindow._backgroundAlpha > 0 && barWindow._backgroundAlpha < 1
|
||||||
|
|
||||||
|
function rebuild() {
|
||||||
|
teardown();
|
||||||
|
if (!BlurService.enabled || !BlurService.available)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const widgets = barWindow._blurWidgetItems.filter(w => w && w.visible && w.width > 0 && w.height > 0);
|
||||||
|
const hasBar = barHasTransparency;
|
||||||
|
if (!hasBar && widgets.length === 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const cr = Theme.cornerRadius;
|
||||||
|
let qml = 'import QtQuick; import Quickshell; Region {';
|
||||||
|
for (let i = 0; i < widgets.length; i++) {
|
||||||
|
qml += ` property Item w${i}; Region { item: w${i}; radius: ${cr} }`;
|
||||||
|
}
|
||||||
|
qml += '}';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const region = Qt.createQmlObject(qml, barWindow, "BarBlurRegion");
|
||||||
|
|
||||||
|
if (hasBar) {
|
||||||
|
region.x = Qt.binding(() => topBarMouseArea.x + barUnitInset.x + topBarSlide.x);
|
||||||
|
region.y = Qt.binding(() => topBarMouseArea.y + barUnitInset.y + topBarSlide.y);
|
||||||
|
region.width = Qt.binding(() => barUnitInset.width);
|
||||||
|
region.height = Qt.binding(() => barUnitInset.height);
|
||||||
|
region.radius = Qt.binding(() => barBackground.rt);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < widgets.length; i++) {
|
||||||
|
region[`w${i}`] = widgets[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
barWindow.BackgroundEffect.blurRegion = region;
|
||||||
|
barWindow.blurRegion = region;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("BarBlur: Failed to create blur region:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function teardown() {
|
||||||
|
if (!barWindow.blurRegion)
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
barWindow.BackgroundEffect.blurRegion = null;
|
||||||
|
} catch (e) {}
|
||||||
|
barWindow.blurRegion.destroy();
|
||||||
|
barWindow.blurRegion = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onBarHasTransparencyChanged: _blurRebuildTimer.restart()
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: BlurService
|
||||||
|
function onEnabledChanged() {
|
||||||
|
barBlur.rebuild();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: topBarSlide
|
||||||
|
function onXChanged() {
|
||||||
|
if (barWindow.blurRegion)
|
||||||
|
barWindow.blurRegion.changed();
|
||||||
|
}
|
||||||
|
function onYChanged() {
|
||||||
|
if (barWindow.blurRegion)
|
||||||
|
barWindow.blurRegion.changed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: rebuild()
|
||||||
|
Component.onDestruction: teardown()
|
||||||
|
}
|
||||||
|
|
||||||
WlrLayershell.layer: dBarLayer
|
WlrLayershell.layer: dBarLayer
|
||||||
WlrLayershell.namespace: "dms:bar"
|
WlrLayershell.namespace: "dms:bar"
|
||||||
|
|
||||||
@@ -711,7 +817,8 @@ PanelWindow {
|
|||||||
onHasActivePopoutChanged: evaluateReveal()
|
onHasActivePopoutChanged: evaluateReveal()
|
||||||
|
|
||||||
function updateActivePopoutState() {
|
function updateActivePopoutState() {
|
||||||
if (!barWindow.screen) return;
|
if (!barWindow.screen)
|
||||||
|
return;
|
||||||
const screenName = barWindow.screen.name;
|
const screenName = barWindow.screen.name;
|
||||||
const activePopout = PopoutManager.currentPopoutsByScreen[screenName];
|
const activePopout = PopoutManager.currentPopoutsByScreen[screenName];
|
||||||
const activeTrayMenu = TrayMenuManager.activeTrayMenus[screenName];
|
const activeTrayMenu = TrayMenuManager.activeTrayMenus[screenName];
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ Item {
|
|||||||
property real barThickness: 48
|
property real barThickness: 48
|
||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
|
property var blurBarWindow: null
|
||||||
property bool overrideAxisLayout: false
|
property bool overrideAxisLayout: false
|
||||||
property bool forceVerticalLayout: false
|
property bool forceVerticalLayout: false
|
||||||
|
|
||||||
@@ -59,6 +60,7 @@ Item {
|
|||||||
barThickness: root.barThickness
|
barThickness: root.barThickness
|
||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
|
blurBarWindow: root.blurBarWindow
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === rowRepeater.count - 1
|
isLast: index === rowRepeater.count - 1
|
||||||
sectionSpacing: parent.rowSpacing
|
sectionSpacing: parent.rowSpacing
|
||||||
@@ -103,6 +105,7 @@ Item {
|
|||||||
barThickness: root.barThickness
|
barThickness: root.barThickness
|
||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
|
blurBarWindow: root.blurBarWindow
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === columnRepeater.count - 1
|
isLast: index === columnRepeater.count - 1
|
||||||
sectionSpacing: parent.columnSpacing
|
sectionSpacing: parent.columnSpacing
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ Item {
|
|||||||
property real barThickness: 48
|
property real barThickness: 48
|
||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
|
property var blurBarWindow: null
|
||||||
property bool overrideAxisLayout: false
|
property bool overrideAxisLayout: false
|
||||||
property bool forceVerticalLayout: false
|
property bool forceVerticalLayout: false
|
||||||
|
|
||||||
@@ -61,6 +62,7 @@ Item {
|
|||||||
barThickness: root.barThickness
|
barThickness: root.barThickness
|
||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
|
blurBarWindow: root.blurBarWindow
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === rowRepeater.count - 1
|
isLast: index === rowRepeater.count - 1
|
||||||
sectionSpacing: parent.rowSpacing
|
sectionSpacing: parent.rowSpacing
|
||||||
@@ -105,6 +107,7 @@ Item {
|
|||||||
barThickness: root.barThickness
|
barThickness: root.barThickness
|
||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
|
blurBarWindow: root.blurBarWindow
|
||||||
isFirst: index === 0
|
isFirst: index === 0
|
||||||
isLast: index === columnRepeater.count - 1
|
isLast: index === columnRepeater.count - 1
|
||||||
sectionSpacing: parent.columnSpacing
|
sectionSpacing: parent.columnSpacing
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Loader {
|
|||||||
property real barThickness: 48
|
property real barThickness: 48
|
||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
|
property var blurBarWindow: null
|
||||||
property bool isFirst: false
|
property bool isFirst: false
|
||||||
property bool isLast: false
|
property bool isLast: false
|
||||||
property real sectionSpacing: 0
|
property real sectionSpacing: 0
|
||||||
@@ -92,6 +93,14 @@ Loader {
|
|||||||
restoreMode: Binding.RestoreNone
|
restoreMode: Binding.RestoreNone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: root.item
|
||||||
|
when: root.item && "blurBarWindow" in root.item
|
||||||
|
property: "blurBarWindow"
|
||||||
|
value: root.blurBarWindow
|
||||||
|
restoreMode: Binding.RestoreNone
|
||||||
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
target: root.item
|
target: root.item
|
||||||
when: root.item && "axis" in root.item
|
when: root.item && "axis" in root.item
|
||||||
|
|||||||
@@ -630,7 +630,7 @@ BasePill {
|
|||||||
if (appItem.isFocused && colorizeEnabled) {
|
if (appItem.isFocused && colorizeEnabled) {
|
||||||
return mouseArea.containsMouse ? Theme.withAlpha(Qt.lighter(appItem.activeOverlayColor, 1.3), 0.4) : Theme.withAlpha(appItem.activeOverlayColor, 0.3);
|
return mouseArea.containsMouse ? Theme.withAlpha(Qt.lighter(appItem.activeOverlayColor, 1.3), 0.4) : Theme.withAlpha(appItem.activeOverlayColor, 0.3);
|
||||||
}
|
}
|
||||||
return mouseArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent";
|
return mouseArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent";
|
||||||
}
|
}
|
||||||
|
|
||||||
border.width: dragHandler.dragging ? 2 : 0
|
border.width: dragHandler.dragging ? 2 : 0
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import Quickshell
|
|||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Modules.Plugins
|
import qs.Modules.Plugins
|
||||||
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
BasePill {
|
BasePill {
|
||||||
@@ -93,6 +94,15 @@ BasePill {
|
|||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: contextMenuWindow
|
id: contextMenuWindow
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: contextMenuWindow
|
||||||
|
blurX: menuContainer.x
|
||||||
|
blurY: menuContainer.y
|
||||||
|
blurWidth: contextMenuWindow.visible ? menuContainer.width : 0
|
||||||
|
blurHeight: contextMenuWindow.visible ? menuContainer.height : 0
|
||||||
|
blurRadius: Theme.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
WlrLayershell.namespace: "dms:clipboard-context-menu"
|
WlrLayershell.namespace: "dms:clipboard-context-menu"
|
||||||
|
|
||||||
property bool isVertical: false
|
property bool isVertical: false
|
||||||
@@ -187,8 +197,8 @@ BasePill {
|
|||||||
height: Math.max(64, menuColumn.implicitHeight + Theme.spacingS * 2)
|
height: Math.max(64, menuColumn.implicitHeight + Theme.spacingS * 2)
|
||||||
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: BlurService.enabled ? BlurService.borderColor : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: BlurService.enabled ? BlurService.borderWidth : 1
|
||||||
|
|
||||||
opacity: contextMenuWindow.visible ? 1 : 0
|
opacity: contextMenuWindow.visible ? 1 : 0
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
@@ -224,7 +234,7 @@ BasePill {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 30
|
height: 30
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: clearAllArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: clearAllArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -264,7 +274,7 @@ BasePill {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 30
|
height: 30
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: savedItemsArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: savedItemsArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ BasePill {
|
|||||||
height: 20
|
height: 20
|
||||||
radius: 10
|
radius: 10
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: prevArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: prevArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
visible: root.playerAvailable
|
visible: root.playerAvailable
|
||||||
opacity: (activePlayer && activePlayer.canGoPrevious) ? 1 : 0.3
|
opacity: (activePlayer && activePlayer.canGoPrevious) ? 1 : 0.3
|
||||||
|
|
||||||
@@ -411,7 +411,7 @@ BasePill {
|
|||||||
height: 20
|
height: 20
|
||||||
radius: 10
|
radius: 10
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
color: nextArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: nextArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
visible: playerAvailable
|
visible: playerAvailable
|
||||||
opacity: (activePlayer && activePlayer.canGoNext) ? 1 : 0.3
|
opacity: (activePlayer && activePlayer.canGoNext) ? 1 : 0.3
|
||||||
|
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ BasePill {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 30
|
height: 30
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: tabArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: tabArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -327,7 +327,7 @@ BasePill {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 30
|
height: 30
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: newNoteArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: newNoteArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ BasePill {
|
|||||||
if (isFocused) {
|
if (isFocused) {
|
||||||
return mouseArea.containsMouse ? Theme.primarySelected : Theme.withAlpha(Theme.primary, 0.2);
|
return mouseArea.containsMouse ? Theme.primarySelected : Theme.withAlpha(Theme.primary, 0.2);
|
||||||
}
|
}
|
||||||
return mouseArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent";
|
return mouseArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent";
|
||||||
}
|
}
|
||||||
|
|
||||||
// App icon
|
// App icon
|
||||||
@@ -528,7 +528,7 @@ BasePill {
|
|||||||
if (isFocused) {
|
if (isFocused) {
|
||||||
return mouseArea.containsMouse ? Theme.primarySelected : Theme.withAlpha(Theme.primary, 0.2);
|
return mouseArea.containsMouse ? Theme.primarySelected : Theme.withAlpha(Theme.primary, 0.2);
|
||||||
}
|
}
|
||||||
return mouseArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent";
|
return mouseArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent";
|
||||||
}
|
}
|
||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
@@ -738,6 +738,15 @@ BasePill {
|
|||||||
sourceComponent: PanelWindow {
|
sourceComponent: PanelWindow {
|
||||||
id: contextMenuWindow
|
id: contextMenuWindow
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: contextMenuWindow
|
||||||
|
blurX: contextMenuRect.x
|
||||||
|
blurY: contextMenuRect.y
|
||||||
|
blurWidth: contextMenuWindow.isVisible ? contextMenuRect.width : 0
|
||||||
|
blurHeight: contextMenuWindow.isVisible ? contextMenuRect.height : 0
|
||||||
|
blurRadius: Theme.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
property var currentWindow: null
|
property var currentWindow: null
|
||||||
property bool isVisible: false
|
property bool isVisible: false
|
||||||
property point anchorPos: Qt.point(0, 0)
|
property point anchorPos: Qt.point(0, 0)
|
||||||
@@ -830,6 +839,7 @@ BasePill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: contextMenuRect
|
||||||
x: {
|
x: {
|
||||||
if (contextMenuWindow.isVertical) {
|
if (contextMenuWindow.isVertical) {
|
||||||
if (contextMenuWindow.edge === "left") {
|
if (contextMenuWindow.edge === "left") {
|
||||||
@@ -858,13 +868,13 @@ BasePill {
|
|||||||
height: 32
|
height: 32
|
||||||
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.width: 1
|
border.width: BlurService.enabled ? BlurService.borderWidth : 1
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: BlurService.enabled ? BlurService.borderColor : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: parent.radius
|
radius: parent.radius
|
||||||
color: closeMouseArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: closeMouseArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ BasePill {
|
|||||||
height: root.trayItemSize
|
height: root.trayItemSize
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: trayItemArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: trayItemArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
border.width: dragHandler.dragging ? 2 : 0
|
border.width: dragHandler.dragging ? 2 : 0
|
||||||
border.color: Theme.primary
|
border.color: Theme.primary
|
||||||
opacity: dragHandler.dragging ? 0.8 : 1.0
|
opacity: dragHandler.dragging ? 0.8 : 1.0
|
||||||
@@ -425,7 +425,7 @@ BasePill {
|
|||||||
height: root.trayItemSize
|
height: root.trayItemSize
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: caretArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: caretArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -547,7 +547,7 @@ BasePill {
|
|||||||
height: root.trayItemSize
|
height: root.trayItemSize
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: trayItemArea.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: trayItemArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
border.width: dragHandler.dragging ? 2 : 0
|
border.width: dragHandler.dragging ? 2 : 0
|
||||||
border.color: Theme.primary
|
border.color: Theme.primary
|
||||||
opacity: dragHandler.dragging ? 0.8 : 1.0
|
opacity: dragHandler.dragging ? 0.8 : 1.0
|
||||||
@@ -685,7 +685,7 @@ BasePill {
|
|||||||
height: root.trayItemSize
|
height: root.trayItemSize
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: caretAreaVert.containsMouse ? Theme.widgetBaseHoverColor : "transparent"
|
color: caretAreaVert.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : "transparent"
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -723,6 +723,16 @@ BasePill {
|
|||||||
|
|
||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: overflowMenu
|
id: overflowMenu
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: overflowMenu
|
||||||
|
blurX: menuContainer.x
|
||||||
|
blurY: menuContainer.y
|
||||||
|
blurWidth: root.menuOpen ? menuContainer.width : 0
|
||||||
|
blurHeight: root.menuOpen ? menuContainer.height : 0
|
||||||
|
blurRadius: Theme.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
visible: root.menuOpen
|
visible: root.menuOpen
|
||||||
screen: root.parentScreen
|
screen: root.parentScreen
|
||||||
WlrLayershell.layer: WlrLayershell.Top
|
WlrLayershell.layer: WlrLayershell.Top
|
||||||
@@ -990,6 +1000,15 @@ BasePill {
|
|||||||
layer.samples: 4
|
layer.samples: 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
border.color: BlurService.borderColor
|
||||||
|
border.width: BlurService.borderWidth
|
||||||
|
z: 100
|
||||||
|
}
|
||||||
|
|
||||||
Grid {
|
Grid {
|
||||||
id: menuGrid
|
id: menuGrid
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -1030,7 +1049,7 @@ BasePill {
|
|||||||
width: root.trayItemSize + 4
|
width: root.trayItemSize + 4
|
||||||
height: root.trayItemSize + 4
|
height: root.trayItemSize + 4
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: itemArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.withAlpha(Theme.surfaceContainer, 0)
|
color: itemArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : Theme.withAlpha(Theme.surfaceContainer, 0)
|
||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
id: menuIconImg
|
id: menuIconImg
|
||||||
@@ -1191,6 +1210,15 @@ BasePill {
|
|||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: menuWindow
|
id: menuWindow
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: menuWindow
|
||||||
|
blurX: trayMenuContainer.x
|
||||||
|
blurY: trayMenuContainer.y
|
||||||
|
blurWidth: menuRoot.showMenu ? trayMenuContainer.width : 0
|
||||||
|
blurHeight: menuRoot.showMenu ? trayMenuContainer.height : 0
|
||||||
|
blurRadius: Theme.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
WlrLayershell.namespace: "dms:tray-menu-window"
|
WlrLayershell.namespace: "dms:tray-menu-window"
|
||||||
visible: menuRoot.showMenu && (menuRoot.trayItem?.hasMenu ?? false)
|
visible: menuRoot.showMenu && (menuRoot.trayItem?.hasMenu ?? false)
|
||||||
WlrLayershell.layer: WlrLayershell.Top
|
WlrLayershell.layer: WlrLayershell.Top
|
||||||
@@ -1302,7 +1330,7 @@ BasePill {
|
|||||||
onClicked: mouse => {
|
onClicked: mouse => {
|
||||||
const clickX = mouse.x + menuWindow.maskX;
|
const clickX = mouse.x + menuWindow.maskX;
|
||||||
const clickY = mouse.y + menuWindow.maskY;
|
const clickY = mouse.y + menuWindow.maskY;
|
||||||
const outsideContent = clickX < menuContainer.x || clickX > menuContainer.x + menuContainer.width || clickY < menuContainer.y || clickY > menuContainer.y + menuContainer.height;
|
const outsideContent = clickX < trayMenuContainer.x || clickX > trayMenuContainer.x + trayMenuContainer.width || clickY < trayMenuContainer.y || clickY > trayMenuContainer.y + trayMenuContainer.height;
|
||||||
|
|
||||||
if (!outsideContent)
|
if (!outsideContent)
|
||||||
return;
|
return;
|
||||||
@@ -1360,7 +1388,7 @@ BasePill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: menuContainer
|
id: trayMenuContainer
|
||||||
|
|
||||||
readonly property real rawWidth: Math.min(500, Math.max(250, menuColumn.implicitWidth + Theme.spacingS * 2))
|
readonly property real rawWidth: Math.min(500, Math.max(250, menuColumn.implicitWidth + Theme.spacingS * 2))
|
||||||
readonly property real rawHeight: Math.max(40, menuColumn.implicitHeight + Theme.spacingS * 2)
|
readonly property real rawHeight: Math.max(40, menuColumn.implicitHeight + Theme.spacingS * 2)
|
||||||
@@ -1438,6 +1466,15 @@ BasePill {
|
|||||||
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
border.color: BlurService.borderColor
|
||||||
|
border.width: BlurService.borderWidth
|
||||||
|
z: 100
|
||||||
|
}
|
||||||
|
|
||||||
QsMenuAnchor {
|
QsMenuAnchor {
|
||||||
id: submenuHydrator
|
id: submenuHydrator
|
||||||
anchor.window: menuWindow
|
anchor.window: menuWindow
|
||||||
@@ -1470,7 +1507,7 @@ BasePill {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 28
|
height: 28
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: visibilityToggleArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.withAlpha(Theme.surfaceContainer, 0)
|
color: visibilityToggleArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : Theme.withAlpha(Theme.surfaceContainer, 0)
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -1523,7 +1560,7 @@ BasePill {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 28
|
height: 28
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: backArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.withAlpha(Theme.surfaceContainer, 0)
|
color: backArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : Theme.withAlpha(Theme.surfaceContainer, 0)
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -1574,7 +1611,7 @@ BasePill {
|
|||||||
color: {
|
color: {
|
||||||
if (menuEntry?.isSeparator)
|
if (menuEntry?.isSeparator)
|
||||||
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2);
|
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2);
|
||||||
return itemArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.withAlpha(Theme.surfaceContainer, 0);
|
return itemArea.containsMouse ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : Theme.withAlpha(Theme.surfaceContainer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ Item {
|
|||||||
property real widgetHeight: 30
|
property real widgetHeight: 30
|
||||||
property real barThickness: 48
|
property real barThickness: 48
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
|
property var blurBarWindow: null
|
||||||
property var hyprlandOverviewLoader: null
|
property var hyprlandOverviewLoader: null
|
||||||
property var parentScreen: null
|
property var parentScreen: null
|
||||||
property int _desktopEntriesUpdateTrigger: 0
|
property int _desktopEntriesUpdateTrigger: 0
|
||||||
@@ -1845,5 +1846,27 @@ Item {
|
|||||||
if (useExtWorkspace && !DMSService.activeSubscriptions.includes("extworkspace")) {
|
if (useExtWorkspace && !DMSService.activeSubscriptions.includes("extworkspace")) {
|
||||||
DMSService.addSubscription("extworkspace");
|
DMSService.addSubscription("extworkspace");
|
||||||
}
|
}
|
||||||
|
_updateBlurRegistration();
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool _blurRegistered: false
|
||||||
|
readonly property bool _shouldBlur: BlurService.enabled && blurBarWindow && blurBarWindow.registerBlurWidget && !(barConfig?.noBackground ?? false) && root.visible && root.width > 0
|
||||||
|
|
||||||
|
on_ShouldBlurChanged: _updateBlurRegistration()
|
||||||
|
|
||||||
|
function _updateBlurRegistration() {
|
||||||
|
if (_shouldBlur && !_blurRegistered) {
|
||||||
|
blurBarWindow.registerBlurWidget(visualBackground);
|
||||||
|
_blurRegistered = true;
|
||||||
|
} else if (!_shouldBlur && _blurRegistered) {
|
||||||
|
if (blurBarWindow && blurBarWindow.unregisterBlurWidget)
|
||||||
|
blurBarWindow.unregisterBlurWidget(visualBackground);
|
||||||
|
_blurRegistered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onDestruction: {
|
||||||
|
if (_blurRegistered && blurBarWindow && blurBarWindow.unregisterBlurWidget)
|
||||||
|
blurBarWindow.unregisterBlurWidget(visualBackground);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,15 @@ Variants {
|
|||||||
delegate: PanelWindow {
|
delegate: PanelWindow {
|
||||||
id: dock
|
id: dock
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: dock
|
||||||
|
blurX: dockBackground.x + dockContainer.x + dockMouseArea.x + dockCore.x + dockSlide.x
|
||||||
|
blurY: dockBackground.y + dockContainer.y + dockMouseArea.y + dockCore.y + dockSlide.y
|
||||||
|
blurWidth: dock.hasApps && dock.reveal ? dockBackground.width : 0
|
||||||
|
blurHeight: dock.hasApps && dock.reveal ? dockBackground.height : 0
|
||||||
|
blurRadius: Theme.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
WlrLayershell.namespace: "dms:dock"
|
WlrLayershell.namespace: "dms:dock"
|
||||||
|
|
||||||
readonly property bool isVertical: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right
|
readonly property bool isVertical: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right
|
||||||
@@ -562,6 +571,15 @@ Variants {
|
|||||||
color: Theme.withAlpha(Theme.surfaceContainer, backgroundTransparency)
|
color: Theme.withAlpha(Theme.surfaceContainer, backgroundTransparency)
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "transparent"
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
border.color: BlurService.borderColor
|
||||||
|
border.width: BlurService.borderWidth
|
||||||
|
z: 100
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape {
|
Shape {
|
||||||
|
|||||||
@@ -9,6 +9,15 @@ import qs.Widgets
|
|||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: root
|
||||||
|
blurX: menuContainer.x
|
||||||
|
blurY: menuContainer.y
|
||||||
|
blurWidth: root.visible ? menuContainer.width : 0
|
||||||
|
blurHeight: root.visible ? menuContainer.height : 0
|
||||||
|
blurRadius: Theme.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
WlrLayershell.namespace: "dms:dock-context-menu"
|
WlrLayershell.namespace: "dms:dock-context-menu"
|
||||||
|
|
||||||
property var appData: null
|
property var appData: null
|
||||||
@@ -168,8 +177,8 @@ PanelWindow {
|
|||||||
height: menuColumn.implicitHeight + Theme.spacingS * 2
|
height: menuColumn.implicitHeight + Theme.spacingS * 2
|
||||||
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: BlurService.enabled ? BlurService.borderColor : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: BlurService.enabled ? BlurService.borderWidth : 1
|
||||||
|
|
||||||
opacity: root.visible ? 1 : 0
|
opacity: root.visible ? 1 : 0
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Effects
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Services.Notifications
|
import Quickshell.Services.Notifications
|
||||||
@@ -11,6 +10,15 @@ import qs.Widgets
|
|||||||
PanelWindow {
|
PanelWindow {
|
||||||
id: win
|
id: win
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: win
|
||||||
|
blurX: content.x + content.cardInset + swipeTx.x + tx.x
|
||||||
|
blurY: content.y + content.cardInset + swipeTx.y + tx.y
|
||||||
|
blurWidth: !win._finalized ? Math.max(0, content.width - content.cardInset * 2) : 0
|
||||||
|
blurHeight: !win._finalized ? Math.max(0, content.height - content.cardInset * 2) : 0
|
||||||
|
blurRadius: Theme.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
WlrLayershell.namespace: "dms:notification-popup"
|
WlrLayershell.namespace: "dms:notification-popup"
|
||||||
|
|
||||||
required property var notificationData
|
required property var notificationData
|
||||||
@@ -436,6 +444,16 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: content.cardInset
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: "transparent"
|
||||||
|
border.color: BlurService.borderColor
|
||||||
|
border.width: BlurService.borderWidth
|
||||||
|
z: 100
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: backgroundContainer
|
id: backgroundContainer
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Item {
|
|||||||
property real barThickness: 48
|
property real barThickness: 48
|
||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
|
property var blurBarWindow: null
|
||||||
property alias content: contentLoader.sourceComponent
|
property alias content: contentLoader.sourceComponent
|
||||||
property bool isVerticalOrientation: axis?.isVertical ?? false
|
property bool isVerticalOrientation: axis?.isVertical ?? false
|
||||||
property bool isFirst: false
|
property bool isFirst: false
|
||||||
@@ -106,7 +107,7 @@ Item {
|
|||||||
const rawTransparency = (root.barConfig && root.barConfig.widgetTransparency !== undefined) ? root.barConfig.widgetTransparency : 1.0;
|
const rawTransparency = (root.barConfig && root.barConfig.widgetTransparency !== undefined) ? root.barConfig.widgetTransparency : 1.0;
|
||||||
const isHovered = root.enableBackgroundHover && (mouseArea.containsMouse || (root.isHovered || false));
|
const isHovered = root.enableBackgroundHover && (mouseArea.containsMouse || (root.isHovered || false));
|
||||||
const transparency = isHovered ? Math.max(0.3, rawTransparency) : rawTransparency;
|
const transparency = isHovered ? Math.max(0.3, rawTransparency) : rawTransparency;
|
||||||
const baseColor = isHovered ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
const baseColor = isHovered ? BlurService.hoverColor(Theme.widgetBaseHoverColor) : Theme.widgetBaseBackgroundColor;
|
||||||
|
|
||||||
if (Theme.widgetBackgroundHasAlpha) {
|
if (Theme.widgetBackgroundHasAlpha) {
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * transparency);
|
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * transparency);
|
||||||
@@ -169,4 +170,26 @@ Item {
|
|||||||
root.wheel(wheelEvent);
|
root.wheel(wheelEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property bool _blurRegistered: false
|
||||||
|
readonly property bool _shouldBlur: BlurService.enabled && blurBarWindow && blurBarWindow.registerBlurWidget && !(barConfig?.noBackground ?? false) && root.visible && root.width > 0
|
||||||
|
|
||||||
|
on_ShouldBlurChanged: _updateBlurRegistration()
|
||||||
|
|
||||||
|
function _updateBlurRegistration() {
|
||||||
|
if (_shouldBlur && !_blurRegistered) {
|
||||||
|
blurBarWindow.registerBlurWidget(visualContent);
|
||||||
|
_blurRegistered = true;
|
||||||
|
} else if (!_shouldBlur && _blurRegistered) {
|
||||||
|
if (blurBarWindow && blurBarWindow.unregisterBlurWidget)
|
||||||
|
blurBarWindow.unregisterBlurWidget(visualContent);
|
||||||
|
_blurRegistered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: _updateBlurRegistration()
|
||||||
|
Component.onDestruction: {
|
||||||
|
if (_blurRegistered && blurBarWindow && blurBarWindow.unregisterBlurWidget)
|
||||||
|
blurBarWindow.unregisterBlurWidget(visualContent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Item {
|
|||||||
property real barThickness: 48
|
property real barThickness: 48
|
||||||
property real barSpacing: 4
|
property real barSpacing: 4
|
||||||
property var barConfig: null
|
property var barConfig: null
|
||||||
|
property var blurBarWindow: null
|
||||||
property string pluginId: ""
|
property string pluginId: ""
|
||||||
property var pluginService: null
|
property var pluginService: null
|
||||||
|
|
||||||
@@ -182,6 +183,7 @@ Item {
|
|||||||
barThickness: root.barThickness
|
barThickness: root.barThickness
|
||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
|
blurBarWindow: root.blurBarWindow
|
||||||
content: root.horizontalBarPill
|
content: root.horizontalBarPill
|
||||||
|
|
||||||
states: State {
|
states: State {
|
||||||
@@ -241,6 +243,7 @@ Item {
|
|||||||
barThickness: root.barThickness
|
barThickness: root.barThickness
|
||||||
barSpacing: root.barSpacing
|
barSpacing: root.barSpacing
|
||||||
barConfig: root.barConfig
|
barConfig: root.barConfig
|
||||||
|
blurBarWindow: root.blurBarWindow
|
||||||
content: root.verticalBarPill
|
content: root.verticalBarPill
|
||||||
isVerticalOrientation: true
|
isVerticalOrientation: true
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import QtQuick
|
|||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Popup {
|
Popup {
|
||||||
@@ -186,8 +187,8 @@ Popup {
|
|||||||
contentItem: Rectangle {
|
contentItem: Rectangle {
|
||||||
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: BlurService.enabled ? BlurService.borderColor : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 1
|
border.width: BlurService.enabled ? BlurService.borderWidth : 1
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: keyboardHandler
|
id: keyboardHandler
|
||||||
|
|||||||
@@ -125,6 +125,15 @@ Item {
|
|||||||
return Theme.warning;
|
return Theme.warning;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openBlurBorderColorPicker() {
|
||||||
|
PopoutService.colorPickerModal.selectedColor = SettingsData.blurBorderCustomColor ?? "#ffffff";
|
||||||
|
PopoutService.colorPickerModal.pickerTitle = I18n.tr("Blur Border Color");
|
||||||
|
PopoutService.colorPickerModal.onColorSelectedCallback = function (color) {
|
||||||
|
SettingsData.set("blurBorderCustomColor", color.toString());
|
||||||
|
};
|
||||||
|
PopoutService.colorPickerModal.open();
|
||||||
|
}
|
||||||
|
|
||||||
function openM3ShadowColorPicker() {
|
function openM3ShadowColorPicker() {
|
||||||
PopoutService.colorPickerModal.selectedColor = SettingsData.m3ElevationCustomColor ?? "#000000";
|
PopoutService.colorPickerModal.selectedColor = SettingsData.m3ElevationCustomColor ?? "#000000";
|
||||||
PopoutService.colorPickerModal.pickerTitle = I18n.tr("Shadow Color");
|
PopoutService.colorPickerModal.pickerTitle = I18n.tr("Shadow Color");
|
||||||
@@ -1816,6 +1825,77 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsCard {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "background", "transparency", "glass", "frosted"]
|
||||||
|
title: I18n.tr("Background Blur")
|
||||||
|
settingKey: "blurEnabled"
|
||||||
|
iconName: "blur_on"
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "background", "transparency", "glass", "frosted"]
|
||||||
|
settingKey: "blurEnabled"
|
||||||
|
text: I18n.tr("Background Blur")
|
||||||
|
description: BlurService.available ? I18n.tr("Blur the background behind bars, popouts, modals, and notifications. Requires compositor support and configuration.") : I18n.tr("Requires a newer version of Quickshell")
|
||||||
|
checked: SettingsData.blurEnabled ?? false
|
||||||
|
enabled: BlurService.available
|
||||||
|
onToggled: checked => SettingsData.set("blurEnabled", checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsDropdownRow {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "border", "outline", "edge"]
|
||||||
|
settingKey: "blurBorderColor"
|
||||||
|
text: I18n.tr("Blur Border Color")
|
||||||
|
description: I18n.tr("Border color around blurred surfaces")
|
||||||
|
visible: SettingsData.blurEnabled
|
||||||
|
options: [I18n.tr("Outline", "blur border color"), I18n.tr("Primary", "blur border color"), I18n.tr("Secondary", "blur border color"), I18n.tr("Text Color", "blur border color"), I18n.tr("Custom", "blur border color")]
|
||||||
|
currentValue: {
|
||||||
|
switch (SettingsData.blurBorderColor) {
|
||||||
|
case "primary":
|
||||||
|
return I18n.tr("Primary", "blur border color");
|
||||||
|
case "secondary":
|
||||||
|
return I18n.tr("Secondary", "blur border color");
|
||||||
|
case "surfaceText":
|
||||||
|
return I18n.tr("Text Color", "blur border color");
|
||||||
|
case "custom":
|
||||||
|
return I18n.tr("Custom", "blur border color");
|
||||||
|
default:
|
||||||
|
return I18n.tr("Outline", "blur border color");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onValueChanged: value => {
|
||||||
|
if (value === I18n.tr("Primary", "blur border color")) {
|
||||||
|
SettingsData.set("blurBorderColor", "primary");
|
||||||
|
} else if (value === I18n.tr("Secondary", "blur border color")) {
|
||||||
|
SettingsData.set("blurBorderColor", "secondary");
|
||||||
|
} else if (value === I18n.tr("Text Color", "blur border color")) {
|
||||||
|
SettingsData.set("blurBorderColor", "surfaceText");
|
||||||
|
} else if (value === I18n.tr("Custom", "blur border color")) {
|
||||||
|
SettingsData.set("blurBorderColor", "custom");
|
||||||
|
openBlurBorderColorPicker();
|
||||||
|
} else {
|
||||||
|
SettingsData.set("blurBorderColor", "outline");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsSliderRow {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["blur", "border", "opacity"]
|
||||||
|
settingKey: "blurBorderOpacity"
|
||||||
|
text: I18n.tr("Blur Border Opacity")
|
||||||
|
visible: SettingsData.blurEnabled
|
||||||
|
value: Math.round((SettingsData.blurBorderOpacity ?? 1.0) * 100)
|
||||||
|
minimum: 0
|
||||||
|
maximum: 100
|
||||||
|
unit: "%"
|
||||||
|
defaultValue: 100
|
||||||
|
onSliderValueChanged: newValue => SettingsData.set("blurBorderOpacity", newValue / 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
tab: "theme"
|
tab: "theme"
|
||||||
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
||||||
@@ -2602,7 +2682,6 @@ Item {
|
|||||||
onToggled: checked => SettingsData.set("matugenTemplateNeovim", checked)
|
onToggled: checked => SettingsData.set("matugenTemplateNeovim", checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SettingsDropdownRow {
|
SettingsDropdownRow {
|
||||||
text: I18n.tr("Dark mode base")
|
text: I18n.tr("Dark mode base")
|
||||||
tab: "theme"
|
tab: "theme"
|
||||||
|
|||||||
88
quickshell/Services/BlurService.qml
Normal file
88
quickshell/Services/BlurService.qml
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
pragma Singleton
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland // ! Import is needed despite what qmlls says
|
||||||
|
import qs.Common
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool available: false
|
||||||
|
readonly property bool enabled: available && (SettingsData.blurEnabled ?? false)
|
||||||
|
|
||||||
|
readonly property color borderColor: {
|
||||||
|
if (!enabled)
|
||||||
|
return "transparent";
|
||||||
|
const opacity = SettingsData.blurBorderOpacity ?? 0.5;
|
||||||
|
switch (SettingsData.blurBorderColor ?? "outline") {
|
||||||
|
case "primary":
|
||||||
|
return Theme.withAlpha(Theme.primary, opacity);
|
||||||
|
case "secondary":
|
||||||
|
return Theme.withAlpha(Theme.secondary, opacity);
|
||||||
|
case "surfaceText":
|
||||||
|
return Theme.withAlpha(Theme.surfaceText, opacity);
|
||||||
|
case "custom":
|
||||||
|
return Theme.withAlpha(SettingsData.blurBorderCustomColor ?? "#ffffff", opacity);
|
||||||
|
default:
|
||||||
|
return Theme.withAlpha(Theme.outline, opacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readonly property int borderWidth: enabled ? 1 : 0
|
||||||
|
|
||||||
|
function hoverColor(baseColor, hoverAlpha) {
|
||||||
|
if (!enabled)
|
||||||
|
return baseColor;
|
||||||
|
return Theme.withAlpha(baseColor, hoverAlpha ?? 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createBlurRegion(targetWindow) {
|
||||||
|
if (!available)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const region = Qt.createQmlObject(`
|
||||||
|
import Quickshell
|
||||||
|
Region {}
|
||||||
|
`, targetWindow, "BlurRegion");
|
||||||
|
targetWindow.BackgroundEffect.blurRegion = region;
|
||||||
|
return region;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("BlurService: Failed to create blur region:", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reapplyBlurRegion(targetWindow, region) {
|
||||||
|
if (!region || !available)
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
targetWindow.BackgroundEffect.blurRegion = region;
|
||||||
|
region.changed();
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroyBlurRegion(targetWindow, region) {
|
||||||
|
if (!region)
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
targetWindow.BackgroundEffect.blurRegion = null;
|
||||||
|
} catch (e) {}
|
||||||
|
region.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
try {
|
||||||
|
const test = Qt.createQmlObject(`
|
||||||
|
import Quickshell
|
||||||
|
Region { radius: 0 }
|
||||||
|
`, root, "BlurAvailabilityTest");
|
||||||
|
test.destroy();
|
||||||
|
available = true;
|
||||||
|
console.info("BlurService: Initialized with blur support");
|
||||||
|
} catch (e) {
|
||||||
|
console.info("BlurService: BackgroundEffect not available - blur disabled. Requires a newer version of Quickshell.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -107,6 +107,16 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
WlrLayershell.exclusiveZone: -1
|
WlrLayershell.exclusiveZone: -1
|
||||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
targetWindow: root
|
||||||
|
blurX: shadowBuffer
|
||||||
|
blurY: shadowBuffer
|
||||||
|
blurWidth: shouldBeVisible ? alignedWidth : 0
|
||||||
|
blurHeight: shouldBeVisible ? alignedHeight : 0
|
||||||
|
blurRadius: Theme.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
readonly property real dpr: CompositorService.getScreenScale(screen)
|
readonly property real dpr: CompositorService.getScreenScale(screen)
|
||||||
@@ -263,8 +273,8 @@ PanelWindow {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.withAlpha(Theme.surfaceContainer, osdContainer.popupSurfaceAlpha)
|
color: Theme.withAlpha(Theme.surfaceContainer, osdContainer.popupSurfaceAlpha)
|
||||||
border.color: Theme.outlineMedium
|
border.color: BlurService.enabled ? BlurService.borderColor : Theme.outlineMedium
|
||||||
border.width: 1
|
border.width: BlurService.enabled ? BlurService.borderWidth : 1
|
||||||
z: -1
|
z: -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -398,6 +398,17 @@ Item {
|
|||||||
visible: false
|
visible: false
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
WindowBlur {
|
||||||
|
id: popoutBlur
|
||||||
|
targetWindow: contentWindow
|
||||||
|
readonly property real s: Math.min(1, contentContainer.scaleValue)
|
||||||
|
blurX: contentContainer.x + contentContainer.width * (1 - s) * 0.5 + Theme.snap(contentContainer.animX, root.dpr)
|
||||||
|
blurY: contentContainer.y + contentContainer.height * (1 - s) * 0.5 + Theme.snap(contentContainer.animY, root.dpr)
|
||||||
|
blurWidth: (shouldBeVisible && contentWrapper.opacity > 0) ? contentContainer.width * s : 0
|
||||||
|
blurHeight: (shouldBeVisible && contentWrapper.opacity > 0) ? contentContainer.height * s : 0
|
||||||
|
blurRadius: Theme.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
WlrLayershell.namespace: root.layerNamespace
|
WlrLayershell.namespace: root.layerNamespace
|
||||||
WlrLayershell.layer: {
|
WlrLayershell.layer: {
|
||||||
switch (Quickshell.env("DMS_POPOUT_LAYER")) {
|
switch (Quickshell.env("DMS_POPOUT_LAYER")) {
|
||||||
@@ -569,8 +580,8 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||||
border.color: Theme.outlineMedium
|
border.color: BlurService.enabled ? BlurService.borderColor : Theme.outlineMedium
|
||||||
border.width: 0
|
border.width: BlurService.borderWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
|||||||
65
quickshell/Widgets/WindowBlur.qml
Normal file
65
quickshell/Widgets/WindowBlur.qml
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Services
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
required property var targetWindow
|
||||||
|
property var blurItem: null
|
||||||
|
property real blurX: 0
|
||||||
|
property real blurY: 0
|
||||||
|
property real blurWidth: 0
|
||||||
|
property real blurHeight: 0
|
||||||
|
property real blurRadius: 0
|
||||||
|
|
||||||
|
property var _region: null
|
||||||
|
|
||||||
|
function _apply() {
|
||||||
|
if (!BlurService.enabled || !targetWindow) {
|
||||||
|
_cleanup();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_region)
|
||||||
|
_region = BlurService.createBlurRegion(targetWindow);
|
||||||
|
|
||||||
|
if (!_region)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_region.item = Qt.binding(() => root.blurItem);
|
||||||
|
_region.x = Qt.binding(() => root.blurX);
|
||||||
|
_region.y = Qt.binding(() => root.blurY);
|
||||||
|
_region.width = Qt.binding(() => root.blurWidth);
|
||||||
|
_region.height = Qt.binding(() => root.blurHeight);
|
||||||
|
_region.radius = Qt.binding(() => root.blurRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _cleanup() {
|
||||||
|
if (!_region)
|
||||||
|
return;
|
||||||
|
BlurService.destroyBlurRegion(targetWindow, _region);
|
||||||
|
_region = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: BlurService
|
||||||
|
function onEnabledChanged() {
|
||||||
|
root._apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.targetWindow
|
||||||
|
function onVisibleChanged() {
|
||||||
|
if (root.targetWindow && root.targetWindow.visible) {
|
||||||
|
root._region = null;
|
||||||
|
root._apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: _apply()
|
||||||
|
Component.onDestruction: _cleanup()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user