238 Commits
Author SHA1 Message Date
bbedward 6eb9df87cf network: set routing preference only from settings
fixes #3068

stable-1.6: core part only, the settings and network popout changes are master-only

(cherry picked from commit 089dc98166)
2026-10-07 13:03:41 -04:00
Marcus Ramberg 8b34bbf71a fix: scope bluez dbus match to bluezService (#3573)
Ensure the watcher only seees bluez messages

(cherry picked from commit 05377e690a)
2026-10-07 12:58:50 -04:00
bbedward fd468a6b78 brightness: ddcutil-parity ddc probing, bounded rereads
fixes #3616

(cherry picked from commit 0b9d931ea3)
2026-10-07 12:58:37 -04:00
Pedro Jose Soto Rivera 7c04b61bcc network(networkd): treat bridge, bond, team and vlan links as wired (#3706)
* network(networkd): treat bridge, bond, team and vlan links as wired

When the IP configuration lives on a bridge or link aggregate, the
enslaved member NIC reports opState=enslaved and the aggregate itself
was dropped by isWired() because only Type=ether was accepted, so the
widget showed Disconnected. Accept the same link types NetworkManager
already handles (#1581).

Also treat lxdbr*/incusbr* as virtual so container bridges, now of a
wired type, are not picked as the uplink.

Fixes #3463

* network(networkd): only treat a bridge as wired if it has a physical member

Name prefixes can't cover every container/VM bridge (lxcbr0, waydroid0,
...). Check the bridge's members in /sys/class/net/<br>/brif instead and
only accept it as the uplink when at least one member is not virtual
(veth*, tap*, ...). This replaces the lxdbr*/incusbr* prefixes.

(cherry picked from commit f886789835)
2026-10-07 12:58:37 -04:00
Pedro Jose Soto Rivera bc4916a132 network(iwd): follow the Wi-Fi device when iwd recreates it (#3707)
When iwd restarts it recreates wlan0 under a new D-Bus path. Only the
Station interface was tracked on InterfacesAdded, so devicePath kept
pointing at the dead object: the PropertiesChanged match for the new
device was never registered, updateState() read Powered from the old
path, and SetWiFiEnabled() failed with "No matching method found".
WiFiEnabled stayed false after handleStationRemoved() until DMS was
restarted.

Handle the Device interface on InterfacesAdded/InterfacesRemoved: move
devicePath and its signal match to the new object and take Name and
Powered from the signal. Process every interface in an
InterfacesRemoved signal instead of stopping at the first match.

Refs #3495

(cherry picked from commit ff50b492b1)
2026-10-07 12:58:37 -04:00
Giacomo Di Clerico fde2181c3b tailscale: handle profile switches and bus updates reactively (#3427)
* tailscale: handle profile switches and bus updates reactively

* tailscale: address review feedback on test coverage and dead code

(cherry picked from commit 218f7f752f)
2026-09-15 16:46:47 -04:00
bbedward e73b9c3ce1 evdev: open input devices read-only
go-evdev default is O_RDWR but we dont need to open evdev devices RW

(cherry picked from commit 6e9a657132)
2026-09-15 16:46:47 -04:00
Huỳnh Thiện Lộc 76ed5d68fa fix(clipboard): preserve pinned state when editing entries (#3412)
* fix(clipboard): preserve pinned state when editing entries

* fix(clipboard): address PR review feedback on editEntry

* fix(clipboard): validate empty text and entry size in EditEntry

* fix(clipboard): gate saving entry on full text load completion

* fix(clipboard): add user feedback and error fallback for entry loading

* fix(clipboard): keep entry and gate save with error toast on load failure

* fix(clipboard): reject non-text edits and add translator contexts

* fix(clipboard): support alt text mime types in EditEntry and UI guards

* fix(clipboard): pre-fetch entry before opening editor and allow retry on load failure

(cherry picked from commit 4141089e63)
2026-09-15 16:46:47 -04:00
Zoey Bauer 4015f634c4 add support for shelly (#3367)
* add support for shelly

* fixed terminal failure

* updated to have it not allow adding ignore aur

* updated error strings

* Fixed label

port 1.6

(cherry picked from commit 8fe918ff24)
2026-09-08 15:50:35 +00:00
bbedward 166b82df1b network: reject weak hotspot passwords before handing them to NetworkManager
fixes #3318
port 1.6

(cherry picked from commit f402731ef2)
2026-09-05 16:21:54 +00:00
bbedward 75b8932b20 network: keep saved wifi profiles when NM fails with no-secrets
fixes #3313
port 1.6

(cherry picked from commit c0f775ae49)
2026-09-05 16:21:49 +00:00
bbedward c929a8952b screenshot: add instancelock on runtimedir/wayland-display to prevent
multiple instances from running

fixes #3293
port 1.6

(cherry picked from commit 7e18a68b82)
2026-09-04 17:04:14 +00:00
usoaraway0 f2114c1a01 brightness: retry initial ddc read (#3287)
port 1.6

(cherry picked from commit ec22e9e594)
2026-09-04 13:51:54 +00:00
Marlon Kranz 4693178345 feat(theme): add a selectable source color mode for wallpaper palettes (#3020)
* feat(theme): add a selectable source color mode for wallpaper palettes

DMS always seeds the palette from matugen's most dominant candidate
(--source-color-index 0, hardcoded at both call sites). When a large
muted region outvotes a smaller vivid one, a visibly warm wallpaper
produces a cold palette: one image here goes to #8ad0ee where the warm
subject is at hue 46.

Adds a Source Color setting with seven values. Dominant is the default
and is byte-identical to today. Colorful is computed in Go before
matugen runs: quantize the image (Wu for the starting clusters, then a
weighted k-means in Lab), score the result the way caelestia-cli does,
and hand matugen the resulting hex. Its scoring walks a chroma/tone bar
down from 20 until something clears it, which biases the pick toward a
colorful, well-lit color rather than whichever muted color covers the
most pixels. The remaining five map to matugen's --prefer.

- core/internal/matugen/sourcecolor.go: extraction, scoring, and the
  one helper both matugen call sites now share
- buildOnce resolves the seed once, before the StockColors branch, so
  the dry run and the real run cannot disagree about it
- extraction failure logs a warning and falls through to matugen's own
  extraction; it never fails a theme build
- --prefer arrived in matugen 4.1, so it is gated separately from the
  existing isV4 check; on 4.0.x those five modes degrade to the
  dominant color instead of aborting on an unknown argument
- --source-mode on generate and queue, plus sourceMode on the socket
  handler
- Source Color dropdown in Theme & Colors, defaulting to Dominant

Adds github.com/Nadim147c/material/v3 (Apache-2.0, no dependencies) for
HCT conversions, Wu quantization and the dislike analyzer. Its
QuantizeCelebi is not used: it returns after one unconverged iteration
and its Lab.DistanceSquared is a dot product rather than a distance, so
it collapses most of an image into a single cluster.

* fix(theme): address review feedback on source color mode

Two points from review on #3020.

The quantize comment pointed at a FOLLOWUPS file that does not exist in
this repository. Replaced the reference with the measurement it was
standing in for, so the claim is self-contained.

setMatugenSourceMode called Theme.generateSystemThemesFromCurrentTheme()
directly on top of the regenSystemThemes onChange hook that Spec.set
already dispatches. Both feed a 100ms debounce so it was one generation
either way, but the direct call was redundant and is gone.

* fix(theme): keep {{image}} resolvable in colorful mode

Colorful resolves the seed itself and calls matugen with a hex source, which
leaves matugen's {{image}} unset: the builtin pywalfox template and any user
template using the keyword render the literal string "Null".

Pass the wallpaper path alongside dank16 in --import-json-string, as suggested
in review, so those templates keep working unedited. The path is made absolute
to match what matugen renders for {{image}} in the other modes.

* fix(theme): cut translator terms on the source color dropdown

Per-mode descriptions were seven of the fifteen new terms this branch adds,
and five of them differed by a single adjective. Drop them: the dropdown row
already describes what the setting does, and the docs cover each mode.
2026-09-03 09:07:21 -04:00
bbedward 875d32176d wayland/gamma: expose contrasta and gamma settings
fixes #3255
2026-09-02 09:50:47 -04:00
bbedward 881cfd2fd3 core: bump dankgo 2026-09-01 20:59:03 -04:00
purian23 5bb6058751 feat(clipboard): add a copy-as-text action for entries with a text alternates
- 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
2026-09-01 19:33:23 -04:00
bbedward 99c5f96575 bluetooth: toggle power from the adapter's live state,
fixes #3242
2026-08-31 19:55:31 -04:00
Mario Mohar 887509548b fix(theme): take sun times from the local calendar day, not the UTC one (#3237)
* 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.
2026-08-31 13:26:39 -04:00
Mario Moharandbbedward 9eaaed3203 feat(clipboard): clear only the filtered entries (#3235)
* 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]>
2026-08-31 10:04:26 -04:00
bbedward c68b7e5333 clipboard: survive corrupted bbolt db
fixes #3232
2026-08-30 11:16:36 -04:00
bbedward b8cceb7b3a gamma: configurable transition duration for time-based night mode 2026-08-29 16:23:48 -04:00
bbedward e99813b07d network: classify AP security by the privacy bit
fixes #3218
2026-08-29 15:40:53 -04:00
08dde7f79a add: Cellular Network support (rebase of #2765) (#3096)
* feat: add cellular support

* fix(settings): resolve cellular tab index collision

* fix: address review feedback for cellular support

Bump the network API version, drop the deleted term freeze file,
regenerate the settings search index, and reuse existing translation
terms where they already cover the new cellular UI.

* fix: do not assign readonly userPreference when switching network type

Assigning SettingsData.networkPreference through the readonly alias
threw on click, so the Cellular segment in Control Center did nothing.

* fix: make Cellular selectable and the modem row clickable

The Control Center type switcher was bound only to preference, so
Cellular snapped back to Ethernet. The settings modem row highlighted
on hover but had no click handler. Show the modem as a connect target
when no APN profiles exist.

* fix: create a GSM profile when connecting cellular with none saved

Clicking Mobile broadband only activated an existing profile, so a
modem with no APN did nothing useful. Fall back to AddAndActivate
like ethernet connect.

* fix: address second round of cellular review feedback

- Guard cellularDevices map with devMutex via snapshot/by-iface/set/remove
  helpers, mirroring the existing ethernet and wifi accessors
- Regenerate mocks with mockery v3 instead of hand-editing mock_Backend.go
- Reuse refreshCellularState() in SetCellularEnabled, DisconnectCellular,
  DisconnectCellularDevice, ActivateCellularConnection and device removal
- Wrap retryErr rather than the first error when the auto-config retry fails
- Use Theme.surfaceTextSecondary/primaryHover/primaryHoverLight in the
  cellular-off state instead of hand-rolled Qt.rgba values
- Drop the duplicate "No devices found" label so it can no longer render
  twice with no modem and no saved config

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* fix: address remaining cellular review comments

- Toast "Failed to toggle cellular" instead of always "enable"
- Remove unused enableCellularRadio() wrappers
- Store Control Center network type as a value, not a list index

* fix: pass nmcli connection selector as separate argument

`nmcli con mod uuid:<UUID>` is not valid syntax -- nmcli expects the
selector keyword as its own argument, so every priority update failed
with "no such connection profile". Because practically every NM profile
has a UUID, this silently disabled autoconnect-priority and route-metric
updates for ethernet and WiFi as well as cellular.

Also fix the Cellular settings status text, which said "Connecting..."
for a flag that only tracks radio enable/disable, and add the seven
cellular terms that were missing from the translation catalogs.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* apply review comments

* fix lints

* update debug doc

* fix style inconsistencies

---------

Co-authored-by: Yechiel Worenklein <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
Co-authored-by: bbedward <[email protected]>
2026-08-29 15:37:36 -04:00
purian23 104bbebbc2 ipc: stop cups capability churn from re-dialing the subscribe socket
ref #3140
2026-08-29 00:46:50 -04:00
bbedward 9f136da2e1 network: disconnect wifi from the associated adapter
ref #1921

looks like the rest of 1921 is more or less addressed on master, just
fixed a dissconnect gap
2026-08-28 14:03:40 -04:00
bbedward 3604fc83a2 brightness/ddc: add an option to disable DDC probing 2026-08-28 10:17:26 -04:00
bbedward dca1bd3591 network: report wifi state from the associated adapter
fixes #2460
2026-08-27 10:37:57 -04:00
bbedward 35aa1329e8 network: treat link aggregates as ethernet in the status mapping
fixes #1581
2026-08-27 10:28:13 -04:00
bbedward ed60fb7e4f trayrecovery: rescan when the StatusNotifierWatcher changes hands
fixes #1142
2026-08-27 10:07:27 -04:00
bbedward 9ed4acd4f8 network: connect to OWE and OWE transition-mode networks
fixes #2458
2026-08-27 09:49:31 -04:00
haikalllp 42080db61b feat(theme): add support for matugen smart mode and type (#3109)
* feat(theme): add support for matugen smart mode and type

* add another dry run to get smart type preview

* fix too much keywords in search index

* revert dont extract translations

* feat gate "Auto From Wallpaper" toggle row and the available matugen scheme for the pallete drop down

* re-extract settings search index

* make portal sync no longer disables matugen smart mode

* make sure cosmic theme mode also follow change from smart mode

* add translator context for Auto (Light Mode) / Auto (Dark Mode) / Auto From Wallpaper

* fix: gate matugen smart mode checks on the dynamic theme so stock themes keep portal sync and fix tile labels in control center
2026-08-27 09:40:23 -04:00
2934188296 fix(suncalc): parenthesise the sunrise-equation denominator (up to 24 min error at high latitude) (#3192)
* fix(suncalc): parenthesise the sunrise-equation denominator

`sunHourAngle` computed

    cos(z) / cos(lat) * cos(dec) - tan(lat) * tan(dec)

but the sunrise equation is

    cos(H) = cos(z) / (cos(lat) * cos(dec)) - tan(lat) * tan(dec)

In Go `a / b * c` is `(a / b) * c`, so `cos(dec)` multiplied where it should divide.

The new test asserts a property rather than a formula: feeding the returned hour
angle back through the definition of the zenith angle,

    cos(z) = sin(lat)*sin(dec) + cos(lat)*cos(dec)*cos(H)

has to reproduce the zenith angle that was requested. It fails on the old expression
and passes on the corrected one, over a grid of latitudes from the equator to the
polar circle, declinations across a full year, and both zenith targets the callers
use (elevTwilight -6, elevDaylight 3).

Worst-case error before the fix, in clock time:

    Singapore    lat  1.35     285 s
    Mexico City  lat 19.43     312 s
    Cairo        lat 30.04     354 s
    New York     lat 40.71     439 s
    Trieste      lat 45.69     512 s
    London       lat 51.51     671 s
    Oslo         lat 59.91     654 s
    Tromso       lat 69.65    1443 s

The error grows with latitude and with |declination|, and is largest at the civil
twilight zenith — which is where the gamma ramp starts and ends.

It also moves the boundary at which Acos leaves its domain, i.e. where the code
decides midnight sun / polar night. Swept over 505062 (lat, dec, zenith) points, the
classification differs at 961 of them (0.190%), all beyond 88 degrees of latitude.

The existing suncalc tests keep passing: they assert sunrise and sunset to the hour,
which is two orders of magnitude coarser than this error.

* fix(suncalc): classify each solar threshold independently

---------

Co-authored-by: Mark2Mac <[email protected]>
Co-authored-by: bbedward <[email protected]>
2026-08-27 09:13:58 -04:00
bbedward fb96661092 fix(network): repair 802.1x credential persistence, add EAP method selection 2026-08-24 14:31:59 -04:00
Connor Welsh 26fb129887 fix(tailscale): back off when the IPN bus read fails (#3142) 2026-08-21 22:45:30 -04:00
bbedward 45cd00bed3 perf(dms): cut daemon idle RAM, threads, and goroutines. Add DMS_PPROF
for performance profiling
2026-08-21 20:24:36 -04:00
bbedward 6a0197d252 fix(accounts): stage profile icon through /tmp before SetIconFile
fixes #3130
2026-08-20 14:59:29 -04:00
bbedward 396d490979 feat(screenshot+colorpicker): support 10-bit colors via
wp_color_manager_v1

Also fix a bunch of unrelated go vet issues
2026-08-19 14:34:56 -04:00
Connor Welshandbbedward 101841585f fix(dgop): stop the process list opening blank (#3108)
* fix(dgop): merge child processes by default

* fix(dgop): show the process list on first open

parseData threw away the first processes payload and waited 1s for a
second, on the grounds that the first carries no CPU deltas. That holds
for the cpu module, whose prime stays, but the processes sample is
usable as it arrives, so the wait only left the list blank.

* fix(dgop): refetch when the module set changes mid-request

updateAllStats returned early while a request was in flight, and that
request was built from the modules as they stood when it went out.
Opening the process list during the bar's periodic poll got back a
response with no process data, then a full updateInterval of waiting.
Queue a refetch and reissue when the response lands.

* fix(dgop): clear pendingUpdate when no request is sent

* fix(dgop): prime the queued refetch so the cpu cursor spans an interval

* core: bump dgop version

---------

Co-authored-by: bbedward <[email protected]>
2026-08-19 12:03:41 -04:00
bbedward 070090c35a bluetooth: multi-adapter support 2026-08-16 11:36:32 -04:00
bbedward fb9f00a616 default apps: add mime-type options for file browser 2026-08-14 18:09:39 -04:00
bbedward 6481f61028 core: migrate to wayland client and wlclipboard from dankgo 2026-08-12 15:45:39 -04:00
bbedward da664565b1 dgop: drop dgop as an external dependency and use dgop/gops internally
fixes #3033
2026-08-10 18:29:59 -04:00
bbedward a713485599 fix(geolocation): fetch IP location lazily so startup never contacts ip-api.com
fixes #3008
port 1.5
2026-08-07 19:54:21 -04:00
David Mirelesandbbedward 3f6cd0b579 feat(registry): support multiple plugin and theme registries via env vars (#2972)
feat(registry): support multiple plugin/theme registries

closes #2763

---------

Co-authored-by: bbedward <[email protected]>
2026-08-06 22:43:44 -04:00
FormalSnake adcafbcc8e location: add missing subscribe fan-out for location events (#2914)
handleSubscribe forwards every service except location, so neither
subscribe-all connections nor explicit location subscriptions ever
receive location events, and the shell's only source of coordinates
is a single getState pull that races the geoclue TimeThreshold and
loses. Wire location into the fan-out like loginctl/sysupdate:
initial state on subscribe, then manager pushes.
2026-08-05 19:28:33 -04:00
bbedward 0c811e3417 gamma: validate config before write and publish state every scheduler
wakeup

fixes #2967
port 1.5
2026-08-05 16:55:34 -04:00
bbedward dc8a47644a evdev: resolve capslock state from any available keyboard
fixes #2991
port 1.5
2026-08-03 19:59:12 -04:00
01832856d4 fix(network): authenticate Fortinet VPNs natively (#2959)
* fix(network): authenticate Fortinet VPNs natively

* cleanup and add test

---------

Co-authored-by: Grant Mosha <[email protected]>
Co-authored-by: bbedward <[email protected]>
2026-07-30 16:45:53 -04:00
Huỳnh Thiện Lộcandbbedward 0033e3f0e0 feat: add QR Generator launcher (#2941)
* feat: add QR Generator modal with auto-generate on input debounce

- QRGeneratorModal with dual-buffer sequential fade animation
- Auto-generate QR code on typing stop (200ms debounce)
- Clear text button on input field
- Escape key closes modal
- Register modal in PopoutService and AppSearchService
- Go backend for text QR code generation

* fix: add QR Generator toggle to Launcher DMS settings

* qr: also add qrg built in launcher plugin

---------

Co-authored-by: bbedward <[email protected]>
2026-07-30 16:33:36 -04:00