aboutsummaryrefslogtreecommitdiffstats
path: root/internal
AgeCommit message (Collapse)AuthorFilesLines
22 hoursfix(notify): treat icons up to 256px as an app icon, not a previewDanilo M.2-4/+10
A 256px themed icon or logo was still drawn as a large balloon preview. The bound is now 256 on the long side, which covers kitty's own PNG and typical application logos; a screenshot stays well above it.
22 hoursfix(notify): route icon-like content images to the app-icon slotDanilo M.3-1/+163
Clients like kitty, mail and opencode send their icon through the content-image hint, so it drew as a large balloon preview. A theme-name source, an SVG, or a raster small on both sides now fills the app-icon slot instead; a larger raster (a screenshot) stays the preview. An app_icon already present keeps the slot.
22 hoursfix(notify): bound RowStride before the int64 guardDanilo M.2-4/+31
The dimension cap closed the named overflow, but stride was still r.RowStride whenever RowStride >= Width*Channels, and asInt accepts an int64 wire value. With Width=2, Height=2, RowStride=MaxInt the int64 need product wraps negative, the guard passes, and r.Data[y*stride:] panics at y=1. Reject a negative stride and any stride above Width*Channels+4096, which is the real packing plus alignment slack. After the cap and this bound neither need nor y*stride can overflow, so the comment now says so.
22 hoursfix(notify): cap image dimensions and rank icon_data lastDanilo M.4-12/+104
A notification is untrusted input. RawImage.PNG computed stride*(Height-1)+Width*Channels in int, so Width=Height=2^31-1 with RowStride=0 wrapped the length expression negative, slipped past the guard, and reached image.NewRGBA, which panics. The D-Bus call path has no recover, so one malformed Notify killed the daemon. Cap Width/Height at 1<<16 before any multiplication and compute the required byte count in int64. image-data, image-path and the deprecated icon_data were read as one tier, with icon_data ahead of image-path, inverting the spec's order. Split the deprecated key into IconDataFromHints and apply tier 1 (image-data/image_data), then image-path, then icon_data. Raw handling is unchanged: encode, hold pendingImage, WriteImage after Add, SetImage.
23 hourstest(notify): cover image-data materialisationDanilo M.2-0/+39
TestNotifyMaterialisesImageData drives a 2x2 RGBA image-data hint through Notify and asserts the PNG is written under the image directory for the returned id, decodes to the right bounds, and is carried on the re-published Popup.Image. The encode-error path now logs instead of dropping the failure silently, matching the WriteImage branch.
23 hourstest(notify): send -1, not 0, in the expiry assertionDanilo M.1-1/+1
The spec makes 0 mean never expire, so the test asserting a non-zero Expires was asserting against the wrong input. -1 asks the server to decide, which is a normal 10s at normal urgency, so the assertion holds. Pre-existing on base a248608 and unrelated to the image support.
23 hoursfeat(notify): materialise notification imagesDanilo M.2-3/+53
Notify resolves app_icon and image-path theme names, decodes image-data to a PNG under the image directory, and re-publishes the entry with its image path. The daemon advertises body-images, and removeImage refuses to touch a path outside its own directory so a client's screenshot file is never deleted.
23 hoursfix(notify): cover expiry cleanup and harden the image-removal guardDanilo M.3-4/+49
Split the dismiss test so expiry is exercised on its own: Expire removes the image without deleting the inert entry, and nothing asserted it. removeImage now requires filepath.Dir(filepath.Clean(path)) to equal the image directory, so a path carrying .. cannot reach a sibling daemon file such as queue.json. The previous prefix test accepted it. Not exploitable until Task 4 populates Popup.Image from a client hint, which is exactly why the guard is fixed now.
23 hoursfeat(notify): add the image field and its cleanupDanilo M.6-14/+126
Popup gains image, and the store calls an injected removeImage when an entry is dismissed, evicted, replaced or expired, so a daemon-written PNG does not outlive its balloon. The service decides what is daemon-owned; the store only names the path. NewStore now takes the callback as a third parameter, so the service wires its removeImage in (unlinking only under ImagesDir) and the existing call sites pass nil.
23 hoursfix(notify): search freedesktop icon layout and rank by effective sizeDanilo M.2-14/+170
The hicolor fallback scanned <theme>/apps/<size>, but freedesktop themes use <size>/apps, so hicolor never resolved. Both layouts are now searched, and rasters are ranked by effective pixel size (N@2x is 2N) with a deterministic name tie-break.
23 hoursfeat(notify): resolve theme icon names to filesDanilo M.2-0/+228
qt6ct's icon_theme is authoritative on this desktop, with the GTK3 setting and hicolor as fallbacks. The lookup prefers scalable, then the largest raster, and follows the theme's Inherits chain, so an app that passes a name instead of a path gets an icon.
23 hourstest(notify): actually exercise rowstride, 3-channel and short-data pathsDanilo M.1-7/+46
The stride test was Height 1, so the second row and the padding beyond the used pixels were never reached and rowstride was untested despite the comment. It is now 2x2 with RowStride 12 and asserts a pixel in row 1, which fails if the stride is ignored (verified by mutation). Add the 3-channel opaque encode and the short-data rejection, both explicit requirements of the image-data contract.
23 hoursfeat(notify): parse the image hints and encode them to PNGDanilo M.2-0/+235
image-data (and the deprecated icon_data) is the (iiibiiay) struct; the PNG encoder honours rowstride and both 3- and 4-channel data. The path and data readers are pure, so the service can apply the spec's priority and the store stays free of image handling.
27 hoursfix: honour the freedesktop expire_timeout directionDanilo M.2-10/+14
The spec says -1 means the server decides and 0 means never; the code had them swapped, so a plain notify-send (libnotify's default is -1) became immortal and an explicit never (-t 0) got the urgency default. Found by the live handover test, where notify-send produced expires 0. The urgency default is unchanged: low and normal 10s, critical never.
27 hoursfix: close the review nits in the write path, query path and testsDanilo M.2-3/+19
Remove the temp file on every writeJSON failure path, not just the write and close ones. A failed rename left the temp behind with no cleanup. Surface the list path's unmarshal error instead of printing null with exit 0, and make a non-positive history limit print an empty array rather than falling through to the whole ring. Assert the evicted item actually lands in the history ring, so the "files to history" half of eviction is covered rather than just its signal. Add the missing README License section beside the GPLv2 text and headers.
27 hoursfeat: add the control interface and notifyctlDanilo M.1-2/+33
The private interface carries what the spec cannot: close-all, invoke action and clear history. notifyctl reads the published files for list and history, because the files are the interface, and uses D-Bus only for the mutations.
27 hoursfix: delete the timer entry on natural expiryDanilo M.2-2/+38
27 hoursfeat: add the D-Bus service and the daemonDanilo M.3-0/+303
Notify assigns an id and publishes; a replaces_id or stack tag reuses the id. CloseNotification closes with reason 3. The daemon claims org.freedesktop.Notifications and exits non-zero if it cannot, which is what happens while dunst still holds it.
27 hoursfeat: publish the queue and history atomicallyDanilo M.2-0/+124
Both files are written whole through a temporary file and a rename, so a renderer never reads a half-written value. An empty queue is [] rather than null, because the renderer parses it as an array.
27 hoursfeat: add the notification storeDanilo M.2-0/+352
The store holds the live queue and the history ring as pure state. Expiry tells the client and keeps the entry inert; dismissal and eviction file it in history. Replacing reuses the id and emits nothing.
27 hoursfix: add the GPLv2 header to the policy testDanilo M.1-0/+11
27 hoursfeat: add the module and the notification policyDanilo M.2-0/+184
The policy functions are pure so they are tested without a bus: urgency from the hints, the timeout rule with its urgency defaults, the two stack tag spellings, and the action pair parse.