feat: add a native macOS build with new Preferences and notifications - #1
Open
gahingwoo wants to merge 1 commit into
Open
feat: add a native macOS build with new Preferences and notifications#1gahingwoo wants to merge 1 commit into
gahingwoo wants to merge 1 commit into
Conversation
gahingwoo
force-pushed
the
macos-support
branch
2 times, most recently
from
August 2, 2026 10:47
5fc498c to
0e2a2d1
Compare
Koshi now builds and runs as a standalone .app on macOS with no Homebrew dependency at runtime. build-aux/macos/bundle.sh compiles the release binary, relinks every dylib it needs with dylibbundler, and bundles the gdk-pixbuf loaders, the GIO TLS module, the Adwaita and hicolor icon themes, and compiled GSettings schemas alongside it. A matching build-macos job in the release workflow packages the result as a .dmg and attaches it to the GitHub release next to the Flatpak; it also installs adwaita-icon-theme explicitly, since neither gtk4 nor libadwaita depends on it and a Homebrew prefix that has never had another GTK app built on it (a fresh CI runner, mainly) won't have it. On macOS the window buttons now match every other platform instead of showing native traffic lights: GtkHeaderBar and GtkWindowControls both default to platform-native controls there since GTK 4.18, so the main window and every dialog force use-native-controls off and move the buttons to the right. AdwDialog also hardcodes its own close button to the start side with no public way to reposition it, so dialogs get a plain close button of their own on the end side instead. Keyboard shortcuts move from a hardcoded <Control> to <Primary> (plus an explicit <Meta> fallback on macOS, where <Primary>'s resolution to Cmd has proven unreliable in practice), so Cmd+F and friends work as expected instead of only ever answering to a literal Ctrl press. New replies notify through UNUserNotificationCenter on macOS, since there is no session D-Bus for the existing XDG portal path to use. Authorization is requested once at startup rather than on the first notification, because addNotificationRequest fails outright while authorization is still undecided and asking any later would lose a fresh install's first notification to that race. A warning row in Preferences points the user at System Settings if they end up denying it. Preferences also picks up a few things asked for directly: adjustable text size for message bodies and, separately, for the whole interface (the interface one scales through gtk-xft-dpi, the same knob GNOME's own large-text accessibility setting uses, so it reaches menus and dialogs too); a system/light/dark theme switch; and, in the thread view, per-message toggles to fold away quoted text and diff hunks without losing the row's place in the list. Folding a line only shrinks the row once the tag covers its trailing newline, not just its glyphs, and diff-folding now hides a hunk's unchanged context lines along with the colored ones - leaving them out stranded isolated fragments of code with blank gaps around them instead of closing the hunk. Thread parsing now drops a message repeated under the same Message-ID: lore mirrors a cross-posted message once per list it was sent to, so a thread spanning more than one list could come back from t.mbox.gz with the same message twice, showing as a genuine duplicate in the thread view and, since the watcher's digest pass goes through the same parser, as a duplicate notification too. The profile popover gained an editor for git send-email identities. Creating, editing, or deleting one still writes straight to the user's global git config, matching how profile.rs already treats git as the only account store Koshi keeps. Finally, a new Sent page (mirroring Favorites/Subscriptions) logs every reply once git send-email has actually confirmed delivery - subject, recipients, when, and, for a reply to a thread Koshi had open, enough to reopen that thread the same way a favorite does.
gahingwoo
force-pushed
the
macos-support
branch
from
August 2, 2026 10:51
0e2a2d1 to
9169e0b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Koshi now builds and runs as a standalone .app on macOS with no
Homebrew dependency at runtime. build-aux/macos/bundle.sh compiles the
release binary, relinks every dylib it needs with dylibbundler, and
bundles the gdk-pixbuf loaders, the GIO TLS module, the Adwaita and
hicolor icon themes, and compiled GSettings schemas alongside it. A
matching build-macos job in the release workflow packages the result
as a .dmg and attaches it to the GitHub release next to the Flatpak;
it also installs adwaita-icon-theme explicitly, since neither gtk4 nor
libadwaita depends on it and a Homebrew prefix that has never had
another GTK app built on it (a fresh CI runner, mainly) won't have it.
On macOS the window buttons now match every other platform instead of
showing native traffic lights: GtkHeaderBar and GtkWindowControls both
default to platform-native controls there since GTK 4.18, so the main
window and every dialog force use-native-controls off and move the
buttons to the right. AdwDialog also hardcodes its own close button to
the start side with no public way to reposition it, so dialogs get a
plain close button of their own on the end side instead. Keyboard
shortcuts move from a hardcoded to (plus an
explicit fallback on macOS, where 's resolution to Cmd
has proven unreliable in practice), so Cmd+F and friends work as
expected instead of only ever answering to a literal Ctrl press.
New replies notify through UNUserNotificationCenter on macOS, since
there is no session D-Bus for the existing XDG portal path to use.
Authorization is requested once at startup rather than on the first
notification, because addNotificationRequest fails outright while
authorization is still undecided and asking any later would lose a
fresh install's first notification to that race. A warning row in
Preferences points the user at System Settings if they end up denying
it.
Preferences also picks up a few things asked for directly: adjustable
text size for message bodies and, separately, for the whole interface
(the interface one scales through gtk-xft-dpi, the same knob GNOME's
own large-text accessibility setting uses, so it reaches menus and
dialogs too); a system/light/dark theme switch; and, in the thread
view, per-message toggles to fold away quoted text and diff hunks
without losing the row's place in the list. Folding a line only
shrinks the row once the tag covers its trailing newline, not just its
glyphs, and diff-folding now hides a hunk's unchanged context lines
along with the colored ones - leaving them out stranded isolated
fragments of code with blank gaps around them instead of closing the
hunk.
Thread parsing now drops a message repeated under the same Message-ID:
lore mirrors a cross-posted message once per list it was sent to, so a
thread spanning more than one list could come back from t.mbox.gz with
the same message twice, showing as a genuine duplicate in the thread
view and, since the watcher's digest pass goes through the same
parser, as a duplicate notification too.
The profile popover gained an editor for git send-email identities.
Creating, editing, or deleting one still writes straight to the user's
global git config, matching how profile.rs already treats git as the
only account store Koshi keeps.
Finally, a new Sent page (mirroring Favorites/Subscriptions) logs every
reply once git send-email has actually confirmed delivery - subject,
recipients, when, and, for a reply to a thread Koshi had open, enough
to reopen that thread the same way a favorite does.