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
@@ -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
|
||||
|
||||
Reference in new issue
Block a user