Keep overlay surfaces mapped so they open sharp (#13419)
The menu, emoji picker, clipboard, OSD, reminder flow and Wi-Fi QR code mapped a fresh surface on every open. Qt drew its first frames before Hyprland sent the surface's fractional scale: the pixel ratio stepped 2, 1, then 1.6, so on a 1.6 display each overlay showed blurry for ~350ms before going sharp. A new OverlayWindow keeps the surface. Hidden, it parks as a 1x1, input-less layer below windows, off the overlay layer so it never blocks direct scanout. Showing only resizes and raises it, so the scale is already settled. Content stays hidden until the surface has grown, so no 1x1 frame is stretched across the screen, and the window follows the focused monitor each time it is shown. The image picker's own fullscreen parking moves onto it too. Each parked overlay keeps a Qt window alive: at rest the shell holds ~40 MiB more RSS and ~20 MiB more GPU memory. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6762769bbf
commit
48de7823da
14 files changed
+164
-96
No files matched your search
@@ -311,15 +311,10 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
OverlayWindow {
|
||||
id: panel
|
||||
visible: root.opened
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
shown: root.opened
|
||||
WlrLayershell.namespace: "omarchy-clipboard"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -157,15 +157,10 @@ Item {
|
||||
path: root.omarchyPath + "/shell/plugins/emojis/emojis.json"
|
||||
onLoaded: root.loadEmojis(text())
|
||||
}
|
||||
PanelWindow {
|
||||
OverlayWindow {
|
||||
id: panel
|
||||
visible: root.opened
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
shown: root.opened
|
||||
WlrLayershell.namespace: "omarchy-emojis"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Shapes
|
||||
import qs.Commons
|
||||
import qs.Ui
|
||||
import "ImagePickerModel.js" as ImagePickerModel
|
||||
|
||||
Item {
|
||||
@@ -36,9 +36,6 @@ Item {
|
||||
property string themeRows: ""
|
||||
property bool themeMode: false
|
||||
property bool themeOpenPending: false
|
||||
// The surface outlives each open, so it no longer lands on the focused
|
||||
// output by itself. Unset until the first open lets the compositor choose.
|
||||
property var targetScreen: null
|
||||
// Bound to the central [image-picker] section in shell.toml via Color.qml.
|
||||
// `dimColor` tints unselected slices and text outlines on top of the scrim;
|
||||
// it intentionally tracks the foundational background, not a surface role.
|
||||
@@ -234,7 +231,6 @@ Item {
|
||||
requestSerial += 1
|
||||
themeMode = false
|
||||
themeOpenPending = false
|
||||
targetScreen = focusedScreen() || targetScreen
|
||||
|
||||
imageDirs = nextImageDirs
|
||||
imageRows = nextImageRows
|
||||
@@ -278,14 +274,6 @@ Item {
|
||||
|
||||
property var imageArray: []
|
||||
|
||||
function focusedScreen() {
|
||||
var monitor = Hyprland.focusedMonitor
|
||||
var name = monitor ? String(monitor.name || "") : ""
|
||||
for (var i = 0; i < Quickshell.screens.length; i++) {
|
||||
if (Quickshell.screens[i].name === name) return Quickshell.screens[i]
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function currentThemePreview() {
|
||||
var name = String(themeNameFile.text() || "").trim()
|
||||
@@ -456,25 +444,11 @@ Item {
|
||||
onExited: root.releaseNextDoneFile()
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
OverlayWindow {
|
||||
id: panel
|
||||
|
||||
// Stay mapped between opens. A fresh surface renders its first frames
|
||||
// before the compositor sends its fractional scale, so the picker flashed
|
||||
// blurry, and it had to re-upload every thumbnail texture. Closed, it
|
||||
// waits transparent and input-less on the bottom layer: anything left on
|
||||
// the overlay layer would block direct scanout for fullscreen apps.
|
||||
visible: true
|
||||
screen: root.targetScreen
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
mask: root.opened ? null : closedMask
|
||||
shown: root.opened
|
||||
shownKeyboardFocus: root.imagesLoaded ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||
WlrLayershell.namespace: "omarchy-image-selector"
|
||||
WlrLayershell.layer: root.opened ? WlrLayer.Overlay : WlrLayer.Bottom
|
||||
WlrLayershell.keyboardFocus: root.opened && root.imagesLoaded ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
Region { id: closedMask }
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -1065,15 +1065,10 @@ Item {
|
||||
if (root.guardsPending) Qt.callLater(function() { root.evaluateGuards() })
|
||||
}
|
||||
}
|
||||
PanelWindow {
|
||||
OverlayWindow {
|
||||
id: panel
|
||||
visible: root.opened && root.rowsLoaded
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
shown: root.opened && root.rowsLoaded
|
||||
WlrLayershell.namespace: "omarchy-menu"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
// The card opens centered exactly as always. The first search keystroke
|
||||
// or submenu move freezes the top line where it currently sits — from
|
||||
@@ -1086,12 +1081,13 @@ Item {
|
||||
readonly property int centeredTop: Math.max(Style.gapsOut, Math.round((height - root.cardHeight) / 2))
|
||||
readonly property int effectiveCardTop: cardTop >= 0 ? cardTop : centeredTop
|
||||
function freezeCardTop() {
|
||||
if (visible && cardTop < 0) {
|
||||
if (shown && cardTop < 0) {
|
||||
cardTop = effectiveCardTop
|
||||
maxRowsHeight = root.visibleRowsHeight
|
||||
}
|
||||
}
|
||||
onVisibleChanged: if (!visible) { cardTop = -1; maxRowsHeight = -1 }
|
||||
// The surface stays mapped between opens, so closing is shown going false.
|
||||
onShownChanged: if (!shown) { cardTop = -1; maxRowsHeight = -1 }
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -123,15 +123,11 @@ Item {
|
||||
function ping(): string { return "ok" }
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
OverlayWindow {
|
||||
id: panel
|
||||
visible: root.opened
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
shown: root.opened
|
||||
shownKeyboardFocus: WlrKeyboardFocus.None
|
||||
WlrLayershell.namespace: "omarchy-osd"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
// Visual-only surface: keep the layer-shell input region empty so the OSD
|
||||
// never blocks clicks to the desktop below it.
|
||||
mask: Region {}
|
||||
|
||||
@@ -210,14 +210,9 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
visible: root.opened
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
OverlayWindow {
|
||||
shown: root.opened
|
||||
WlrLayershell.namespace: "omarchy-network-qr"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
|
||||
|
||||
// Deep scrim: the floating code needs the backdrop to carry the contrast
|
||||
// on any wallpaper.
|
||||
|
||||
@@ -92,15 +92,10 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
OverlayWindow {
|
||||
id: panel
|
||||
visible: root.opened
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
shown: root.opened
|
||||
WlrLayershell.namespace: "omarchy-reminders"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
||||
Reference in new issue
Block a user