Forráskód Böngészése

WindowServer+Magnifier: Make Magnifier buttery smooth :^)

This patch moves the magnifier rect computation over to the server side
to ensure that the mouse cursor position and the screen image never get
out of sync.
Andreas Kling 4 éve
szülő
commit
cb295ab644

+ 2 - 7
Userland/Applications/Magnifier/MagnifierWidget.cpp

@@ -39,13 +39,8 @@ void MagnifierWidget::set_scale_factor(int scale_factor)
 
 void MagnifierWidget::sync()
 {
-    m_mouse_position = GUI::WindowServerConnection::the().get_global_cursor_position();
-    m_desktop_display_scale = GUI::WindowServerConnection::the().get_desktop_display_scale();
-
-    // Grab and paint our screenshot.
-    Gfx::IntSize region_size { size().width() / m_scale_factor, size().height() / m_scale_factor };
-    Gfx::Rect region { (m_mouse_position.x() * m_desktop_display_scale) - (region_size.width() / 2), (m_mouse_position.y() * m_desktop_display_scale) - (region_size.height() / 2), region_size.width(), region_size.height() };
-    m_grabbed_bitmap = GUI::WindowServerConnection::the().get_screen_bitmap(region).bitmap();
+    Gfx::IntSize grab_size { size().width() / m_scale_factor, size().height() / m_scale_factor };
+    m_grabbed_bitmap = GUI::WindowServerConnection::the().get_screen_bitmap_around_cursor(grab_size).bitmap();
     update();
 }
 

+ 0 - 2
Userland/Applications/Magnifier/MagnifierWidget.h

@@ -23,8 +23,6 @@ private:
 
     void sync();
 
-    Gfx::IntPoint m_mouse_position;
     int m_scale_factor { 2 };
-    int m_desktop_display_scale { 1 };
     RefPtr<Gfx::Bitmap> m_grabbed_bitmap;
 };

+ 14 - 0
Userland/Services/WindowServer/ClientConnection.cpp

@@ -904,6 +904,20 @@ Messages::WindowServer::GetScreenBitmapResponse ClientConnection::get_screen_bit
     return bitmap.to_shareable_bitmap();
 }
 
+Messages::WindowServer::GetScreenBitmapAroundCursorResponse ClientConnection::get_screen_bitmap_around_cursor(Gfx::IntSize const& size)
+{
+    auto scale_factor = WindowManager::the().scale_factor();
+    auto cursor_location = Screen::the().cursor_location();
+    Gfx::Rect rect { (cursor_location.x() * scale_factor) - (size.width() / 2), (cursor_location.y() * scale_factor) - (size.height() / 2), size.width(), size.height() };
+
+    // Recompose the screen to make sure the cursor is painted in the location we think it is.
+    // FIXME: This is rather wasteful. We can probably think of a way to avoid this.
+    Compositor::the().compose();
+
+    auto bitmap = Compositor::the().front_bitmap_for_screenshot({}).cropped(rect);
+    return bitmap->to_shareable_bitmap();
+}
+
 Messages::WindowServer::IsWindowModifiedResponse ClientConnection::is_window_modified(i32 window_id)
 {
     auto it = m_windows.find(window_id);

+ 1 - 0
Userland/Services/WindowServer/ClientConnection.h

@@ -147,6 +147,7 @@ private:
     virtual void set_scroll_step_size(u32) override;
     virtual Messages::WindowServer::GetScrollStepSizeResponse get_scroll_step_size() override;
     virtual Messages::WindowServer::GetScreenBitmapResponse get_screen_bitmap(Optional<Gfx::IntRect> const&) override;
+    virtual Messages::WindowServer::GetScreenBitmapAroundCursorResponse get_screen_bitmap_around_cursor(Gfx::IntSize const&) override;
     virtual void set_double_click_speed(i32) override;
     virtual Messages::WindowServer::GetDoubleClickSpeedResponse get_double_click_speed() override;
     virtual void set_window_modified(i32, bool) override;

+ 1 - 0
Userland/Services/WindowServer/WindowServer.ipc

@@ -121,6 +121,7 @@ endpoint WindowServer
     get_scroll_step_size() => (u32 step_size)
 
     get_screen_bitmap(Optional<Gfx::IntRect> rect) => (Gfx::ShareableBitmap bitmap)
+    get_screen_bitmap_around_cursor(Gfx::IntSize size) => (Gfx::ShareableBitmap bitmap)
 
     pong() =|