Ver código fonte

LibGUI+WindowServer: Add a GResizeCorner widget.

This widget is automatically included in GStatusBar, but can be added in
any other place, too. When clicked (with the left button), it initiates a
window resize (using a WM request.)

In this patch I also fixed up some issues with override cursors being
cleared after the WindowServer finishes a drag or resize.
Andreas Kling 6 anos atrás
pai
commit
ea9a39a9f2

BIN
Base/res/icons/resize-corner.png


+ 10 - 4
LibGUI/GEventLoop.cpp

@@ -24,6 +24,7 @@
 //#define COALESCING_DEBUG
 //#define COALESCING_DEBUG
 
 
 int GEventLoop::s_event_fd = -1;
 int GEventLoop::s_event_fd = -1;
+int GEventLoop::s_my_client_id = -1;
 pid_t GEventLoop::s_server_pid = -1;
 pid_t GEventLoop::s_server_pid = -1;
 
 
 void GEventLoop::connect_to_server()
 void GEventLoop::connect_to_server()
@@ -59,8 +60,7 @@ void GEventLoop::connect_to_server()
     request.type = WSAPI_ClientMessage::Type::Greeting;
     request.type = WSAPI_ClientMessage::Type::Greeting;
     request.greeting.client_pid = getpid();
     request.greeting.client_pid = getpid();
     auto response = sync_request(request, WSAPI_ServerMessage::Type::Greeting);
     auto response = sync_request(request, WSAPI_ServerMessage::Type::Greeting);
-    s_server_pid = response.greeting.server_pid;
-    GDesktop::the().did_receive_screen_rect(Badge<GEventLoop>(), response.greeting.screen_rect);
+    handle_greeting(response);
 }
 }
 
 
 GEventLoop::GEventLoop()
 GEventLoop::GEventLoop()
