diff --git a/src/Surface.zig b/src/Surface.zig index eda00483f..24b67a647 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -122,6 +122,9 @@ const Mouse = struct { /// Pending scroll amounts for high-precision scrolls pending_scroll_x: f64 = 0, pending_scroll_y: f64 = 0, + + /// True if the mouse is hidden + hidden: bool = false, }; /// The configuration that a surface has, this is copied from the main @@ -138,6 +141,7 @@ const DerivedConfig = struct { copy_on_select: configpkg.CopyOnSelect, confirm_close_surface: bool, mouse_interval: u64, + mouse_hide_while_typing: bool, macos_non_native_fullscreen: configpkg.NonNativeFullscreen, macos_option_as_alt: configpkg.OptionAsAlt, window_padding_x: u32, @@ -157,6 +161,7 @@ const DerivedConfig = struct { .copy_on_select = config.@"copy-on-select", .confirm_close_surface = config.@"confirm-close-surface", .mouse_interval = config.@"click-repeat-interval" * 1_000_000, // 500ms + .mouse_hide_while_typing = config.@"mouse-hide-while-typing", .macos_non_native_fullscreen = config.@"macos-non-native-fullscreen", .macos_option_as_alt = config.@"macos-option-as-alt", .window_padding_x = config.@"window-padding-x", @@ -961,6 +966,14 @@ pub fn keyCallback( } } + // If this input event has text, then we hide the mouse if configured. + if (self.config.mouse_hide_while_typing and + !self.mouse.hidden and + event.utf8.len > 0) + { + self.hideMouse(); + } + // No binding, so we have to perform an encoding task. This // may still result in no encoding. Under different modes and // inputs there are many keybindings that result in no encoding @@ -1049,6 +1062,9 @@ pub fn scrollCallback( // log.info("SCROLL: xoff={} yoff={} mods={}", .{ xoff, yoff, scroll_mods }); + // Always show the mouse again if it is hidden + if (self.mouse.hidden) self.showMouse(); + const ScrollAmount = struct { // Positive is up, right sign: isize = 1, @@ -1446,6 +1462,9 @@ pub fn mouseButtonCallback( self.mouse.click_state[@intCast(@intFromEnum(button))] = action; self.mouse.mods = @bitCast(mods); + // Always show the mouse again if it is hidden + if (self.mouse.hidden) self.showMouse(); + // Shift-click continues the previous mouse state if we have a selection. // cursorPosCallback will also do a mouse report so we don't need to do any // of the logic below. @@ -1594,6 +1613,9 @@ pub fn cursorPosCallback( const tracy = trace(@src()); defer tracy.end(); + // Always show the mouse again if it is hidden + if (self.mouse.hidden) self.showMouse(); + // We are reading/writing state for the remainder self.renderer_state.mutex.lock(); defer self.renderer_state.mutex.unlock(); @@ -1852,6 +1874,18 @@ fn scrollToBottom(self: *Surface) !void { try self.queueRender(); } +fn hideMouse(self: *Surface) void { + if (self.mouse.hidden) return; + self.mouse.hidden = true; + self.rt_surface.setMouseVisibility(false); +} + +fn showMouse(self: *Surface) void { + if (!self.mouse.hidden) return; + self.mouse.hidden = false; + self.rt_surface.setMouseVisibility(true); +} + /// Perform a binding action. A binding is a keybinding. This function /// must be called from the GUI thread. pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !void { diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index 2efab9539..3a53bb9dc 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -542,6 +542,11 @@ pub const Surface = struct { self.cursor = new; } + /// Set the visibility of the mouse cursor. + pub fn setMouseVisibility(self: *Surface, visible: bool) void { + self.window.setInputModeCursor(if (visible) .normal else .hidden); + } + /// Read the clipboard. The windowing system is responsible for allocating /// a buffer as necessary. This should be a stable pointer until the next /// time getClipboardString is called. diff --git a/src/config/Config.zig b/src/config/Config.zig index b5e4340dd..7a0adb8c4 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -119,6 +119,10 @@ palette: Palette = .{}, /// will be chosen. @"cursor-text": ?Color = null, +/// Hide the mouse immediately when typing. The mouse becomes visible +/// again when the mouse is used. +@"mouse-hide-while-typing": bool = false, + /// The opacity level (opposite of transparency) of the background. /// A value of 1 is fully opaque and a value of 0 is fully transparent. /// A value less than 0 or greater than 1 will be clamped to the nearest