Skip to content

feat: v1.6.0 — theme system fix, new themes, session restore, native frame mode, tab UX#170

Merged
puneetsl merged 13 commits into
masterfrom
feat/v1.6.0
May 26, 2026
Merged

feat: v1.6.0 — theme system fix, new themes, session restore, native frame mode, tab UX#170
puneetsl merged 13 commits into
masterfrom
feat/v1.6.0

Conversation

@puneetsl
Copy link
Copy Markdown
Owner

@puneetsl puneetsl commented May 26, 2026

Summary

Post-v1.5.1 feature batch + packaging/docs overhaul. 12 commits, bumps to v1.6.0.

🎨 Themes (closes #150)

  • Fix: built-in themes (Dracula/Nord/Gruvbox/4 Catppuccin) were listed in the menu but never shipped CSS — theming silently no-oped for everyone. CSS files now bundled in assets/themes/ and override Notion's current --c-* variable convention with !important on .notion-dark-theme / .notion-light-theme.
  • Add: Monokai, Noir, Sakura (10 themes total).
  • Sync: picking a light theme flips Notion's "use system setting" to light via nativeTheme.themeSource; dark themes flip it back.

🪟 Window & Tab UX

🎛️ Logo Menu

Native checkboxes instead of emoji + text-prefix hacks; About dialog; Help & GitHub submenu.

📦 Arch packaging (closes the root cause of #146)

  • Rewrote PKGBUILD as lotion-bin — downloads the official .deb from the GitHub release and extracts it. Same binary as the official build, ~30s install, no npm install chain on the user's machine (that was the source of the 950 packages + vulnerability output the user in Severe issues with Arch install? #146 complained about).
  • Deleted install-arch.sh (bash <(curl …) pattern, security-flagged, redundant with makepkg).
  • Updated PKGBUILD.md and knol/AUR_SUBMISSION.md for the new flow.
  • Updated the test-arch workflow to fail CI if the PKGBUILD drifts off .deb sources or if npm calls sneak back in.
  • README is honest about AUR status: not yet on the AUR, build locally from the included PKGBUILD.

📝 README rewrite

Drifted out of sync over time — version badge was 1.5.0, Electron 34.3.2, themes list missed 5 themes, .deb example used 1.0.0, broken references to portable.sh and a root-level AUR_SUBMISSION.md that didn't exist. Rewritten end to end:

  • Updated badges + features for v1.6.0
  • All 10 themes listed (dark/light table)
  • Custom-theme CSS example uses the correct --c-* selectors that actually work
  • Honest Arch install section
  • Full keyboard shortcuts table
  • Configuration / user-data paths documented
  • File-tree updated to reflect the current layout

🔧 Fixes that fell out

  • Restart hang on native-frame toggle (app.exit(0)setImmediate + app.quit()).
  • Notion content not filling window after native-frame init (post-show resize hook).

Commits

2d3be12 Rewrite README for v1.6.0
688a1f2 Rewrite Arch packaging as lotion-bin (closes #146 root cause)
61d81c4 Bump to v1.6.0 + CHANGELOG entry
c3b48db Fix #150: built-in themes now actually apply + add Monokai, Noir, Sakura
ba079fe Fix Notion content sizing after native-frame mode init
ef20076 Implement #151: option to use native DE window decorations
426158d Fix #158: replace tab overflow scrollbar with shrink-then-fade pattern
f463500 Redesign logo menu for a more professional look
5635038 Add session restore + fix first-tab visibility bug
46163a4 Fix #157: active tab indicator not updating on tab switch
c98058d Fix #155: zoom shortcuts on non-US keyboard layouts

Test plan

  • Pick each of the 10 themes — Notion content + tab bar both pick up theme colors
  • Pick Sakura/Latte → Notion's appearance setting (if on "use system") flips to light; pick Dracula → flips back to dark
  • Enable "Restore Tabs on Startup", open 3 tabs to different pages, close via X button, relaunch — all 3 tabs restore with the right active one
  • Toggle "Use Native Window Decorations" → restart dialog → Restart Now → app comes back with native title bar + visible menu bar, no orphan processes
  • Toggle back → custom tab bar restored
  • Try Ctrl+=, Ctrl+-, Ctrl+0 zoom shortcuts (and Ctrl++ on US layouts)
  • Drag tabs to reorder; switch tabs and check active-tab underline follows; open many tabs and confirm fade indicators on edges
  • Open logo menu — only one theme is checked at a time; About dialog opens
  • On Arch: git clone this branch, cd lotion, makepkg -si — lotion installs from the release .deb without running npm, lotion command works
  • README renders correctly on GitHub (tables, code blocks, image refs)

Not included

AUR follow-up (not in this PR)

Once this merges and the v1.6.0 release builds, someone with AUR access can publish lotion-bin to the AUR using the workflow in knol/AUR_SUBMISSION.md. Until then, users build from the included PKGBUILD.

🤖 Generated with Claude Code

puneetsl and others added 13 commits May 25, 2026 03:18
Replace the built-in zoomIn/zoomOut/resetZoom menu roles with explicit
handlers using CmdOrCtrl+= / CmdOrCtrl+- / CmdOrCtrl+0 accelerators.
The default 'Plus' accelerator binds to the layout's '+' key, which on
Spanish (and other) layouts requires a modifier the user shouldn't have
to press. Using '=' as the primary key works across layouts, with a
hidden CmdOrCtrl+Shift+= alias so US users pressing Ctrl++ still
trigger zoom in.

Also retarget the zoom calls from the BrowserWindow's webContents (the
tab bar) to the active tab's WebContentsView so the Notion content
actually scales.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Redux subscriber that drives tab-bar IPC updates only watched
state.tabs.tabs and ignored state.windows.windows[*].activeTabId, so
clicking a tab updated the WebContentsView but never resent the
tab-activated event. The highlight stayed on the previously active tab
until something else (new tab, title change, etc.) caused a tab-data
diff. Track active-tab IDs across windows in a separate snapshot and
notify when either snapshot changes.

Fix #156: enable drag-and-drop tab reordering

The IPC handler tab-bar:reorder-tabs and the preload bridge were both
already in place, but the renderer never wired any drag handlers, so
the documented reorder feature simply did nothing. Add native HTML5
drag-and-drop on tab elements with before/after drop indicators and an
optimistic local reorder before the IPC roundtrip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add an opt-in "Restore Tabs on Startup" toggle (in the logo popup
menu) that persists each window's tabs and restores them on next
launch.

Implementation:
- AppController: debounced Redux subscriber writes a session snapshot
  to electron-store on every state change. Saving on before-quit
  doesn't work because clicking the window's X fires window-closed
  first, which wipes Redux state and empties windowControllers, so
  before-quit had nothing left to save.
- TabController: also listen for did-navigate-in-page so Notion's
  pushState-based routing keeps the saved URL in sync with the page
  the user is actually on.
- WindowController: dispatch addWindow BEFORE createInitialTab. The
  reverse order silently dropped the first tab from tabIds (since
  addTabToWindow no-ops when the window entry doesn't exist yet).
  This bug pre-dated session restore — it was just invisible with one
  tab because the tab bar still showed the "+" button. Restore made it
  visible by trying to add subsequent tabs that *did* register.
- index.js: localStore default for restoreTabsOnStartup, and a
  ✓-prefixed toggle item in the logo popup menu (the standard
  Electron menu bar is hidden by design in Lotion).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the ✓-prefix and emoji-decoration pattern with native Electron
menu controls and a cleaner hierarchy:
- App version header at the top
- type:'checkbox' for Spell Check and Restore Tabs on Startup (proper
  native checkmark instead of a text prefix that flipped the label)
- type:'radio' for theme selection (mutually exclusive)
- Themes grouped in a submenu
- About Lotion dialog with version and a button to open GitHub
- Help & GitHub submenu collects external links (Star, Follow, Report
  Issue)
- Spell-check tab application extracted into a small helper for clarity

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch the tab bar's overflow behavior from "show a native horizontal
scrollbar" to a hybrid that matches mainstream tabbed apps:

1. Tabs shrink first (min-width 100→80px) so moderate tab counts fit
   without scrolling at all — Chrome/Firefox behavior.
2. When even shrunk tabs overflow, the scrollbar is styled thin and
   transparent until hover, so it's not visually intrusive.
3. Mouse-wheel over the tab list scrolls horizontally (vertical wheel
   translates to scrollLeft) so users can navigate without aiming for
   the hidden scrollbar.
4. A soft fade mask appears on whichever edge has hidden tabs as a
   discoverable "more tabs that way" cue — toggled live on scroll and
   on resize.

Also move the "+" button out of the scrolling .tab-list so it stays
pinned next to the window controls instead of scrolling out of view
when the bar overflows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a Use Native Window Decorations toggle (logo menu + standard menu
bar's Lotion submenu) that swaps the frameless custom-tab-bar window
for a native-frame single-tab window.

Trade-off is deliberate: combining tabs with native decorations would
mean stacking two title bars, so native mode drops the tab bar
entirely. Settings/navigation in native mode go through the standard
Electron menu bar (which is already wired up, just hidden in custom
mode). The session-restore feature still works as one-tab-per-window.

The Electron `frame` option is fixed at BrowserWindow creation, so
toggling shows a Restart Now / Later dialog rather than trying to
hot-swap.

WindowController reads the setting in its constructor, conditionally
skips the tab bar, sets `frame`/`titleBarStyle`, makes the menu bar
visible, and uses a 0-height tab-bar offset so the active tab fills
the content area.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When the user toggled "Use Native Window Decorations" and Lotion
relaunched, the WM-reported window bounds on Linux were sometimes
stale at the moment we computed view bounds (especially with DE
decorations enabled), leaving a gap below the WebContentsView so the
Notion content didn't fill the window. Hook the BrowserWindow 'show'
event to re-run updateViewBounds, with a second pass 100ms later to
catch WMs that report final geometry only after a frame or two of
compositing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 7 named themes (Dracula, Nord, Gruvbox Dark, 4 Catppuccin
variants) were listed in the menu but never shipped any CSS — the
injector looked under ~/.config/Lotion/themes/<name>.css and silently
no-oped when nothing was there. That's why every reporter in #150
said theming was broken regardless of OS.

Ship 10 themes as bundled assets and fall back to them when no user
override is present. New themes added beyond the original 7: Monokai
(classic Sublime palette), Noir (high-contrast B&W + blood red), and
Sakura (pastel pink Hello-Kitty light theme).

Three follow-ups that fell out of getting the themes to actually
paint:

- Notion no longer uses the --theme--* variable convention from the
  old notion-enhancer era — it uses obfuscated --c-* names declared
  on .notion-dark-theme / .notion-light-theme (on <body>). CSS custom
  properties inherit from the closest defining ancestor, so a :root
  override is shadowed for everything inside <body>. Each theme
  declares on :root + body + .notion-dark-theme + .notion-light-theme
  + .notion-app-inner with !important so our values win regardless of
  where Notion (or a Notion update) puts the source.

- nativeTheme.themeSource is set to match each theme's mode
  ('light' / 'dark' / 'system') so Notion's "use system setting"
  appearance preference auto-flips its own light/dark when the user
  picks a Sakura-style light theme or a Dracula-style dark theme.
  Initialized at app startup from the saved theme so launches are
  consistent before any window opens.

- Tab bar (separate WebContentsView, not reached by injected CSS)
  gets matching color classes for the 3 new themes and the
  class-removal list is kept in sync so themes don't leak across
  switches.

Menu fixes that came out of polishing the Theme submenu:
- Switch from type:'radio' to type:'checkbox' for theme items —
  Electron's radio behavior in popup menus on Linux/GTK was leaking
  selected state across menu instances, so users saw 3+ themes
  marked as "active" after a few switches.

Also fix a hang on the Use-Native-Window-Decorations restart: the
old code did app.exit(0) right after the dialog .then() returned,
bypassing graceful BrowserWindow teardown and orphaning renderer
processes. Defer to setImmediate then call app.quit() so WebContents
cleanup runs first.

dumpNotionCSSVars() is kept on TabController (gated behind
LOTION_DUMP_VARS=1) for future investigations when Notion next
changes their CSS variable naming.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Minor-version bump for the post-1.5.1 feature batch: 10-theme system
fix, Monokai/Noir/Sakura additions, system-theme sync, session
restore, native window decorations toggle, tab UX fixes, and the
logo menu redesign.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous PKGBUILD built from source by running `npm install` + `npm
run package` inside makepkg. That's exactly what the user in #146 was
complaining about: hundreds of npm warnings, deprecated packages,
"12 vulnerabilities (4 low, 4 moderate, 4 high)" on a fresh install.
The vulnerabilities aren't really Lotion's fault — they're inherent
to building any Electron app from source — but we shouldn't be forcing
that experience on people who just want to install Lotion.

Switch to a lotion-bin style PKGBUILD: it downloads the .deb produced
by our build-and-release workflow and extracts it into the system.
Same binary that ships in the official release, ~30s install instead
of ~5min, no npm chain on the user's machine.

- PKGBUILD: -bin style, separate source_x86_64 / source_aarch64
  pulling lotion_${pkgver}_${arch}.deb from the GitHub release.
  package() just calls bsdtar to extract the .deb. Declares Electron
  runtime deps (gtk3, nss, libxss, libsecret, libnotify, alsa-lib,
  xdg-utils) explicitly.
- PKGBUILD.md: documents the new approach + update workflow.
- knol/AUR_SUBMISSION.md: rewritten for lotion-bin naming and the
  release-artifact-driven release flow.
- install-arch.sh: deleted. The "bash <(curl ...)" pattern is
  security-flagged and was solving a problem (one-line install) that
  AUR / makepkg solves better.
- test-arch-install.yml: replaced source-build / install-arch.sh
  checks with assertions that the PKGBUILD stays binary-only — fails
  CI if the source array drifts off .deb or if npm calls sneak back
  in.

Note: the lotion-bin package isn't actually published on the AUR
yet — README is updated to reflect that. The PKGBUILD works locally
via `makepkg -si` from this repo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Substantial overhaul. The previous README had drifted out of sync with
reality across several axes — the AUR section claimed `yay -S lotion`
worked when the package isn't on the AUR; the Themes section listed 8
themes when v1.6.0 ships 10; the Electron version badge was three
majors behind; `.deb` / `.rpm` install examples used 1.0.0 filenames;
and there were broken references (`portable.sh`, root-level
`AUR_SUBMISSION.md`) that didn't exist.

Rewritten so it reflects what actually ships:

- Version badge bumped to 1.6.0, Electron badge to 41.7.0.
- Features section restructured into Window/Tabs, Theming, Other.
  Calls out the v1.6.0 additions explicitly: session restore (opt-in),
  native window decorations toggle, shrink-then-fade tab overflow,
  layout-independent zoom shortcuts.
- Themes section lists all 10 in a dark/light table, including the
  new Monokai / Noir / Sakura, and mentions the system-theme sync
  behavior (light theme → Notion flips its "use system" appearance to
  light, dark theme → dark).
- Custom themes example rewritten against Notion's current --c-*
  variable convention with the right selector list (Notion declares
  these on .notion-dark-theme on <body>, so :root alone isn't enough).
  Points readers at assets/themes/ for a complete template.
- Arch install section is honest: lotion-bin isn't on the AUR yet,
  here's how to build from the PKGBUILD locally.
- Other install examples use 1.6.0 filenames.
- Removes references to nonexistent files (portable.sh, root-level
  AUR_SUBMISSION.md) and fixes the actual path to knol/.
- Adds a proper keyboard shortcuts table (zoom, navigation, prefs,
  devtools).
- Adds a configuration section listing where user data lives
  (~/.config/Lotion/) and pointer to the logo menu for preferences.
- Development section trimmed: file tree updated to reflect current
  layout (assets/themes/, managers/, etc.), and includes a small note
  on how to dump Notion CSS variables when their naming changes in
  the future (LOTION_DUMP_VARS=1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Unsigned Electron apps on Apple Silicon get the misleading "Lotion
is damaged and can't be opened" Gatekeeper error rather than the
clearer "unidentified developer" warning Intel macs used to show.
It's not actually damaged — macOS just refuses to validate the
missing signature.

Two fixes in this change:

1. Add `osxSign: { identity: "-" }` to packagerConfig so the build
   does an ad-hoc signature. Doesn't satisfy Gatekeeper (no Apple
   Developer cert involved), but does change the error from
   "damaged" to "unidentified developer" — meaning the user can
   right-click → Open to bypass it interactively. No money or Apple
   account required.

2. README macOS section explains why it happens, links the GitHub
   Sponsors page for if someone wants to fund the $99/year Developer
   Program, and gives the two user-side workarounds (xattr -cr on
   the .zip before extraction, or on the extracted .app). Also adds
   a brief Windows SmartScreen note for symmetry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Arch Linux container's default GitHub Actions shell is `sh -e`,
where `source` doesn't exist (POSIX uses `.`) and bash array
expansions like ${source_x86_64[@]} aren't valid syntax. The
"Verify lotion-bin-style PKGBUILD shape" step failed with
"source: PKGBUILD: file not found" because of that.

Set defaults.run.shell=bash at the job level so all run steps use
bash. Cleaner than scattering shell: bash on individual steps and
leaves room for future bashisms in the validation logic without
having to remember the shell override each time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@puneetsl puneetsl merged commit 492b0d7 into master May 26, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Option to use DEs Window decorations Themeing does not work

1 participant