@@ -235,8 +235,7 @@ void GEventLoop::process_unprocessed_bundles()
     for (auto& bundle : unprocessed_bundles) {
     for (auto& bundle : unprocessed_bundles) {
         auto& event = bundle.message;
         auto& event = bundle.message;
         if (event.type == WSAPI_ServerMessage::Type::Greeting) {
         if (event.type == WSAPI_ServerMessage::Type::Greeting) {
-            s_server_pid = event.greeting.server_pid;
-            GDesktop::the().did_receive_screen_rect(Badge<GEventLoop>(), event.greeting.screen_rect);
+            handle_greeting(event);
             continue;
             continue;
         }
         }
 
 
@@ -402,3 +401,10 @@ WSAPI_ServerMessage GEventLoop::sync_request(const WSAPI_ClientMessage& request,
     ASSERT(success);
     ASSERT(success);
     return response;
     return response;
 }
 }
+
+void GEventLoop::handle_greeting(WSAPI_ServerMessage& message)
+{
+    s_server_pid = message.greeting.server_pid;
+    s_my_client_id = message.greeting.your_client_id;
+    GDesktop::the().did_receive_screen_rect(Badge<GEventLoop>(), message.greeting.screen_rect);
+}

+ 4 - 1
LibGUI/GEventLoop.h

@@ -21,6 +21,7 @@ public:
     WSAPI_ServerMessage sync_request(const WSAPI_ClientMessage& request, WSAPI_ServerMessage::Type response_type);
     WSAPI_ServerMessage sync_request(const WSAPI_ClientMessage& request, WSAPI_ServerMessage::Type response_type);
 
 
     static pid_t server_pid() { return s_server_pid; }
     static pid_t server_pid() { return s_server_pid; }
+    static int my_client_id() { return s_my_client_id; }
 
 
     virtual void take_pending_events_from(CEventLoop& other) override
     virtual void take_pending_events_from(CEventLoop& other) override
     {
     {
@@ -59,6 +60,7 @@ private:
     void handle_menu_event(const WSAPI_ServerMessage&);
     void handle_menu_event(const WSAPI_ServerMessage&);
     void handle_window_entered_or_left_event(const WSAPI_ServerMessage&, GWindow&);
     void handle_window_entered_or_left_event(const WSAPI_ServerMessage&, GWindow&);
     void handle_wm_event(const WSAPI_ServerMessage&, GWindow&);
     void handle_wm_event(const WSAPI_ServerMessage&, GWindow&);
+    void handle_greeting(WSAPI_ServerMessage&);
     void connect_to_server();
     void connect_to_server();
 
 
     struct IncomingWSMessageBundle {
     struct IncomingWSMessageBundle {
@@ -68,5 +70,6 @@ private:
 
 
     Vector<IncomingWSMessageBundle, 64> m_unprocessed_bundles;
     Vector<IncomingWSMessageBundle, 64> m_unprocessed_bundles;
     static pid_t s_server_pid;
     static pid_t s_server_pid;
-    static pid_t s_event_fd;
+    static int s_my_client_id;
+    static int s_event_fd;
 };
 };

+ 46 - 0
LibGUI/GResizeCorner.cpp

@@ -0,0 +1,46 @@
+#include <LibGUI/GResizeCorner.h>
+#include <LibGUI/GPainter.h>
+#include <LibGUI/GWindow.h>
+#include <SharedGraphics/GraphicsBitmap.h>
+#include <WindowServer/WSAPITypes.h>
+
+GResizeCorner::GResizeCorner(GWidget* parent)
+    : GWidget(parent)
+{
+    set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
+    set_preferred_size({ 16, 16 });
+    m_bitmap = GraphicsBitmap::load_from_file("/res/icons/resize-corner.png");
+    ASSERT(m_bitmap);
+}
+
+GResizeCorner::~GResizeCorner()
+{
+}
+
+void GResizeCorner::paint_event(GPaintEvent& event)
+{
+    GPainter painter(*this);
+    painter.add_clip_rect(event.rect());
+    painter.fill_rect(rect(), background_color());
+    painter.blit({ 0, 0 }, *m_bitmap, m_bitmap->rect());
+    GWidget::paint_event(event);
+}
+
+void GResizeCorner::mousedown_event(GMouseEvent& event)
+{
+    if (event.button() == GMouseButton::Left)
+        window()->start_wm_resize();
+    GWidget::mousedown_event(event);
+}
+
+void GResizeCorner::enter_event(CEvent& event)
+{
+    window()->set_override_cursor(GStandardCursor::ResizeDiagonalTLBR);
+    GWidget::enter_event(event);
+}
+
+void GResizeCorner::leave_event(CEvent& event)
+{
+    window()->set_override_cursor(GStandardCursor::None);
+    GWidget::leave_event(event);
+}

+ 18 - 0
LibGUI/GResizeCorner.h

@@ -0,0 +1,18 @@
+#include <LibGUI/GWidget.h>
+
+class GResizeCorner : public GWidget {
+public:
+    explicit GResizeCorner(GWidget* parent);
+    virtual ~GResizeCorner() override;
+
+    virtual const char* class_name() const override { return "GResizeCorner"; }
+
+protected:
+    virtual void paint_event(GPaintEvent&) override;
+    virtual void mousedown_event(GMouseEvent&) override;
+    virtual void enter_event(CEvent&) override;
+    virtual void leave_event(CEvent&) override;
+
+private:
+    RetainPtr<GraphicsBitmap> m_bitmap;
+};

+ 3 - 0
LibGUI/GStatusBar.cpp

@@ -3,6 +3,7 @@
 #include <LibGUI/GBoxLayout.h>
 #include <LibGUI/GBoxLayout.h>
 #include <SharedGraphics/StylePainter.h>
 #include <SharedGraphics/StylePainter.h>
 #include <LibGUI/GPainter.h>
 #include <LibGUI/GPainter.h>
+#include <LibGUI/GResizeCorner.h>
 
 
 GStatusBar::GStatusBar(GWidget* parent)
 GStatusBar::GStatusBar(GWidget* parent)
     : GWidget(parent)
     : GWidget(parent)
@@ -17,6 +18,8 @@ GStatusBar::GStatusBar(GWidget* parent)
     m_label->set_frame_shape(FrameShape::Panel);
     m_label->set_frame_shape(FrameShape::Panel);
     m_label->set_frame_thickness(1);
     m_label->set_frame_thickness(1);
     m_label->set_text_alignment(TextAlignment::CenterLeft);
     m_label->set_text_alignment(TextAlignment::CenterLeft);
+
+    m_corner = new GResizeCorner(this);
 }
 }
 
 
 GStatusBar::~GStatusBar()
 GStatusBar::~GStatusBar()

+ 2 - 0
LibGUI/GStatusBar.h

@@ -3,6 +3,7 @@
 #include <LibGUI/GWidget.h>
 #include <LibGUI/GWidget.h>
 
 
 class GLabel;
 class GLabel;
+class GResizeCorner;
 
 
 class GStatusBar : public GWidget {
 class GStatusBar : public GWidget {
 public:
 public:
@@ -18,4 +19,5 @@ private:
     virtual void paint_event(GPaintEvent&) override;
     virtual void paint_event(GPaintEvent&) override;
 
 
     GLabel* m_label { nullptr };
     GLabel* m_label { nullptr };
+    GResizeCorner* m_corner { nullptr };
 };
 };

+ 9 - 0
LibGUI/GWindow.cpp

@@ -490,3 +490,12 @@ void GWindow::set_icon_path(const String& path)
     message.text_length = path.length();
     message.text_length = path.length();
     GEventLoop::post_message_to_server(message);
     GEventLoop::post_message_to_server(message);
 }
 }
