Add a refresh action to the Network detail header that calls
NetworkService.scanWifi(), mirroring the existing button in the Settings
WiFi tab. The button is hidden while WiFi is toggling or a scan is in
progress, and sits left of the connection-type tabs so the tab group
does not shift when switching between Ethernet, WiFi and Cellular.
* fix(bar): prevent focused app widget from blanking and live-sync popout on focus switch
* fix(bar): use per-output is_active flag for Niri workspace resolution
* fix(bar): gate Niri lastFocusedWindowId fallback on active popout visibility
* fix(powermenu): close on escape key and deduplicate action shortcuts
- Centralize Escape key handling in PowerMenuContent via closeRequested signal,
cancelling any active hold and enabling Esc to close both modal and popout variants.
- Remove redundant Keys.onEscapePressed wrapper in PowerMenuPopout.
- Extract handleActionShortcut and handleKeyRelease helpers to eliminate ~50 lines
of duplicated action shortcut dispatch between list and grid navigation.
* fix(powermenu): drop duplicate Keys.onEscapePressed handler
- Remove redundant Keys.onEscapePressed in PowerMenuContent, keeping Escape
handling unified under Keys.onPressed to preserve isAutoRepeat and
committedAction guards.
* feat(screenshot): support 4-corner resizing while holding Ctrl
- Hit-test selection corners when Ctrl is held to allow resizing.
- Set opposite corner as fixed anchor and update dynamic cursor shape
(NwseResize/NeswResize).
- Draw corner handle indicators when Ctrl is held or during active resize.
- Add 'Ctrl resize/move' to overlay HUD and provide complete glyph
coverage for HUD labels.
- Add comprehensive unit tests covering hit testing, inverted dragging,
incremental handle damage, and glyph coverage.
* fix(screenshot): invalidate background cache on handle and shift modifier changes
- Track backgroundHandles and backgroundShift in RenderSlot.cacheValid.
- Rebuild background slot and HUD when handle or shift modifier states
change with an existing selection, preventing incremental re-dimming
from punching holes in the HUD.
- Fix trailing newline in region_resize_test.go for golangci-lint.
* fix(screenshot): gate redraw and handle dimming on render modifier changes
- Only trigger redrawSurface when Shift or Ctrl modifier states actually
change, preventing redundant redraws when tapping Alt, Super, or Locks.
- Only re-dim and damage corner handle bounding boxes in overlayDelta and
overlayDamage when handles move or their visibility changes, preventing
unnecessary re-dimming of stationary handles over the HUD.
- Add TestOverlayDeltaIdenticalOverlayNoHandleDimming test.
* fix(screenshot): measure hud text advance accurately to prevent pill overflow
- Use (1+len(item.desc))*(charW+1) when calculating totalW in drawHUD,
matching the full 9px advance used when drawing space and description.
- Add TestHUDDimensionsContainText to verify HUD pill dimensions enclose
all text items with correct padding across all variant combinations.
* fix(screenshot): compare handle rect sets in overlay delta and damage
- Use slices.Equal to compare prev and cur handleRects in overlayDelta
and overlayDamage instead of interior equality.
- Properly re-dim and damage handles when selection corners cross monitor
boundaries where clamped interior is unchanged but top/bottom/left/right
flags change.
- Add TestOverlayDeltaHandlesClampedMonitorEdge test.
* test(screenshot): verify drawHUD output buffer pixels stay within pill bounds
- Extract hudDimensions helper on RegionSelector used by drawHUD.
- Update TestHUDDimensionsContainText to drive drawHUD directly into a
zeroed buffer and assert no lit pixel falls outside the computed
HUD pill boundary across all configuration variants.
* fix(dock): fix solid mask regression and geometry distortion when switching orientation in frame mode
* fix(dock): fix running app indicator misalignment on orientation change
* fix(dock): center multi-window running indicators around app icon
* fix(dock): fix vertical hit area collapse and transient background flicker on position change
- User icon dirs now sort ahead of system ones so overrides in
~/.icons and ~/.local/share/icons
- Desktop entry changes
refresh that index and drop cached misses instead of clearing
everything
Closes#2360Closes#3246
- New Entries captured from a mixed image+text offer keep the image as the primary mime i.e. bitmap
- Copy Text context-menu item on atlernates
Closes#2849
* feat(dock): sync background and icons in frame overview
- Keep FrameDockHost pre-instantiated in FrameWindow when dockOpenOnOverview is enabled to eliminate QML Loader instantiation lag on overview toggle.
- Add overviewReveal property to DockBody and snap slide spring positions instantly on overview enter.
- Enforce showDock check in DockBody reveal property so dock stays hidden outside overview when showDock is disabled.
* fix(dock): handle fullscreen in overview and disable hover
- Evaluate overviewReveal before hiddenForFullscreen so dock can open in overview over fullscreen windows.
- Return false when showDock is disabled to prevent hover reveals outside overview.
* fix(doctor): validate QT_QPA_PLATFORMTHEME instead of trusting its presence
dms doctor reported any non-empty QT_QPA_PLATFORMTHEME as healthy, so a
wrong value passed with "All checks passed!" while every Qt app silently
ran without a platform theme: palettes stayed unstyled and QIcon lookups
returned nothing, which is how Quickshell ends up drawing its missing-
icon placeholder for every icon an SNI app such as blueman publishes in
tray menus. The real-world trap is qt6ct-kde — the AUR package name —
set as the theme value; the settings UI toast already documents that
only the qt6ct theme requires the qt6ct-kde package, but the doctor,
the tool meant to catch exactly this, blessed the broken value.
- checkQtPlatformThemePlugin validates both QT_QPA_PLATFORMTHEME and
QT_QPA_PLATFORMTHEME_QT6 (the latter was not reported at all):
qt6ct-kde gets a targeted warning naming the fix, and any other value
has its plugin probed the way the qtengine check does — qmake/qtpaths
are asked for QT_INSTALL_PLUGINS and the conventional file names are
looked up, warning with the exact expected path on a miss
- a miss never warns when it cannot be sure: no Qt build tools and the
version-dependent plasma-integration file name both degrade to info,
mirroring the qtengine check's no-false-alarm policy
- the plugin-root interrogation moves into qtPluginRoots, shared with
the qtengine check
On an affected system:
before: ○ QT_QPA_PLATFORMTHEME · qt6ct-kde
✓ All checks passed!
after: ○ QT_QPA_PLATFORMTHEME · qt6ct-kde
● qt6ct-kde Package name, not a theme
* fix(doctor): probe qtengine plugin with a bare file name
qtenginePluginFile("", major) returns a path with a directory
component, and qtPluginPath joins platformthemes/ again, so the
qtengine check stat'd
<root>/platformthemes/platformthemes/libqt6engine-plugin.so and warned
"Not found" on every correctly installed system. Pass the bare file
name instead, and pin the resolved path with a regression test that
fails on the double join.
Found in review by claude[bot].
* Update core/cmd/dms/commands_doctor.go
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
---------
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
* fix(theme): take sun times from the local calendar day, not the UTC one
CalculateSunTimesWithTwilight read its reference day off date.UTC(). The
event seconds it computes are local mean solar time and lonOffset converts
them to UTC, so the instant of a local day's sunrise lands on the previous
UTC day east of Greenwich and a local sunset on the next one west of it.
Whenever the local and UTC calendars disagree, the function therefore
returned a neighbouring day's times.
Everything around it already works in local calendar days: the polar
branches of CalculateSunTimes build their day from date.Year/Month/Day,
thememode's startOfNextDay uses next.Location(), and the gamma scheduler
keys its calcDay cache on now.Location(). Only the reference day inside
the calculation disagreed.
Effect at UTC+8 (Kunming, 25.04N 102.72E): between local sunrise and 08:00
local, computeLocationSchedule got yesterday's sunrise and sunset, both
already past, fell through to the next-day branch and got today's sunrise,
also past. It reported dark with nextTransition in the past, which
schedulerLoop clamps to a one-second wait, so it re-evaluated every second
until 08:00 local and then flipped to light on its own. West of UTC the
mirror image: at UTC-7 the mode went dark from 17:00 local, when the UTC
date rolls over, until the real sunset.
The same SunTimes drive the gamma/night-light scheduler, so night light
shifted by a day the same way.
Fix: derive the reference day from date's own calendar day, keeping
dayStart anchored at UTC midnight so the lonOffset arithmetic is
unchanged, and take the orbit angle from the same day. Callers whose date
is already in UTC are unaffected.
Tests: suncalc_refday_test.go covers the reference day east and west of
UTC, stability across UTC midnight, and that UTC callers do not move.
manager_location_test.go is new to the thememode package and covers
computeLocationSchedule at both offsets, including that nextTransition is
never in the past.
* fix(theme): pick the reference day from the solar day, not the civil one
Taking the reference day straight off the caller's calendar day is right
for nearly every zone, but not for one shifted a full day away from its
own meridian. Apia, Kiritimati, Tongatapu and the Chathams all sit on
west longitudes while keeping a UTC+12:45..+14 offset, so their mean
solar time and their civil time are a day apart. Every sun event landed
on the following local day there, and the location schedule reported
dark around the clock.
Anchor on the caller's local noon and convert that to mean solar time to
pick the reference day. For every other zone this resolves to the same
date as before, so Kunming, Los Angeles and London are unchanged to the
second. dateOrbitAngle now takes the same reference day, so declination
and the equation of time no longer belong to a different day than the
events computed from them.
Covered at both levels: three antimeridian zones in the suncalc test,
and two cases in the location schedule test for the symptom itself.
Both fail without this change.
In Hyprland a second bind on an already bound key does not replace the
first, both stay live, which is why an override is written as hl.unbind
followed by hl.bind. The parser dropped that pair on the floor when it
came from a user's own Lua module:
- parseLuaLines discarded the unbind whenever the same file rebound the
key, so the DMS default was never removed
- addBind then treated the rebind as a config bind conflicting with a DMS
bind, counted it in bindsAfterDMS and returned false, so it never
reached the section
The keybinds modal therefore showed the DMS default for that key and the
user's actual action was nowhere, which is what #3145 reports.
The discard existed to protect dms/binds-user.lua, the file the settings
modal writes, which uses the same unbind+bind pair: recording its unbind
would have deleted its own rebind too, since that file is also a DMS bind
source. The guard was just too coarse, suppressing the unbind entirely
instead of exempting the one bind it belongs to.
Now the unbind is always recorded, and rebindSources remembers which file
unbound and rebound a key so removeUnboundDMSBinds spares that file's own
bind. addBind treats a bind as an override, not a conflict, when the same
file unbound the key earlier — tracked per file in fileUnbinds, saved and
restored around each parsed file so an include cannot leak into its
parent.
A config bind without a preceding unbind is unchanged: both binds really
are live in Hyprland, so it stays a conflict and keeps counting towards
"Some DMS binds may be overridden by config binds".
No other provider has an unbind concept; mangowc, niri and sway parse
formats without one, so this is Hyprland-only.
Tests: hyprland_parser_override_test.go covers the reported case, the
conflict case without an unbind, a bare unbind with no rebind, and the
dms/binds-user.lua round trip. Only the first fails without the fix; the
other three pass either way and guard against over-correcting.
* feat(clipboard): clear only the filtered entries
With a search query or type filter active, the clear button deleted
every unpinned entry regardless of what the list was showing, so
pruning a subset meant deleting entries one by one from the context
menu.
When the recents list is filtered, the button now clears exactly the
entries it shows and the modal stays open on that filter; with no
filter the previous behaviour is untouched. A filter that matches
nothing does nothing at all, rather than falling back to clearing
everything. The tooltip says "Clear Filtered" while a filter is
active, and the confirmation names the count.
Deleting one id at a time would have cost a round trip and a full
state broadcast per entry, so this adds clipboard.deleteEntries: one
bolt transaction, one state update, and it skips pinned entries
server-side so a bulk delete can never take out saved items.
Fixes#3198
* fix(clipboard): add translator context and list deleteEntries in IPC help
Review follow-up.
The two strings this branch adds carried no translator context: the
"Clear Filtered" tooltip in ClipboardHeader and the confirmation body for
a filtered clear in ClipboardHistoryContent. Both now say where they
appear, and the second one names what %1 is, per CONTRIBUTING.
"Clear All" on the same line is deliberately left alone. It is an
existing shared term with four other call sites, so a context there would
attach a clipboard-specific comment to a term the printer tab also uses.
clipboard.deleteEntries was handled but absent from the IPC method
listing that `dms debug-srv` prints, which left it undiscoverable right
next to clipboard.deleteEntry.
Catalogs untouched.
* chore: re-trigger CI
The lint-and-test failure on 21cefbf is an unrelated flake:
TestStoreEntry_CorruptDBReturnsErrorNotPanic died with SIGBUS in the
bbolt mmap. That test comes from master (c68b7e5) and passes there;
this branch only adds TestDeleteEntries_*/TestHandleDeleteEntries_*
and touches manager.go additively.
* clipboard: survive mmap faults from corrupted db pages
---------
Co-authored-by: bbedward <[email protected]>