7.8 KiB
Plan: Keyboard Shortcut to Toggle All Menu Bars (per-window)
Goal
Add a configurable keyboard shortcut that shows/hides all the browser's
"menu bars" — the per-tab toolbars, bookmark bars, and the tab strip —
independently per window. Pressing the shortcut in one window hides
that window's chrome only; other windows are unaffected. This mirrors how
the agent sidebar already works (per-window sidebar_visible on
window_state_t).
In sovereign_browser there is no traditional GtkMenuBar; each tab's chrome
is two widgets packed at the top of the tab page
(tab->page):
#main-toolbar— the horizontal GtkBox holding the hamburger menu button, refresh/stop, back, forward, URL entry, and bookmark button (built intab_create()).#bookmark-bar— the bookmarks toolbar below the URL toolbar (tab->bookmark_bar).
Plus the tab strip itself, which is the GtkNotebook header, controlled
via gtk_notebook_set_show_tabs().
Hiding all three gives the webview the entire window (a focus / kiosk mode). Pressing the shortcut again restores them.
Design
1. New shortcut action
Add SHORTCUT_TOGGLE_TOOLBARS to the enum in shortcuts.h
(before SHORTCUT_COUNT) and a matching entry in the g_registry table in
shortcuts.c:
| Field | Value |
|---|---|
| id | toggle_toolbars |
| label | Toggle menu bars |
| desc | Show or hide the tab strip, toolbars, and bookmark bars in the active window |
| dflt | <Control><Shift>m |
Default <Control><Shift>m ("m" for menu) is free and mnemonic. It is a
browser-level shortcut (not consumed by WebKit for web content), so it
reaches the window-level on_key_press handler reliably.
Because the settings page enumerates actions via
sovereign://settings/config (which loops over
SHORTCUT_COUNT calling shortcuts_meta() /
shortcuts_get()), the new action appears
automatically in the Keyboard Shortcuts section of
www/settings.html with no JS changes. NIP-78 sync
also picks it up for free via shortcuts_serialize().
2. Track toolbar widgets on each tab
The #main-toolbar GtkBox is currently a local variable in
tab_create() and is not stored on
tab_info_t. Add a field:
GtkWidget *toolbar; /* #main-toolbar (hamburger + nav + URL) */
to tab_info_t in tab_manager.h, and assign
tab->toolbar = toolbar; in tab_create().
tab->bookmark_bar already exists.
3. Per-window visibility flag
Add a field to window_state_t in
tab_manager.c:
gboolean toolbars_visible; /* per-window menu-bar visibility */
Initialize it to TRUE for g_main_window (in
tab_manager_init, near where
sidebar_visible = FALSE is set at line 3643) and for each aux window
created in tab_manager_new_window (near line
1376 where sidebar_visible = FALSE is set).
4. Toggle function (active window only)
Add a public function in tab_manager.c:
void tab_manager_toggle_toolbars(void);
Implementation — mirrors tab_manager_toggle_sidebar():
window_state_t *ws = get_active_window_state();— resolves the focused window (main or aux), exactly like the sidebar toggle does.- Flip
ws->toolbars_visible. gtk_notebook_set_show_tabs(GTK_NOTEBOOK(ws->notebook), ws->toolbars_visible);— hides/shows the tab strip for this window's notebook only.- Iterate
g_tabs[0..g_tab_count)and, for each tab whose page belongs to this window's notebook (usetab_find_notebook(tab->page)and compare tows->notebook), callgtk_widget_set_visible(tab->toolbar, ws->toolbars_visible)andgtk_widget_set_visible(tab->bookmark_bar, ws->toolbars_visible).
This affects only the active window's tabs and tab strip; other windows
keep their own toolbars_visible state.
5. Respect hidden state for new tabs
In tab_create(), after building toolbar and
tab->bookmark_bar, look up the notebook the tab is being added to (the
target notebook — g_active_notebook / get_effective_notebook() at tab
creation time, or tab_find_notebook(tab->page) after packing) and its
window_state_t via window_state_for_notebook(),
then apply that window's flag:
window_state_t *ws = window_state_for_notebook(<target notebook>);
gboolean vis = ws ? ws->toolbars_visible : TRUE;
gtk_widget_set_visible(toolbar, vis);
gtk_widget_set_visible(tab->bookmark_bar, vis);
So a tab opened in a hidden-chrome window is also hidden, while a tab
opened in a visible-chrome window stays visible. The tab strip visibility
is per-notebook via gtk_notebook_set_show_tabs(), so no extra work is
needed there.
6. Dispatch the shortcut
Add a case to the switch in on_key_press in
main.c:
case SHORTCUT_TOGGLE_TOOLBARS:
tab_manager_toggle_toolbars();
return TRUE;
The key-press handler is window-level, so get_active_window_state()
inside the toggle resolves to the window that had focus when the key was
pressed — giving the per-window behavior.
7. Expose in tab_manager.h
Add the prototype for tab_manager_toggle_toolbars(void) near the other
toggle prototypes (tab_manager_toggle_inspector,
tab_manager_toggle_sidebar).
Files touched
| File | Change |
|---|---|
src/shortcuts.h |
Add SHORTCUT_TOGGLE_TOOLBARS to enum |
src/shortcuts.c |
Add registry entry (id/label/desc/dflt) |
src/tab_manager.h |
Add GtkWidget *toolbar field + tab_manager_toggle_toolbars prototype |
src/tab_manager.c |
Add toolbars_visible to window_state_t; init to TRUE for main + aux windows |
src/tab_manager.c |
Store tab->toolbar; apply window's toolbars_visible on creation; implement tab_manager_toggle_toolbars() (active window only: tab strip + that window's tabs' toolbars/bookmark bars) |
src/main.c |
Add case SHORTCUT_TOGGLE_TOOLBARS dispatch |
No changes needed in www/ (settings page auto-discovers the action) or in
settings_sync.c (NIP-78 sync already serializes all actions).
Verification
make— builds clean../browser.sh restart --login-method generate --url https://example.com- Press
Ctrl+Shift+M→ in the focused window, toolbars + bookmark bar + tab strip disappear; the webview fills the entire window. Press again → they reappear. - Open a second window (
Ctrl+N). Hide chrome in window A withCtrl+Shift+M; window B's chrome stays visible. Hide B independently. - With chrome hidden in a window,
Ctrl+Topens a new tab in that window whose toolbars are also hidden; the tab strip stays hidden too. - Open
sovereign://settings→ Keyboard Shortcuts section lists "Toggle menu bars" withCtrl+Shift+M; rebind it and confirm the new binding works.