+
+void GWindow::start_wm_resize()
+{
+    WSAPI_ClientMessage message;
+    message.type = WSAPI_ClientMessage::Type::WM_StartWindowResize;
+    message.wm.client_id = GEventLoop::my_client_id();
+    message.wm.window_id = m_window_id;
+    GEventLoop::post_message_to_server(message);
+}

+ 4 - 0
LibGUI/GWindow.h

@@ -16,6 +16,8 @@ enum class GStandardCursor {
     IBeam,
     IBeam,
     ResizeHorizontal,
     ResizeHorizontal,
     ResizeVertical,
     ResizeVertical,
+    ResizeDiagonalTLBR,
+    ResizeDiagonalBLTR,
 };
 };
 
 
 class GWindow : public CObject {
 class GWindow : public CObject {
@@ -71,6 +73,8 @@ public:
     void hide();
     void hide();
     void close();
     void close();
 
 
+    void start_wm_resize();
+
     GWidget* main_widget() { return m_main_widget; }
     GWidget* main_widget() { return m_main_widget; }
     const GWidget* main_widget() const { return m_main_widget; }
     const GWidget* main_widget() const { return m_main_widget; }
     void set_main_widget(GWidget*);
     void set_main_widget(GWidget*);

+ 1 - 0
LibGUI/Makefile

@@ -53,6 +53,7 @@ LIBGUI_OBJS = \
     GSpinBox.o \
     GSpinBox.o \
     GGroupBox.o \
     GGroupBox.o \
     GSlider.o \
     GSlider.o \
+    GResizeCorner.o \
     GWindow.o
     GWindow.o
 
 
 OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)
 OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)

+ 4 - 0
Servers/WindowServer/WSAPITypes.h

