aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/island
AgeCommit message (Collapse)AuthorFilesLines
5 daysdesktop: Tab moves between the hand-rolled text fieldsDanilo M.1-0/+1
A bare TextInput defaults activeFocusOnTab to false, unlike the Controls TextField some pages use, so Tab skipped every field built from one: the settings search, Field, the qtmaildir, git, autostart, assistant, OBS, user, VM and network rows, and the calendar editor. Multi-line TextEdits stay out of the chain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysisland: headphones panel for Sony noise controlDanilo M.6-8/+804
A headphones icon in the status pill, shown while Sony headphones are connected, opens a panel in the capsule: battery, noise control tiles (ANC, ambient, off), ambient level, focus on voice, the headphones' own sink volume, power off and refresh. Battery and volume need nothing new: BlueZ's Battery1 already reports the charge, and volume is AVRCP through PipeWire, so the slider drives the headphones' bluez_output node rather than the default sink. Only the mode needs Sony's own protocol, which sonyctl speaks over RFCOMM with the Python standard library. The headphones advertise the v2 MDR service on channel 18 and answer an 8-byte init reply, which is the v2 shape. What was measured on a WH-CH720N, and differs from what reading Gadgetbridge alone suggested: the ambient subtype is 17, while 15 (what Gadgetbridge sends to models without wind-noise reduction) is acked and never answered; the set payload is 7 bytes, with no wind byte. Noise cancelling has no strength, only on or off; a level sent with it is ignored and the previous ambient level kept. Focus on voice reads back as set. A connect right after the previous run closed fails with EBUSY, so sonyctl retries it briefly. Each call is about 2s, so the panel runs one at a time and sends the ambient level only once the slider or wheel settles. The mode is re-read on every open because the headphones' own button changes it too. Power off was not exercised, to keep the headphones on during development. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5 daysName the project Keystone, and move its paths and namespacesDanilo M.4-6/+6
The repository had no name of its own, only the framework's. It is now Keystone, in the README, AGENTS.md, the settings window, notes commit messages, calctl's PRODID and the user page's User-Agent. Its files move off quickshell's name too: ~/.config/quickshell/greetings -> ~/.config/keystone/ ~/.config/quickshell/obs-scene-icons.json -> ~/.config/keystone/ $XDG_STATE_HOME/quickshell/desktop.json -> $XDG_STATE_HOME/keystone/ ~/.config/quickshell is Quickshell's own default config directory (a bare qs loads its shell.qml), so sharing it was a collision rather than a home. There is no fallback to the old paths: the files are moved once. The layer namespaces become keystone-*, and the Hyprland blur rules in hypr-theme are renamed to match in the same change. A running shell keeps its old namespaces until restarted. Left alone: the retired standalone mail and vm shells' namespaces, which their READMEs keep as history; Quickshell's own app id, binary and process name; and the repository directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 daysisland: open the window source's properties from the pillDanilo M.3-6/+30
A Wayland window capture is chosen in the portal picker, which only OBS's source dialog can open. In a scene whose only source is a PipeWire capture, the panel gets a Window button that opens that dialog. A window scene with more than one source needs a per-scene designation the pill does not have yet.
6 daysisland: let record events own the OBS stateDanilo M.1-4/+13
6 daysisland: keep a paused OBS take as recordingDanilo M.1-2/+6
6 dayssettings: OBS scenes icon pageDanilo M.1-2/+44
6 daysisland: icon buttons, audio and corner controls, scene gridDanilo M.2-29/+71
6 daysisland: OBS desktop audio and webcam corner controlDanilo M.1-1/+41
6 daysisland: corner position helper for the OBS webcamDanilo M.2-1/+15
6 daysisland: watched scene icon map singletonDanilo M.1-0/+46
6 daysisland: scene icon map logic and its testsDanilo M.2-0/+139
6 daysdocs: the OBS pillDanilo M.1-0/+19
6 daysisland: place the OBS pill and pulse the sliver while recordingDanilo M.1-2/+43
6 daysisland: OBS pill and its controls panelDanilo M.1-0/+125
6 daysisland: Obs singleton, obs-websocket v5 clientDanilo M.1-0/+217
6 daysisland: obs-websocket auth helperDanilo M.1-0/+22
6 daysisland: elapsed-time helper for the OBS pillDanilo M.2-1/+17
7 daysappearance moves into the settings windowDanilo M.1-1/+1
The appearance shell existed because a wallpaper picker needed more room than the 600px drawer, so it ran as its own process with a full-screen overlay. The settings window now gives it that room, and its five tabs become five settings pages in the desktop process: Wallpaper, Theme, Icons & cursor, Sunset and Idle. appearance/ is gone, and with it a process, a keepalive window and a layer blur rule. The files move to desktop/modules/appearance/ unchanged in what they do. Each tab gets a small *Module.qml; the window's refresh-on-open calls the singletons' refresh(), which the panel's show() used to. The two tabs that were inline Components in AppearancePanel become ThemeTab and WallpaperTab, owning the notices the panel printed. Sunset, Idle and Icons drop their own Flickable so the page scrolls them and search can reveal a row; the wallpaper list virtualises its rows and scrolls itself, so it takes the page's new viewHeight instead. Search finds a colour scheme and an icon or cursor theme by name. The appearance IPC target moves to desktop/shell.qml with the same verbs, so udt-steps and any keybind change only the path. Git now follows the appearance pages and autostart in the sidebar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 daysfix(island): say why a drop is refusedDanilo M.2-6/+24
A drop offering no local file:// URL was refused silently: the bubble vanished and nothing happened. Measured on the first report: the file manager offers a trashed file as trash:, with no path to read. The bubble now shows the reason for a moment, Trash named as such, and the refusal is logged with the URL schemes and offered formats (never the paths). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 daysfix(assistant): keep state across reloads, refusals and long repliesDanilo M.1-1/+2
From review. A shell reload reconnected with lastActive at 0, so the next SUPER+Home started a new conversation thirty seconds into one; hello with turns now counts as activity. show() could send new under a reply still running, which stops it unsaved; it waits while busy. ask() cleared the chips before the daemon accepted them, so a refused file (unreadable, too big, a model without vision) dropped them and collapsed the card to the entry line; the user event clears them now, and chatting holds the layout while a PDF is read. In the picker, folders ignore name filters and sorted first, so filter then Enter opened a folder; folders hide while filtering. Folder URLs are encoded, so a '#' in a name no longer cuts the path, and glob characters typed in the filter are taken literally. The card says the assistant is not running in every state, panels sit under the chat header instead of over it, and History and the picker no longer open together. Dropped file://localhost/ URLs are accepted, other hosts refused, and the island receptor keeps the sliver's width at rest so it takes no clicks beside it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 daysfeat(island): take a file drop for the assistantDanilo M.2-0/+63
A DropArea over the sliver grows into a bubble while a file drag is over it and hands file:// paths to the canvas. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
7 daysfeat(island): a media pill left of the clockDanilo M.3-2/+183
Shows album art and a scrolling "artist · album · title" while a player is playing or paused, using the sound module's Player so the browser proxy duplicates are already filtered. Hovering swaps the text for a progress bar, swapped in place rather than growing the pill; MPRIS does not push position, so it is re-read every second while hovered, and a click seeks only when the player reports canSeek and a known length. The wheel steps tracks one per notch, as the layout flag does, so a touchpad does not skip several. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysfeat(perf): the performance page moves to the drawer, with ~/.cacheDanilo M.3-92/+12
The island's performance icon and panel are gone: the drawer page covers them. With only one host left, the panel drops its three-column grid for one card per row at a larger size, since the page scrolls; temperatures get a card of their own as tiles. The files move from island/perf to modules/perf. A cache card ports conky's: ~/.cache and its five largest children, measured with du each time the page opens (28ms over 2 GiB here) rather than read from conky's 15-minute sampler file. The largest is yellow, red past half the total, as conky had it. The warning dot now shows only on the drawer tile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysdocs(spec): user details in the drawerDanilo M.4-979/+0
A drawer row greets the login user and opens a page that edits name, email, avatar, language and location, written where other programs already read them: AccountsService (and through it the passwd GECOS LibreOffice reads), KDE's emaildefaults and the global git config, with the surname shortened to an initial for git. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysfeat(desktop): performance and clipboard pages, a scrolling tile gridDanilo M.3-5/+11
The tile grid sits in a Flickable capped at three rows, so the fourth row the new modules bring scrolls inside that box instead of eating the notification space; a thin accent bar in the margin shows only when a row is hidden. Tiles are reordered with the everyday ones first. Performance shows the island's PerfPanel in a Page, with a tile line of CPU and RAM and the warning dot. Perf.detailed is now a count of live PerfPanel instances instead of a binding in the status pill: the island and the drawer both host the panel, and a bool with two writers would let one clear it under the other. Clipboard reads cliphist when its page opens: search, copy on click or Enter, delete per row, clear all behind a 3 second confirm, image entries as thumbnails decoded once onto tmpfs. Entries reach sh as $1, never inside a command string. A copy closes the drawer through a new Page.dismiss signal the drawer connects like back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 daysrefactor(island): the controls panel goesDanilo M.7-598/+13
Each of its seven tiles opened a drawer page that already existed, and it went unused. SUPER alone will open the drawer instead. Removed with it: the status pill's controls icon, Island.toggleControls, the island IPC target, Controls.js and its test, and the controls list in Prefs. Prefs now holds only the pinned IP; a controls key left in desktop.json is still kept on write, because writes merge into the parsed document. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysdocs: the performance panelDanilo M.1-1/+38
What the panel shows, the dot's thresholds and their lack of hysteresis, why the public IP is pinned, and what is sampled always versus only while open. AGENTS.md gains two gotchas found building it: FileView reads /proc on reload(), and a hot reload does not resize an existing layer surface, which left the panel cut off after the height was raised. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysfix(perf): review findings in the service and the panelDanilo M.5-16/+26
- The panel loads only while open. Its models are fresh arrays every sample, so a hidden instance rebuilt its rows every 2s for the whole session. - The public IP fetch never kills one already running, and waits 30 minutes from the last attempt, not the last success: a rate-limited or offline fetch was retried every minute. - curl -4, so an IPv6 answer cannot silently stall the VPN check. - CPU load sums only the first eight /proc/stat fields. guest and guest_nice are already inside user and nice, and counting them again read high while VMs ran. - df gets timeout -k; the VRAM scan is not restarted over itself. - The GPU name joins the host constants in Perf.qml. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysfix(island): the window is tall enough for the performance panelDanilo M.1-1/+3
The performance grid runs past the old 360px surface and its disks card was cut off. The surface is click-through outside the pills, so the extra height costs nothing. A hot reload does not resize an existing layer surface; it takes a restart of the desktop component. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysfeat(island): the status pill opens the performance panelDanilo M.2-7/+57
A system monitor icon before the controls icon opens the panel in the status pill's capsule at 600px. A dot on its corner shows the worst of temperatures, RAM, disks and the public IP check, yellow or red, so a problem shows without opening anything. The detailed sampling runs only while the panel is open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysfeat(perf): the performance panel's card gridDanilo M.1-0/+330
CPU with per-core bars, RAM and temperatures down the left; GPU and network beside it; disks under those two. Colours follow conky's bands so the numbers read as they did there. The pin beside the public IP stores the address shown, and the address turns red when a fresh one differs from the pin. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
10 daysfeat(perf): the performance serviceDanilo M.1-0/+295
CPU, RAM, temperatures and disks are sampled always, so the island's icon can warn with the panel closed; per-core load, the network rate, VRAM and the GPU fan only while the panel is open. hwmon chips are found by name, since their numbers move across boots. df runs under timeout so a dead NFS server keeps the last rows rather than blocking. The public IP keeps conky's cache file and 30 minute pace. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
10 daysfeat(perf): pure parsing and arithmetic for the performance panelDanilo M.2-0/+336
/proc/stat deltas, meminfo, df rows, the fdinfo VRAM sum, byte rates, hwmon lookup by chip name, the pubip cache in conky's format, and the bands that colour the panel and the icon. A reading that cannot be made is null, and null never raises the worst band, so a missing sensor cannot raise an alarm. Only a fresh public IP can mismatch the pinned one; a failed fetch goes stale instead. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
10 daysdocs(island): calendar edits touch only what changedDanilo M.1-2/+4
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysfix(calendar): review findings in calctl and the editorDanilo M.7-59/+170
An edit now rewrites only the fields that changed. A save with nothing changed used to rebuild the alarm, turning ACTION:AUDIO into DISPLAY and dropping ACKNOWLEDGED, re-anchor the start to the local zone, and strip SUMMARY's parameters; the test edits a foreign event unchanged and checks every one survives. get, edit and delete name the calendar the event is in. The same invite synced into two calendars has one UID, and the panel acted on whichever file came first, so editing one copy could overwrite or delete the other. A custom rule's date cannot be moved from the panel: BYDAY=MO stayed on Monday while the start moved, and the series lost the day shown. UNTIL is read back in local time, so a 22:30 series keeps its last occurrence. Files are written 0644 like vdirsyncer's. Enter in the title no longer bypasses the busy guard, which could create an event twice, and a throwing callback no longer leaks its Process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 daysdocs: the calendar panel and calctlDanilo M.1-1/+18
The island README gains the panel. AGENTS.md records why calctl reads the vdir itself, the local-time recurrence rule, the system Python it needs, and two traps the build hit: a QML method named escape fails to load, and a pill expanding for any panel grew beside the calendar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 daysfeat(calendar): a bell on agenda rows whose event has an alarmDanilo M.1-1/+12
Checking a day's reminders meant opening each event. The bell shows when the event carries its own VALARM, preset or custom. cal-notif's per-calendar defaults are not reflected: they are its configuration, not a property of the event. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 daysfix(island): the status pill stays at rest while the calendar is openDanilo M.1-1/+1
It expanded for any panel, which was right while it hosted every panel there was. The calendar panel lives in the clock pill, so the status pill grew into an empty box beside it. It now expands for its own two. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 daysfeat(island): the clock pill opens the calendar panelDanilo M.3-7/+45
A click on the pill opens the panel in its capsule, 620px wide, growing left from the gap so the status pill does not move. Focus goes into the panel so its text fields and Escape work; Escape closes the editor before the panel. The Escape hook is back(), not escape(): QML rejects a method named escape with "Illegal method name", since it shadows the global JS function, and the reload failed until it was renamed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 daysfeat(calendar): month grid beside the day's agendaDanilo M.1-0/+323
Six weeks from Monday, a dot per calendar with something that day, today and the selection marked. The agenda lists the selected day, all-day first; a click opens the event in the editor, and while the editor is open the grid picks its dates instead of the selection. Escape closes the editor before the panel. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
11 daysfeat(calendar): the event formDanilo M.1-0/+356
Dates come from the month grid beside it; times are typed or scrolled in 15-minute steps. Repeat and alarm offer the presets and show custom, unselectable, for an event carrying something richer, which the save then leaves alone. A failed save keeps the form open with calctl's line. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
11 daysfeat(calendar): the calendar serviceDanilo M.1-0/+102
Runs calctl, one Process per call so a reload and a save never collide, and drops a list that a newer one overtook. Watches the calendar directories the way the mail count watches xapian, so an edit from khal or a cron sync repaints the panel too. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
11 daysfeat(calendar): pure date logic for the panelDanilo M.2-0/+279
Month cells from Monday, which days an event covers, the day's agenda order, the grid's dots, time stepping, and the editor's draft in both directions. Days are strings and arithmetic is in UTC, so the DST change at the end of October never moves a day; the test steps across it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
11 daysfeat(calendar): calctl creates, edits and deletes eventsDanilo M.2-1/+237
Edits change only what the form owns: a custom rule, extra alarms and properties this tool does not know survive, which the test checks on an event with BYDAY, two alarms and an X- property. Writes go through a temporary file and a rename so khal, cal-notif and vdirsyncer never read half a file, and a vdirsyncer sync is started detached afterwards. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
11 daysfeat(calendar): calctl reads the vdir as JSONDanilo M.2-0/+444
The calendar list comes from khal's config, so there is no second list. Recurrence is expanded with dateutil in naive local time, which keeps a weekly 09:00 at 09:00 across the DST change; the test pins that on 26 October. A rule richer than a plain FREQ, or alarms other than one preset, read as custom, which is what lets an edit leave them alone. A file that fails to parse is skipped rather than blanking the month. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
11 daysfix(island): review findings in the controls panelDanilo M.3-2/+14
Edit mode let a right-click and the wheel through to the tile, so a right-click opened the drawer and scroll changed volume, against the spec. The drag area now takes both buttons and the wheel. A scroll up on a level already above the cap, such as a mic set to 120% elsewhere, snapped it down to the cap. The cap now only stops a step up. Prefs logs a failed write, which printErrors off had silenced: the new order would otherwise vanish at the next restart with no trace. Its parsed object is renamed from data to doc, so it cannot shadow a base property of that name. The spec now says what was built: JSON.parse rather than a JsonAdapter, and the helper list as it is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 daysdocs: the controls panel, its preferences file and bindDanilo M.1-1/+24
The island README gains the panel. AGENTS.md records that a bare SUPER release bind is cancelled by drag and scroll on Hyprland 0.56.2, which was the open risk in the spec, and that FileView creates parent directories while Quickshell.stateDir is per-shell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 daysfeat(island): controls panel in the status pill, island IPCDanilo M.2-7/+48
A settings icon in the status pill opens the controls panel in the same capsule the sound panel uses. Right-click on a tile closes the panel and opens its drawer page. The island IPC target reveals the island and toggles the panel, for the SUPER release bind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 daysfeat(island): controls grid with an edit modeDanilo M.1-0/+175
Four columns, the visible list from Prefs. Edit mode puts a MouseArea over each tile that drags it and drops it into the slot under its centre, a × that hides it, and a strip of hidden tiles with a + each. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>