Skip to content

Commit

Permalink
add 'Toggle Menu Bar' menu item on Windows or Linux
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysd committed Oct 17, 2023
1 parent 076f4e3 commit c04f36d
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 23 deletions.
1 change: 0 additions & 1 deletion v2/src/assets/default_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ keymaps:
ctrl+up: ScrollTop
ctrl+j: ScrollNextSection
ctrl+k: ScrollPrevSection
alt: ShowMenu
?: Help

# Configuration related to text search.
Expand Down
1 change: 0 additions & 1 deletion v2/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ const DEFAULT_KEY_MAPPINGS: &[(&str, KeyAction)] = {
("ctrl+up", ScrollTop),
("ctrl+j", ScrollNextSection),
("ctrl+k", ScrollPrevSection),
("alt", ShowMenu),
("?", Help),
]
};
Expand Down
3 changes: 3 additions & 0 deletions v2/src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ pub enum MenuItem {
OpenRepo,
ToggleAlwaysOnTop,
EditConfig,
#[cfg(not(target_os = "macos"))]
ToggleMenuBar,
}

pub trait RawMessageWriter {
Expand Down Expand Up @@ -192,6 +194,7 @@ pub trait Renderer {
fn drag_window(&self) -> Result<()>;
fn window_appearance(&self) -> WindowAppearance;
fn show_menu_at(&self, position: Option<(f64, f64)>);
fn toggle_menu(&mut self) -> Result<()>;
}

/// Context to execute rendering.
Expand Down
2 changes: 2 additions & 0 deletions v2/src/shiba.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,8 @@ where
Print => self.renderer.print()?,
ZoomIn => self.zoom(Zoom::In)?,
ZoomOut => self.zoom(Zoom::Out)?,
#[cfg(not(target_os = "macos"))]
ToggleMenuBar => self.renderer.toggle_menu()?,
History => self.renderer.send_message(MessageToRenderer::History)?,
ToggleAlwaysOnTop => self.toggle_always_on_top()?,
Help => self.renderer.send_message(MessageToRenderer::Help)?,
Expand Down
71 changes: 52 additions & 19 deletions v2/src/wry/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ use muda::{
AboutMetadata, ContextMenu, LogicalPosition, Menu as MenuBar, MenuEvent, MenuEventReceiver,
MenuId, MenuItem, Position, PredefinedMenuItem, Submenu,
};
use std::collections::hash_map::Entry;
use std::collections::HashMap;
#[cfg(target_os = "macos")]
use wry::application::platform::macos::WindowExtMacOS as _;
#[cfg(target_os = "linux")]
use wry::application::platform::unix::WindowExtUnix as _;
#[cfg(target_os = "windows")]
use wry::application::platform::windows::WindowExtWindows as _;
use wry::application::window::Window;
use wry::application::window::{Window, WindowId};

fn metadata() -> AboutMetadata {
let mut m = AboutMetadata {
Expand Down Expand Up @@ -67,6 +68,7 @@ impl MenuEvents {
pub struct Menu {
// This instance must be kept since dropping this instance removes menu from application
menu_bar: MenuBar,
visibility: HashMap<WindowId, bool>,
#[cfg(target_os = "macos")]
window_menu: Submenu,
#[cfg(target_os = "macos")]
Expand All @@ -90,6 +92,7 @@ impl Menu {
let menu_bar = MenuBar::new();

// Custom menu items
let settings = no_accel("Settings…");
let quit = accel("Quit", MOD, Code::KeyQ);
let open_file = accel("Open File…", MOD, Code::KeyO);
let watch_dir = accel("Watch Directory…", MOD | Modifiers::SHIFT, Code::KeyO);
Expand All @@ -101,12 +104,13 @@ impl Menu {
let reload = accel("Reload", MOD, Code::KeyR);
let zoom_in = accel("Zoom In", MOD | Modifiers::SHIFT, Code::Equal); // XXX: US keyboard only
let zoom_out = accel("Zoom Out", MOD, Code::Minus);
#[cfg(not(target_os = "macos"))]
let toggle_menu_bar = no_accel("Toggle Menu Bar");
let forward = accel("Forward", MOD, Code::BracketRight);
let back = accel("Back", MOD, Code::BracketLeft);
let history = accel("History…", MOD, Code::KeyY);
let always_on_top = no_accel("Pin/Unpin On Top");
let guide = no_accel("Show Guide…");
let settings = no_accel("Settings…");
let open_repo = no_accel("Open Repository Page");

// Menu bar structure
Expand All @@ -124,6 +128,10 @@ impl Menu {
&PredefinedMenuItem::separator(),
&zoom_in,
&zoom_out,
#[cfg(not(target_os = "macos"))]
&PredefinedMenuItem::separator(),
#[cfg(not(target_os = "macos"))]
&toggle_menu_bar,
],
)?;
let help_menu = Submenu::with_items("&Help", true, &[&guide, &open_repo])?;
Expand Down Expand Up @@ -227,12 +235,15 @@ impl Menu {
(guide.into_id(), Help),
(open_repo.into_id(), OpenRepo),
(settings.into_id(), EditConfig),
#[cfg(not(target_os = "macos"))]
(toggle_menu_bar.into_id(), ToggleMenuBar),
]
});

log::debug!("Registered menu items: {:?}", events.ids);
Ok(Self {
menu_bar,
visibility: HashMap::new(),
#[cfg(target_os = "macos")]
window_menu,
#[cfg(target_os = "macos")]
Expand All @@ -245,24 +256,46 @@ impl Menu {
&self.menu_bar
}

pub fn set_to_window(&self, window: &Window) -> Result<()> {
#[cfg(target_os = "windows")]
{
self.menu_bar.init_for_hwnd(window.hwnd() as _)?;
}
#[cfg(target_os = "linux")]
{
self.menu_bar.init_for_gtk_window(window.gtk_window(), window.default_vbox())?;
}
#[cfg(target_os = "macos")]
{
self.menu_bar.init_for_nsapp();
self.window_menu.set_as_windows_menu_for_nsapp();
self.help_menu.set_as_help_menu_for_nsapp();
let _ = window;
pub fn toggle(&mut self, window: &Window) -> Result<()> {
let id = window.id();
match self.visibility.entry(id) {
Entry::Vacant(entry) => {
#[cfg(target_os = "windows")]
self.menu_bar.init_for_hwnd(window.hwnd() as _)?;
#[cfg(target_os = "linux")]
self.menu_bar.init_for_gtk_window(window.gtk_window(), window.default_vbox())?;
#[cfg(target_os = "macos")]
{
self.menu_bar.init_for_nsapp();
self.window_menu.set_as_windows_menu_for_nsapp();
self.help_menu.set_as_help_menu_for_nsapp();
}
entry.insert(true);
log::debug!("Initialized menubar for window (id={:?})", id);
Ok(())
}
#[cfg(target_os = "macos")]
Entry::Occupied(_) => Ok(()), // On macOS, menu bar is always visible
#[cfg(not(target_os = "macos"))]
Entry::Occupied(entry) => {
let visible = entry.into_mut();
if *visible {
#[cfg(target_os = "windows")]
self.menu_bar.hide_for_hwnd(window.hwnd() as _)?;
#[cfg(target_os = "linux")]
self.menu_bar.hide_for_gtk_window(window.gtk_window())?;
log::debug!("Hide menu on window (id={:?})", id);
} else {
#[cfg(target_os = "windows")]
self.menu_bar.show_for_hwnd(window.hwnd() as _)?;
#[cfg(target_os = "linux")]
self.menu_bar.show_for_gtk_window(window.gtk_window())?;
log::debug!("Show menu on window (id={:?})", id);
}
*visible = !*visible;
Ok(())
}
}
log::debug!("Added menubar to window");
Ok(())
}

pub fn show_at(&self, position: Option<(f64, f64)>, window: &Window) {
Expand Down
8 changes: 6 additions & 2 deletions v2/src/wry/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ pub struct WebViewRenderer {
}

impl WebViewRenderer {
pub fn new(config: &Config, event_loop: &EventLoop, menu: Menu) -> Result<Self> {
pub fn new(config: &Config, event_loop: &EventLoop, mut menu: Menu) -> Result<Self> {
let mut builder = WindowBuilder::new().with_title("Shiba").with_visible(false);

let window_state = if config.window().restore { config.data_dir().load() } else { None };
Expand Down Expand Up @@ -222,7 +222,7 @@ impl WebViewRenderer {

let window = builder.build(event_loop)?;
if cfg!(target_os = "macos") || config.window().menu {
menu.set_to_window(&window)?;
menu.toggle(&window)?;
}

let webview = create_webview(window, event_loop, config)?;
Expand Down Expand Up @@ -357,4 +357,8 @@ impl Renderer for WebViewRenderer {
fn show_menu_at(&self, position: Option<(f64, f64)>) {
self.menu.show_at(position, self.webview.window());
}

fn toggle_menu(&mut self) -> Result<()> {
self.menu.toggle(self.webview.window())
}
}

0 comments on commit c04f36d

Please sign in to comment.