@@ -55,6 +55,8 @@ enum class WSAPI_StandardCursor : unsigned char {
     IBeam,
     IBeam,
     ResizeHorizontal,
     ResizeHorizontal,
     ResizeVertical,
     ResizeVertical,
+    ResizeDiagonalTLBR,
+    ResizeDiagonalBLTR,
 };
 };
 
 
 enum WSAPI_WMEventMask : unsigned {
 enum WSAPI_WMEventMask : unsigned {
@@ -126,6 +128,7 @@ struct WSAPI_ServerMessage {
     union {
     union {
         struct {
         struct {
             int server_pid;
             int server_pid;
+            int your_client_id;
             WSAPI_Rect screen_rect;
             WSAPI_Rect screen_rect;
         } greeting;
         } greeting;
         struct {
         struct {
@@ -211,6 +214,7 @@ struct WSAPI_ClientMessage {
         SetWindowOverrideCursor,
         SetWindowOverrideCursor,
         WM_SetActiveWindow,
         WM_SetActiveWindow,
         WM_SetWindowMinimized,
         WM_SetWindowMinimized,
+        WM_StartWindowResize,
         PopupMenu,
         PopupMenu,
         DismissMenu,
         DismissMenu,
         SetWindowIcon,
         SetWindowIcon,

+ 21 - 0
Servers/WindowServer/WSClientConnection.cpp

@@ -48,6 +48,7 @@ WSClientConnection::WSClientConnection(int fd)
     WSAPI_ServerMessage message;
     WSAPI_ServerMessage message;
     message.type = WSAPI_ServerMessage::Type::Greeting;
     message.type = WSAPI_ServerMessage::Type::Greeting;
     message.greeting.server_pid = getpid();
     message.greeting.server_pid = getpid();
+    message.greeting.your_client_id = m_client_id;
     message.greeting.screen_rect = WSScreen::the().rect();
     message.greeting.screen_rect = WSScreen::the().rect();
     post_message(message);
     post_message(message);
 }
 }
@@ -645,6 +646,24 @@ void WSClientConnection::handle_request(const WSWMAPISetActiveWindowRequest& req
     WSWindowManager::the().move_to_front_and_make_active(window);
     WSWindowManager::the().move_to_front_and_make_active(window);
 }
 }
 
 
+void WSClientConnection::handle_request(const WSWMAPIStartWindowResizeRequest& request)
+{
+    auto* client = WSClientConnection::from_client_id(request.target_client_id());
+    if (!client) {
+        post_error("WSWMAPIStartWindowResizeRequest: Bad client ID");
+        return;
+    }
+    auto it = client->m_windows.find(request.target_window_id());
+    if (it == client->m_windows.end()) {
+        post_error("WSWMAPIStartWindowResizeRequest: Bad window ID");
+        return;
+    }
+    auto& window = *(*it).value;
+    // FIXME: We are cheating a bit here by using the current cursor location and hard-coding the left button.
+    //        Maybe the client should be allowed to specify what initiated this request?
+    WSWindowManager::the().start_window_resize(window, WSScreen::the().cursor_location(), MouseButton::Left);
+}
+
 void WSClientConnection::handle_request(const WSWMAPISetWindowMinimizedRequest& request)
 void WSClientConnection::handle_request(const WSWMAPISetWindowMinimizedRequest& request)
 {
 {
     auto* client = WSClientConnection::from_client_id(request.target_client_id());
     auto* client = WSClientConnection::from_client_id(request.target_client_id());
@@ -722,6 +741,8 @@ void WSClientConnection::on_request(const WSAPIClientRequest& request)
         return handle_request(static_cast<const WSWMAPISetActiveWindowRequest&>(request));
         return handle_request(static_cast<const WSWMAPISetActiveWindowRequest&>(request));
     case WSEvent::WMAPISetWindowMinimizedRequest:
     case WSEvent::WMAPISetWindowMinimizedRequest:
         return handle_request(static_cast<const WSWMAPISetWindowMinimizedRequest&>(request));
         return handle_request(static_cast<const WSWMAPISetWindowMinimizedRequest&>(request));
+    case WSEvent::WMAPIStartWindowResizeRequest:
+        return handle_request(static_cast<const WSWMAPIStartWindowResizeRequest&>(request));
     case WSEvent::APIPopupMenuRequest:
     case WSEvent::APIPopupMenuRequest:
         return handle_request(static_cast<const WSAPIPopupMenuRequest&>(request));
         return handle_request(static_cast<const WSAPIPopupMenuRequest&>(request));
     case WSEvent::APIDismissMenuRequest:
     case WSEvent::APIDismissMenuRequest:

+ 1 - 0
Servers/WindowServer/WSClientConnection.h

@@ -74,6 +74,7 @@ private:
     void handle_request(const WSAPISetWindowOverrideCursorRequest&);
     void handle_request(const WSAPISetWindowOverrideCursorRequest&);
     void handle_request(const WSWMAPISetActiveWindowRequest&);
     void handle_request(const WSWMAPISetActiveWindowRequest&);
     void handle_request(const WSWMAPISetWindowMinimizedRequest&);
     void handle_request(const WSWMAPISetWindowMinimizedRequest&);
+    void handle_request(const WSWMAPIStartWindowResizeRequest&);
     void handle_request(const WSAPIPopupMenuRequest&);
     void handle_request(const WSAPIPopupMenuRequest&);
     void handle_request(const WSAPIDismissMenuRequest&);
     void handle_request(const WSAPIDismissMenuRequest&);
 
 

+ 4 - 0
Servers/WindowServer/WSCursor.cpp

@@ -34,6 +34,10 @@ RetainPtr<WSCursor> WSCursor::create(WSStandardCursor standard_cursor)
         return WSWindowManager::the().resize_horizontally_cursor();
         return WSWindowManager::the().resize_horizontally_cursor();
     case WSStandardCursor::ResizeVertical:
     case WSStandardCursor::ResizeVertical:
         return WSWindowManager::the().resize_vertically_cursor();
         return WSWindowManager::the().resize_vertically_cursor();
+    case WSStandardCursor::ResizeDiagonalTLBR:
+        return WSWindowManager::the().resize_diagonally_tlbr_cursor();
+    case WSStandardCursor::ResizeDiagonalBLTR:
+        return WSWindowManager::the().resize_diagonally_bltr_cursor();
     }
     }
     ASSERT_NOT_REACHED();
     ASSERT_NOT_REACHED();
 }
 }

+ 2 - 0
Servers/WindowServer/WSCursor.h

@@ -8,6 +8,8 @@ enum class WSStandardCursor {
     IBeam,
     IBeam,
     ResizeHorizontal,
     ResizeHorizontal,
     ResizeVertical,
     ResizeVertical,
+    ResizeDiagonalTLBR,
+    ResizeDiagonalBLTR,
 };
 };
 
 
 class WSCursor : public Retainable<WSCursor> {
 class WSCursor : public Retainable<WSCursor> {

+ 18 - 0
Servers/WindowServer/WSEvent.h

@@ -62,6 +62,7 @@ public:
         APISetWindowOverrideCursorRequest,
         APISetWindowOverrideCursorRequest,
         WMAPISetActiveWindowRequest,
         WMAPISetActiveWindowRequest,
         WMAPISetWindowMinimizedRequest,
         WMAPISetWindowMinimizedRequest,
+        WMAPIStartWindowResizeRequest,
         APIPopupMenuRequest,
         APIPopupMenuRequest,
         APIDismissMenuRequest,
         APIDismissMenuRequest,
         __End_API_Client_Requests,
         __End_API_Client_Requests,
@@ -104,6 +105,23 @@ private:
     int m_client_id { 0 };
     int m_client_id { 0 };
 };
 };
 
 
+class WSWMAPIStartWindowResizeRequest : public WSAPIClientRequest {
+public:
+    WSWMAPIStartWindowResizeRequest(int client_id, int target_client_id, int target_window_id)
+        : WSAPIClientRequest(WSEvent::WMAPIStartWindowResizeRequest, client_id)
+        , m_target_client_id(target_client_id)
+        , m_target_window_id(target_window_id)
+    {
+    }
+
+    int target_client_id() const { return m_target_client_id; }
+    int target_window_id() const { return m_target_window_id; }
+
+private:
+    int m_target_client_id;
+    int m_target_window_id;
+};
+
 class WSWMAPISetActiveWindowRequest : public WSAPIClientRequest {
 class WSWMAPISetActiveWindowRequest : public WSAPIClientRequest {
 public:
 public:
     WSWMAPISetActiveWindowRequest(int client_id, int target_client_id, int target_window_id)
     WSWMAPISetActiveWindowRequest(int client_id, int target_client_id, int target_window_id)

+ 3 - 0
Servers/WindowServer/WSEventLoop.cpp

@@ -250,6 +250,9 @@ bool WSEventLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessag
     case WSAPI_ClientMessage::Type::WM_SetWindowMinimized:
     case WSAPI_ClientMessage::Type::WM_SetWindowMinimized:
         post_event(client, make<WSWMAPISetWindowMinimizedRequest>(client_id, message.wm.client_id, message.wm.window_id, message.wm.minimized));
         post_event(client, make<WSWMAPISetWindowMinimizedRequest>(client_id, message.wm.client_id, message.wm.window_id, message.wm.minimized));
         break;
         break;
+    case WSAPI_ClientMessage::Type::WM_StartWindowResize:
+        post_event(client, make<WSWMAPIStartWindowResizeRequest>(client_id, message.wm.client_id, message.wm.window_id));
+        break;
     default:
     default:
         break;
         break;
     }
     }

+ 33 - 17
Servers/WindowServer/WSWindowManager.cpp

@@ -490,7 +490,7 @@ void WSWindowManager::start_window_drag(WSWindow& window, const WSMouseEvent& ev
     invalidate(window);
     invalidate(window);
 }
 }
 
 
-void WSWindowManager::start_window_resize(WSWindow& window, const WSMouseEvent& event)
+void WSWindowManager::start_window_resize(WSWindow& window, const Point& position, MouseButton button)
 {
 {
     move_to_front_and_make_active(window);
     move_to_front_and_make_active(window);
     constexpr ResizeDirection direction_for_hot_area[3][3] = {
     constexpr ResizeDirection direction_for_hot_area[3][3] = {
@@ -499,9 +499,9 @@ void WSWindowManager::start_window_resize(WSWindow& window, const WSMouseEvent&
         { ResizeDirection::DownLeft, ResizeDirection::Down, ResizeDirection::DownRight },
         { ResizeDirection::DownLeft, ResizeDirection::Down, ResizeDirection::DownRight },
     };
     };
     Rect outer_rect = window.frame().rect();
     Rect outer_rect = window.frame().rect();
-    ASSERT(outer_rect.contains(event.position()));
-    int window_relative_x = event.x() - outer_rect.x();
-    int window_relative_y = event.y() - outer_rect.y();
+    ASSERT(outer_rect.contains(position));
+    int window_relative_x = position.x() - outer_rect.x();
+    int window_relative_y = position.y() - outer_rect.y();
     int hot_area_row = min(2, window_relative_y / (outer_rect.height() / 3));
     int hot_area_row = min(2, window_relative_y / (outer_rect.height() / 3));
     int hot_area_column = min(2, window_relative_x / (outer_rect.width() / 3));
     int hot_area_column = min(2, window_relative_x / (outer_rect.width() / 3));
     m_resize_direction = direction_for_hot_area[hot_area_row][hot_area_column];
     m_resize_direction = direction_for_hot_area[hot_area_row][hot_area_column];
@@ -513,15 +513,20 @@ void WSWindowManager::start_window_resize(WSWindow& window, const WSMouseEvent&
 #ifdef RESIZE_DEBUG
 #ifdef RESIZE_DEBUG
     printf("[WM] Begin resizing WSWindow{%p}\n", &window);
     printf("[WM] Begin resizing WSWindow{%p}\n", &window);
 #endif
 #endif
-    m_resizing_mouse_button = event.button();
+    m_resizing_mouse_button = button;
     m_resize_window = window.make_weak_ptr();;
     m_resize_window = window.make_weak_ptr();;
-    m_resize_origin = event.position();
+    m_resize_origin = position;
     m_resize_window_original_rect = window.rect();
     m_resize_window_original_rect = window.rect();
 
 
     invalidate(window);
     invalidate(window);
 }
 }
 
 
-bool WSWindowManager::process_ongoing_window_drag(const WSMouseEvent& event, WSWindow*&)
+void WSWindowManager::start_window_resize(WSWindow& window, const WSMouseEvent& event)
+{
+    start_window_resize(window, event.position(), event.button());
+}
+
+bool WSWindowManager::process_ongoing_window_drag(const WSMouseEvent& event, WSWindow*& hovered_window)
 {
 {
     if (!m_drag_window)
     if (!m_drag_window)
         return false;
         return false;
@@ -530,6 +535,8 @@ bool WSWindowManager::process_ongoing_window_drag(const WSMouseEvent& event, WSW
         printf("[WM] Finish dragging WSWindow{%p}\n", m_drag_window.ptr());
         printf("[WM] Finish dragging WSWindow{%p}\n", m_drag_window.ptr());
 #endif
 #endif
         invalidate(*m_drag_window);
         invalidate(*m_drag_window);
+        if (m_drag_window->rect().contains(event.position()))
+            hovered_window = m_drag_window;
         m_drag_window = nullptr;
         m_drag_window = nullptr;
         return true;
         return true;
     }
     }
@@ -539,12 +546,14 @@ bool WSWindowManager::process_ongoing_window_drag(const WSMouseEvent& event, WSW
 #endif
 #endif
         Point pos = m_drag_window_origin.translated(event.position() - m_drag_origin);
         Point pos = m_drag_window_origin.translated(event.position() - m_drag_origin);
         m_drag_window->set_position_without_repaint(pos);
         m_drag_window->set_position_without_repaint(pos);
+        if (m_drag_window->rect().contains(event.position()))
+            hovered_window = m_drag_window;
         return true;
         return true;
     }
     }
     return false;
     return false;
 }
 }
 
 
-bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, WSWindow*&)
+bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, WSWindow*& hovered_window)
 {
 {
     if (!m_resize_window)
     if (!m_resize_window)
         return false;
         return false;
@@ -555,6 +564,8 @@ bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, W
 #endif
 #endif
         WSEventLoop::the().post_event(*m_resize_window, make<WSResizeEvent>(m_resize_window->rect(), m_resize_window->rect()));
         WSEventLoop::the().post_event(*m_resize_window, make<WSResizeEvent>(m_resize_window->rect(), m_resize_window->rect()));
         invalidate(*m_resize_window);
         invalidate(*m_resize_window);
+        if (m_resize_window->rect().contains(event.position()))
+            hovered_window = m_resize_window;
         m_resize_window = nullptr;
         m_resize_window = nullptr;
         m_resizing_mouse_button = MouseButton::None;
         m_resizing_mouse_button = MouseButton::None;
         return true;
         return true;
@@ -627,6 +638,9 @@ bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, W
         new_rect.set_height(m_resize_window->base_size().height() + vertical_incs * m_resize_window->size_increment().height());
         new_rect.set_height(m_resize_window->base_size().height() + vertical_incs * m_resize_window->size_increment().height());
     }
     }
 
 
