From 5a083c03a62e9ad1595995a847007cc47b14bef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filiph=20Sandstr=C3=B6m?= Date: Wed, 30 Nov 2022 13:45:35 +0100 Subject: [PATCH] WindowServer: Add "Natural scrolling" support Also commonly referred to as "reverse scrolling" or "inverted scrolling". --- Base/etc/WindowServer.ini | 1 + .../Services/WindowServer/ConnectionFromClient.cpp | 10 ++++++++++ .../Services/WindowServer/ConnectionFromClient.h | 2 ++ Userland/Services/WindowServer/EventLoop.cpp | 7 ++++++- Userland/Services/WindowServer/WindowManager.cpp | 14 ++++++++++++++ Userland/Services/WindowServer/WindowManager.h | 3 +++ Userland/Services/WindowServer/WindowServer.ipc | 3 +++ 7 files changed, 39 insertions(+), 1 deletion(-) diff --git a/Base/etc/WindowServer.ini b/Base/etc/WindowServer.ini index 30d0a8eb3e7..a5e7fcd9f72 100644 --- a/Base/etc/WindowServer.ini +++ b/Base/etc/WindowServer.ini @@ -23,6 +23,7 @@ AccelerationFactor=1.0 ScrollStepSize=4 CursorTheme=Default ButtonsSwitched=false +NaturalScroll=false [Graphics] OverlayRectShadow=/res/graphics/overlay-rect-shadow.png diff --git a/Userland/Services/WindowServer/ConnectionFromClient.cpp b/Userland/Services/WindowServer/ConnectionFromClient.cpp index a715decadbd..e5b4e1524a2 100644 --- a/Userland/Services/WindowServer/ConnectionFromClient.cpp +++ b/Userland/Services/WindowServer/ConnectionFromClient.cpp @@ -1110,6 +1110,16 @@ Messages::WindowServer::GetButtonsSwitchedResponse ConnectionFromClient::get_but return WindowManager::the().get_buttons_switched(); } +void ConnectionFromClient::set_natural_scroll(bool inverted) +{ + WindowManager::the().set_natural_scroll(inverted); +} + +Messages::WindowServer::IsNaturalScrollResponse ConnectionFromClient::is_natural_scroll() +{ + return WindowManager::the().is_natural_scroll(); +} + void ConnectionFromClient::set_unresponsive(bool unresponsive) { if (m_unresponsive == unresponsive) diff --git a/Userland/Services/WindowServer/ConnectionFromClient.h b/Userland/Services/WindowServer/ConnectionFromClient.h index 1d69214ab55..e48a62fc36c 100644 --- a/Userland/Services/WindowServer/ConnectionFromClient.h +++ b/Userland/Services/WindowServer/ConnectionFromClient.h @@ -178,6 +178,8 @@ private: virtual Messages::WindowServer::GetDoubleClickSpeedResponse get_double_click_speed() override; virtual void set_buttons_switched(bool) override; virtual Messages::WindowServer::GetButtonsSwitchedResponse get_buttons_switched() override; + virtual void set_natural_scroll(bool) override; + virtual Messages::WindowServer::IsNaturalScrollResponse is_natural_scroll() override; virtual void set_window_modified(i32, bool) override; virtual Messages::WindowServer::IsWindowModifiedResponse is_window_modified(i32) override; virtual Messages::WindowServer::GetDesktopDisplayScaleResponse get_desktop_display_scale(u32) override; diff --git a/Userland/Services/WindowServer/EventLoop.cpp b/Userland/Services/WindowServer/EventLoop.cpp index 7a1d28683b7..205188516e8 100644 --- a/Userland/Services/WindowServer/EventLoop.cpp +++ b/Userland/Services/WindowServer/EventLoop.cpp @@ -70,10 +70,15 @@ void EventLoop::drain_mouse() state.x = packet.x; state.y = packet.y; } - state.z += packet.z; state.w += packet.w; state_is_sent = false; + // Invert scroll direction if checked in the settings. + if (WindowManager::the().is_natural_scroll()) + state.z -= packet.z; + else + state.z += packet.z; + if (packet.buttons != state.buttons) { state.buttons = packet.buttons; dbgln_if(WSMESSAGELOOP_DEBUG, "EventLoop: Mouse Button Event"); diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index 5175c35e721..33544d7e0d9 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -83,6 +83,7 @@ void WindowManager::reload_config() m_double_click_speed = m_config->read_num_entry("Input", "DoubleClickSpeed", 250); m_buttons_switched = m_config->read_bool_entry("Mouse", "ButtonsSwitched", false); + m_natural_scroll = m_config->read_bool_entry("Mouse", "NaturalScroll", false); m_cursor_highlight_radius = m_config->read_num_entry("Mouse", "CursorHighlightRadius", 25); Color default_highlight_color = Color::NamedColor::Red; default_highlight_color.set_alpha(110); @@ -305,6 +306,19 @@ bool WindowManager::get_buttons_switched() const return m_buttons_switched; } +void WindowManager::set_natural_scroll(bool inverted) +{ + m_natural_scroll = inverted; + dbgln("Saving scroll inverted state {} to config file at {}", inverted, m_config->filename()); + m_config->write_bool_entry("Mouse", "NaturalScroll", inverted); + sync_config_to_disk(); +} + +bool WindowManager::is_natural_scroll() const +{ + return m_natural_scroll; +} + WindowStack& WindowManager::window_stack_for_window(Window& window) { if (is_stationary_window_type(window.type())) diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index feb4e10e003..ce0076c728c 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -153,6 +153,8 @@ public: int double_click_speed() const; void set_buttons_switched(bool); bool get_buttons_switched() const; + void set_natural_scroll(bool); + bool is_natural_scroll() const; void set_active_window(Window*); void set_hovered_button(Button*); @@ -433,6 +435,7 @@ private: int m_max_distance_for_double_click { 4 }; bool m_previous_event_was_super_keydown { false }; bool m_buttons_switched { false }; + bool m_natural_scroll { false }; bool m_theme_overridden { false }; WeakPtr m_hovered_window; diff --git a/Userland/Services/WindowServer/WindowServer.ipc b/Userland/Services/WindowServer/WindowServer.ipc index 75c262c9164..b773cdfc1a7 100644 --- a/Userland/Services/WindowServer/WindowServer.ipc +++ b/Userland/Services/WindowServer/WindowServer.ipc @@ -176,6 +176,9 @@ endpoint WindowServer set_buttons_switched(bool switched) =| get_buttons_switched() => (bool switched) + set_natural_scroll(bool inverted) =| + is_natural_scroll() => (bool inverted) + get_desktop_display_scale(u32 screen_index) => (int desktop_display_scale) set_flash_flush(bool enabled) =|