From fcddc2c2bf6ad0b84fc430694b7644bb84d04aae Mon Sep 17 00:00:00 2001 From: Neil Chudleigh <5580824+nchudleigh@users.noreply.github.com> Date: Tue, 3 Nov 2026 12:15:57 -0500 Subject: [PATCH 1/3] Render the Omarchy logo in the search bar sharply At 1.5x scale the logo glyph rendered 27 device pixels wide, off the 15 px grid it is drawn on, so its 1 px strokes straddled pixels and blurred. Snap its size to the nearest multiple of 15 device pixels (window.devicePixelRatio, since Screen.devicePixelRatio reports 1 in layer windows) and render it natively so FreeType hints the strokes onto that grid. Measured on a 1.5x monitor, half-tone pixels in the logo fell from 35% to 17%. Co-Authored-By: Claude Opus 5.5 --- ui/LauncherWindow.qml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ui/LauncherWindow.qml b/ui/LauncherWindow.qml index 618a8ad..cf90668 100644 --- a/ui/LauncherWindow.qml +++ b/ui/LauncherWindow.qml @@ -48,6 +48,14 @@ PanelWindow { } readonly property real zoom: window.general.uiZoom > 0 ? window.general.uiZoom : 1 function px(value) { return Math.round(Style.space(value) * window.zoom) } + // The Omarchy logo glyph is drawn on a 15 px grid: at other sizes its thin + // strokes straddle device pixels and blur (27 px at 1.5x scale). Snap the + // size to the nearest multiple of 15 device pixels; the glyph also renders + // natively so FreeType hints it onto that grid. + function crispLogoSize(size) { + var ratio = window.devicePixelRatio || 1 + return Math.round(Math.max(1, Math.round(size * ratio / 15)) * 15 / ratio) + } readonly property var look: ({ background: Commons.Color.menu.background, @@ -704,7 +712,8 @@ PanelWindow { textFormat: Text.PlainText text: window.atRoot ? "" : "" font.family: window.atRoot ? "omarchy" : window.look.fontFamily - font.pixelSize: window.atRoot ? window.px(18) : window.px(15) + font.pixelSize: window.atRoot ? window.crispLogoSize(window.px(18)) : window.px(15) + renderType: Text.NativeRendering color: window.atRoot ? window.look.accent : window.look.foreground opacity: window.atRoot ? 1 : 0.7 } From a90270617f5fce4ac70526610e7299b15a9a8e20 Mon Sep 17 00:00:00 2001 From: Neil Chudleigh <5580824+nchudleigh@users.noreply.github.com> Date: Tue, 3 Nov 2026 12:30:14 -0500 Subject: [PATCH 2/3] Render the footer's Omarchy logo sharply too Same as the search bar logo: 11 px became 16.5 device pixels at 1.5x, off the glyph's 15 px grid. Snap it and hint it; toast icons keep their size. Co-Authored-By: Claude Opus 5.5 --- ui/LauncherWindow.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/LauncherWindow.qml b/ui/LauncherWindow.qml index cf90668..6f51e09 100644 --- a/ui/LauncherWindow.qml +++ b/ui/LauncherWindow.qml @@ -974,7 +974,8 @@ PanelWindow { textFormat: Text.PlainText text: window.toast ? (window.toast.style === "failure" ? "" : "") : "" font.family: window.toast ? window.look.fontFamily : "omarchy" - font.pixelSize: window.toast ? window.px(12) : window.px(11) + font.pixelSize: window.toast ? window.px(12) : window.crispLogoSize(window.px(11)) + renderType: window.toast ? Text.QtRendering : Text.NativeRendering color: window.toast && window.toast.style === "failure" ? "#e06c75" : window.look.accent } Text { From 0b3277d94319a65a16cb2af04b2b56e5a2430072 Mon Sep 17 00:00:00 2001 From: Neil Chudleigh <5580824+nchudleigh@users.noreply.github.com> Date: Tue, 3 Nov 2026 12:41:55 -0500 Subject: [PATCH 3/3] Hide the launcher's first frame until it has the output's scale Qt draws the first frame after the surface maps at scale 1, before the output's fractional scale arrives. That frame was shown stretched and soft, with scale-dependent sizes (the snapped logos) visibly jumping as the real scale landed. Hold the content transparent until the surface has the output's size and scale, as Omarchy's OverlayWindow does. Co-Authored-By: Claude Opus 5.5 --- ui/LauncherWindow.qml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/ui/LauncherWindow.qml b/ui/LauncherWindow.qml index 6f51e09..0933662 100644 --- a/ui/LauncherWindow.qml +++ b/ui/LauncherWindow.qml @@ -1,5 +1,6 @@ import QtQuick import Quickshell +import Quickshell.Hyprland import Quickshell.Wayland import qs.Commons import qs.Commons as Commons @@ -138,7 +139,37 @@ PanelWindow { Qt.callLater(function() { keyCatcher.forceActiveFocus() }) } + // Hold the content transparent until the surface has the output's size and + // scale, as Omarchy's OverlayWindow does. Qt draws the first frame after + // mapping at scale 1, which showed stretched and soft, with scale-dependent + // sizes jumping as the real scale landed. + readonly property var targetMonitor: { + var monitors = Hyprland.monitors.values + for (var i = 0; i < monitors.length; i++) { + if (window.screen && monitors[i].name === window.screen.name) return monitors[i] + } + return null + } + readonly property bool contentReady: window.shown && !!window.screen && !!window.targetMonitor + && window.width === window.screen.width && window.height === window.screen.height + && Math.round(window.devicePixelRatio * 120) === Math.round(window.targetMonitor.scale * 120) + property bool contentRevealed: false + onContentReadyChanged: { + window.contentRevealed = false + // Size and scale arrive while Qt is still updating the window; reveal once + // its layout has caught up. + if (window.contentReady) Qt.callLater(function() { if (window.contentReady) window.contentRevealed = true }) + } + // Live monitor scaling emits no Hyprland event, so refresh the cached scale. + onDevicePixelRatioChanged: if (window.shown) Hyprland.refreshMonitors() + Binding { + target: window.contentItem + property: "opacity" + value: window.contentRevealed ? 1 : 0 + } + onShownChanged: { + if (window.shown) Hyprland.refreshMonitors() if (window.shown) return window.searchSerial++ window.backend.cancelSearch()