+    if (new_rect.contains(event.position()))
+        hovered_window = m_resize_window;
+
     if (m_resize_window->rect() == new_rect)
     if (m_resize_window->rect() == new_rect)
         return true;
         return true;
 #ifdef RESIZE_DEBUG
 #ifdef RESIZE_DEBUG
@@ -644,14 +658,14 @@ void WSWindowManager::set_cursor_tracking_button(WSButton* button)
     m_cursor_tracking_button = button ? button->make_weak_ptr() : nullptr;
     m_cursor_tracking_button = button ? button->make_weak_ptr() : nullptr;
 }
 }
 
 
-void WSWindowManager::process_mouse_event(const WSMouseEvent& event, WSWindow*& event_window)
+void WSWindowManager::process_mouse_event(const WSMouseEvent& event, WSWindow*& hovered_window)
 {
 {
-    event_window = nullptr;
+    hovered_window = nullptr;
 
 
-    if (process_ongoing_window_drag(event, event_window))
+    if (process_ongoing_window_drag(event, hovered_window))
         return;
         return;
 
 
-    if (process_ongoing_window_resize(event, event_window))
+    if (process_ongoing_window_resize(event, hovered_window))
         return;
         return;
 
 
     if (m_cursor_tracking_button)
     if (m_cursor_tracking_button)
@@ -687,7 +701,7 @@ void WSWindowManager::process_mouse_event(const WSMouseEvent& event, WSWindow*&
             if (event.type() == WSEvent::MouseDown || event.type() == WSEvent::MouseUp)
             if (event.type() == WSEvent::MouseDown || event.type() == WSEvent::MouseUp)
                 close_current_menu();
                 close_current_menu();
         } else {
         } else {
-            event_window = &window;
+            hovered_window = &window;
             auto translated_event = event.translated(-window.position());
             auto translated_event = event.translated(-window.position());
             window.event(translated_event);
             window.event(translated_event);
         }
         }
@@ -708,10 +722,12 @@ void WSWindowManager::process_mouse_event(const WSMouseEvent& event, WSWindow*&
         // In those cases, the event is swallowed by the window manager.
         // In those cases, the event is swallowed by the window manager.
         if (window.type() == WSWindowType::Normal) {
         if (window.type() == WSWindowType::Normal) {
             if (m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) {
             if (m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) {
+                hovered_window = &window;
                 start_window_drag(window, event);
                 start_window_drag(window, event);
                 return IterationDecision::Abort;
                 return IterationDecision::Abort;
             }
             }
             if (window.is_resizable() && m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Right && !window.is_blocked_by_modal_window()) {
             if (window.is_resizable() && m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Right && !window.is_blocked_by_modal_window()) {
+                hovered_window = &window;
                 start_window_resize(window, event);
                 start_window_resize(window, event);
                 return IterationDecision::Abort;
                 return IterationDecision::Abort;
             }
             }
@@ -720,7 +736,7 @@ void WSWindowManager::process_mouse_event(const WSMouseEvent& event, WSWindow*&
         if (window.rect().contains(event.position())) {
         if (window.rect().contains(event.position())) {
             if (window.type() == WSWindowType::Normal && event.type() == WSEvent::MouseDown)
             if (window.type() == WSWindowType::Normal && event.type() == WSEvent::MouseDown)
                 move_to_front_and_make_active(window);
                 move_to_front_and_make_active(window);
-            event_window = &window;
+            hovered_window = &window;
             if (!window.global_cursor_tracking() && !windows_who_received_mouse_event_due_to_cursor_tracking.contains(&window)) {
             if (!window.global_cursor_tracking() && !windows_who_received_mouse_event_due_to_cursor_tracking.contains(&window)) {
                 auto translated_event = event.translated(-window.position());
                 auto translated_event = event.translated(-window.position());
                 window.event(translated_event);
                 window.event(translated_event);
@@ -987,9 +1003,9 @@ void WSWindowManager::draw_cursor()
 void WSWindowManager::event(CEvent& event)
 void WSWindowManager::event(CEvent& event)
 {
 {
     if (static_cast<WSEvent&>(event).is_mouse_event()) {
     if (static_cast<WSEvent&>(event).is_mouse_event()) {
-        WSWindow* event_window = nullptr;
-        process_mouse_event(static_cast<const WSMouseEvent&>(event), event_window);
-        set_hovered_window(event_window);
+        WSWindow* hovered_window = nullptr;
+        process_mouse_event(static_cast<const WSMouseEvent&>(event), hovered_window);
+        set_hovered_window(hovered_window);
         return;
         return;
     }
     }
 
 

+ 6 - 4
Servers/WindowServer/WSWindowManager.h

@@ -116,14 +116,16 @@ public:
     void tell_wm_listeners_window_icon_changed(WSWindow&);
     void tell_wm_listeners_window_icon_changed(WSWindow&);
     void tell_wm_listeners_window_rect_changed(WSWindow&);
     void tell_wm_listeners_window_rect_changed(WSWindow&);
 
 
+    void start_window_resize(WSWindow&, const Point&, MouseButton);
+    void start_window_resize(WSWindow&, const WSMouseEvent&);
+
 private:
 private:
-    void process_mouse_event(const WSMouseEvent&, WSWindow*& event_window);
-    bool process_ongoing_window_resize(const WSMouseEvent&, WSWindow*& event_window);
-    bool process_ongoing_window_drag(const WSMouseEvent&, WSWindow*& event_window);
+    void process_mouse_event(const WSMouseEvent&, WSWindow*& hovered_window);
+    bool process_ongoing_window_resize(const WSMouseEvent&, WSWindow*& hovered_window);
+    bool process_ongoing_window_drag(const WSMouseEvent&, WSWindow*& hovered_window);
     void handle_menu_mouse_event(WSMenu&, const WSMouseEvent&);
     void handle_menu_mouse_event(WSMenu&, const WSMouseEvent&);
     void handle_menubar_mouse_event(const WSMouseEvent&);
     void handle_menubar_mouse_event(const WSMouseEvent&);
     void handle_close_button_mouse_event(WSWindow&, const WSMouseEvent&);
     void handle_close_button_mouse_event(WSWindow&, const WSMouseEvent&);
-    void start_window_resize(WSWindow&, const WSMouseEvent&);
     void start_window_drag(WSWindow&, const WSMouseEvent&);
     void start_window_drag(WSWindow&, const WSMouseEvent&);
     void handle_client_request(const WSAPIClientRequest&);
     void handle_client_request(const WSAPIClientRequest&);
     void set_hovered_window(WSWindow*);
     void set_hovered_window(WSWindow*);