mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 05:32:44 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									34c5db61aa
								
							
						
					
					
						commit
						ea9a39a9f2
					
				
					 19 changed files with 189 additions and 26 deletions
				
			
		
							
								
								
									
										
											BIN
										
									
								
								Base/res/icons/resize-corner.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Base/res/icons/resize-corner.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 127 B | 
|  | @ -24,6 +24,7 @@ | |||
| //#define COALESCING_DEBUG
 | ||||
| 
 | ||||
| int GEventLoop::s_event_fd = -1; | ||||
| int GEventLoop::s_my_client_id = -1; | ||||
| pid_t GEventLoop::s_server_pid = -1; | ||||
| 
 | ||||
| void GEventLoop::connect_to_server() | ||||
|  | @ -59,8 +60,7 @@ void GEventLoop::connect_to_server() | |||
|     request.type = WSAPI_ClientMessage::Type::Greeting; | ||||
|     request.greeting.client_pid = getpid(); | ||||
|     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() | ||||
|  | @ -235,8 +235,7 @@ void GEventLoop::process_unprocessed_bundles() | |||
|     for (auto& bundle : unprocessed_bundles) { | ||||
|         auto& event = bundle.message; | ||||
|         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; | ||||
|         } | ||||
| 
 | ||||
|  | @ -402,3 +401,10 @@ WSAPI_ServerMessage GEventLoop::sync_request(const WSAPI_ClientMessage& request, | |||
|     ASSERT(success); | ||||
|     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); | ||||
| } | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ public: | |||
|     WSAPI_ServerMessage sync_request(const WSAPI_ClientMessage& request, WSAPI_ServerMessage::Type response_type); | ||||
| 
 | ||||
|     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 | ||||
|     { | ||||
|  | @ -59,6 +60,7 @@ private: | |||
|     void handle_menu_event(const WSAPI_ServerMessage&); | ||||
|     void handle_window_entered_or_left_event(const WSAPI_ServerMessage&, GWindow&); | ||||
|     void handle_wm_event(const WSAPI_ServerMessage&, GWindow&); | ||||
|     void handle_greeting(WSAPI_ServerMessage&); | ||||
|     void connect_to_server(); | ||||
| 
 | ||||
|     struct IncomingWSMessageBundle { | ||||
|  | @ -68,5 +70,6 @@ private: | |||
| 
 | ||||
|     Vector<IncomingWSMessageBundle, 64> m_unprocessed_bundles; | ||||
|     static pid_t s_server_pid; | ||||
|     static pid_t s_event_fd; | ||||
|     static int s_my_client_id; | ||||
|     static int s_event_fd; | ||||
| }; | ||||
|  |  | |||
							
								
								
									
										46
									
								
								LibGUI/GResizeCorner.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								LibGUI/GResizeCorner.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
									
								
								LibGUI/GResizeCorner.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								LibGUI/GResizeCorner.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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,6 +3,7 @@ | |||
| #include <LibGUI/GBoxLayout.h> | ||||
| #include <SharedGraphics/StylePainter.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
| #include <LibGUI/GResizeCorner.h> | ||||
| 
 | ||||
| GStatusBar::GStatusBar(GWidget* parent) | ||||
|     : GWidget(parent) | ||||
|  | @ -17,6 +18,8 @@ GStatusBar::GStatusBar(GWidget* parent) | |||
|     m_label->set_frame_shape(FrameShape::Panel); | ||||
|     m_label->set_frame_thickness(1); | ||||
|     m_label->set_text_alignment(TextAlignment::CenterLeft); | ||||
| 
 | ||||
|     m_corner = new GResizeCorner(this); | ||||
| } | ||||
| 
 | ||||
| GStatusBar::~GStatusBar() | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| #include <LibGUI/GWidget.h> | ||||
| 
 | ||||
| class GLabel; | ||||
| class GResizeCorner; | ||||
| 
 | ||||
| class GStatusBar : public GWidget { | ||||
| public: | ||||
|  | @ -18,4 +19,5 @@ private: | |||
|     virtual void paint_event(GPaintEvent&) override; | ||||
| 
 | ||||
|     GLabel* m_label { nullptr }; | ||||
|     GResizeCorner* m_corner { nullptr }; | ||||
| }; | ||||
|  |  | |||
|  | @ -490,3 +490,12 @@ void GWindow::set_icon_path(const String& path) | |||
|     message.text_length = path.length(); | ||||
|     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); | ||||
| } | ||||
|  |  | |||
|  | @ -16,6 +16,8 @@ enum class GStandardCursor { | |||
|     IBeam, | ||||
|     ResizeHorizontal, | ||||
|     ResizeVertical, | ||||
|     ResizeDiagonalTLBR, | ||||
|     ResizeDiagonalBLTR, | ||||
| }; | ||||
| 
 | ||||
| class GWindow : public CObject { | ||||
|  | @ -71,6 +73,8 @@ public: | |||
|     void hide(); | ||||
|     void close(); | ||||
| 
 | ||||
|     void start_wm_resize(); | ||||
| 
 | ||||
|     GWidget* main_widget() { return m_main_widget; } | ||||
|     const GWidget* main_widget() const { return m_main_widget; } | ||||
|     void set_main_widget(GWidget*); | ||||
|  |  | |||
|  | @ -53,6 +53,7 @@ LIBGUI_OBJS = \ | |||
|     GSpinBox.o \
 | ||||
|     GGroupBox.o \
 | ||||
|     GSlider.o \
 | ||||
|     GResizeCorner.o \
 | ||||
|     GWindow.o | ||||
| 
 | ||||
| OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS) | ||||
|  |  | |||
|  | @ -55,6 +55,8 @@ enum class WSAPI_StandardCursor : unsigned char { | |||
|     IBeam, | ||||
|     ResizeHorizontal, | ||||
|     ResizeVertical, | ||||
|     ResizeDiagonalTLBR, | ||||
|     ResizeDiagonalBLTR, | ||||
| }; | ||||
| 
 | ||||
| enum WSAPI_WMEventMask : unsigned { | ||||
|  | @ -126,6 +128,7 @@ struct WSAPI_ServerMessage { | |||
|     union { | ||||
|         struct { | ||||
|             int server_pid; | ||||
|             int your_client_id; | ||||
|             WSAPI_Rect screen_rect; | ||||
|         } greeting; | ||||
|         struct { | ||||
|  | @ -211,6 +214,7 @@ struct WSAPI_ClientMessage { | |||
|         SetWindowOverrideCursor, | ||||
|         WM_SetActiveWindow, | ||||
|         WM_SetWindowMinimized, | ||||
|         WM_StartWindowResize, | ||||
|         PopupMenu, | ||||
|         DismissMenu, | ||||
|         SetWindowIcon, | ||||
|  |  | |||
|  | @ -48,6 +48,7 @@ WSClientConnection::WSClientConnection(int fd) | |||
|     WSAPI_ServerMessage message; | ||||
|     message.type = WSAPI_ServerMessage::Type::Greeting; | ||||
|     message.greeting.server_pid = getpid(); | ||||
|     message.greeting.your_client_id = m_client_id; | ||||
|     message.greeting.screen_rect = WSScreen::the().rect(); | ||||
|     post_message(message); | ||||
| } | ||||
|  | @ -645,6 +646,24 @@ void WSClientConnection::handle_request(const WSWMAPISetActiveWindowRequest& req | |||
|     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) | ||||
| { | ||||
|     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)); | ||||
|     case WSEvent::WMAPISetWindowMinimizedRequest: | ||||
|         return handle_request(static_cast<const WSWMAPISetWindowMinimizedRequest&>(request)); | ||||
|     case WSEvent::WMAPIStartWindowResizeRequest: | ||||
|         return handle_request(static_cast<const WSWMAPIStartWindowResizeRequest&>(request)); | ||||
|     case WSEvent::APIPopupMenuRequest: | ||||
|         return handle_request(static_cast<const WSAPIPopupMenuRequest&>(request)); | ||||
|     case WSEvent::APIDismissMenuRequest: | ||||
|  |  | |||
|  | @ -74,6 +74,7 @@ private: | |||
|     void handle_request(const WSAPISetWindowOverrideCursorRequest&); | ||||
|     void handle_request(const WSWMAPISetActiveWindowRequest&); | ||||
|     void handle_request(const WSWMAPISetWindowMinimizedRequest&); | ||||
|     void handle_request(const WSWMAPIStartWindowResizeRequest&); | ||||
|     void handle_request(const WSAPIPopupMenuRequest&); | ||||
|     void handle_request(const WSAPIDismissMenuRequest&); | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,6 +34,10 @@ RetainPtr<WSCursor> WSCursor::create(WSStandardCursor standard_cursor) | |||
|         return WSWindowManager::the().resize_horizontally_cursor(); | ||||
|     case WSStandardCursor::ResizeVertical: | ||||
|         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(); | ||||
| } | ||||
|  |  | |||
|  | @ -8,6 +8,8 @@ enum class WSStandardCursor { | |||
|     IBeam, | ||||
|     ResizeHorizontal, | ||||
|     ResizeVertical, | ||||
|     ResizeDiagonalTLBR, | ||||
|     ResizeDiagonalBLTR, | ||||
| }; | ||||
| 
 | ||||
| class WSCursor : public Retainable<WSCursor> { | ||||
|  |  | |||
|  | @ -62,6 +62,7 @@ public: | |||
|         APISetWindowOverrideCursorRequest, | ||||
|         WMAPISetActiveWindowRequest, | ||||
|         WMAPISetWindowMinimizedRequest, | ||||
|         WMAPIStartWindowResizeRequest, | ||||
|         APIPopupMenuRequest, | ||||
|         APIDismissMenuRequest, | ||||
|         __End_API_Client_Requests, | ||||
|  | @ -104,6 +105,23 @@ private: | |||
|     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 { | ||||
| public: | ||||
|     WSWMAPISetActiveWindowRequest(int client_id, int target_client_id, int target_window_id) | ||||
|  |  | |||
|  | @ -250,6 +250,9 @@ bool WSEventLoop::on_receive_from_client(int client_id, const WSAPI_ClientMessag | |||
|     case WSAPI_ClientMessage::Type::WM_SetWindowMinimized: | ||||
|         post_event(client, make<WSWMAPISetWindowMinimizedRequest>(client_id, message.wm.client_id, message.wm.window_id, message.wm.minimized)); | ||||
|         break; | ||||
|     case WSAPI_ClientMessage::Type::WM_StartWindowResize: | ||||
|         post_event(client, make<WSWMAPIStartWindowResizeRequest>(client_id, message.wm.client_id, message.wm.window_id)); | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|  |  | |||
|  | @ -490,7 +490,7 @@ void WSWindowManager::start_window_drag(WSWindow& window, const WSMouseEvent& ev | |||
|     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); | ||||
|     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 }, | ||||
|     }; | ||||
|     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_column = min(2, window_relative_x / (outer_rect.width() / 3)); | ||||
|     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 | ||||
|     printf("[WM] Begin resizing WSWindow{%p}\n", &window); | ||||
| #endif | ||||
|     m_resizing_mouse_button = event.button(); | ||||
|     m_resizing_mouse_button = button; | ||||
|     m_resize_window = window.make_weak_ptr();; | ||||
|     m_resize_origin = event.position(); | ||||
|     m_resize_origin = position; | ||||
|     m_resize_window_original_rect = window.rect(); | ||||
| 
 | ||||
|     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) | ||||
|         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()); | ||||
| #endif | ||||
|         invalidate(*m_drag_window); | ||||
|         if (m_drag_window->rect().contains(event.position())) | ||||
|             hovered_window = m_drag_window; | ||||
|         m_drag_window = nullptr; | ||||
|         return true; | ||||
|     } | ||||
|  | @ -539,12 +546,14 @@ bool WSWindowManager::process_ongoing_window_drag(const WSMouseEvent& event, WSW | |||
| #endif | ||||
|         Point pos = m_drag_window_origin.translated(event.position() - m_drag_origin); | ||||
|         m_drag_window->set_position_without_repaint(pos); | ||||
|         if (m_drag_window->rect().contains(event.position())) | ||||
|             hovered_window = m_drag_window; | ||||
|         return true; | ||||
|     } | ||||
|     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) | ||||
|         return false; | ||||
|  | @ -555,6 +564,8 @@ bool WSWindowManager::process_ongoing_window_resize(const WSMouseEvent& event, W | |||
| #endif | ||||
|         WSEventLoop::the().post_event(*m_resize_window, make<WSResizeEvent>(m_resize_window->rect(), m_resize_window->rect())); | ||||
|         invalidate(*m_resize_window); | ||||
|         if (m_resize_window->rect().contains(event.position())) | ||||
|             hovered_window = m_resize_window; | ||||
|         m_resize_window = nullptr; | ||||
|         m_resizing_mouse_button = MouseButton::None; | ||||
|         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()); | ||||
|     } | ||||
| 
 | ||||
|     if (new_rect.contains(event.position())) | ||||
|         hovered_window = m_resize_window; | ||||
| 
 | ||||
|     if (m_resize_window->rect() == new_rect) | ||||
|         return true; | ||||
| #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; | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
| 
 | ||||
|     if (process_ongoing_window_resize(event, event_window)) | ||||
|     if (process_ongoing_window_resize(event, hovered_window)) | ||||
|         return; | ||||
| 
 | ||||
|     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) | ||||
|                 close_current_menu(); | ||||
|         } else { | ||||
|             event_window = &window; | ||||
|             hovered_window = &window; | ||||
|             auto translated_event = event.translated(-window.position()); | ||||
|             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.
 | ||||
|         if (window.type() == WSWindowType::Normal) { | ||||
|             if (m_keyboard_modifiers == Mod_Logo && event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) { | ||||
|                 hovered_window = &window; | ||||
|                 start_window_drag(window, event); | ||||
|                 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()) { | ||||
|                 hovered_window = &window; | ||||
|                 start_window_resize(window, event); | ||||
|                 return IterationDecision::Abort; | ||||
|             } | ||||
|  | @ -720,7 +736,7 @@ void WSWindowManager::process_mouse_event(const WSMouseEvent& event, WSWindow*& | |||
|         if (window.rect().contains(event.position())) { | ||||
|             if (window.type() == WSWindowType::Normal && event.type() == WSEvent::MouseDown) | ||||
|                 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)) { | ||||
|                 auto translated_event = event.translated(-window.position()); | ||||
|                 window.event(translated_event); | ||||
|  | @ -987,9 +1003,9 @@ void WSWindowManager::draw_cursor() | |||
| void WSWindowManager::event(CEvent& 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; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -116,14 +116,16 @@ public: | |||
|     void tell_wm_listeners_window_icon_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: | ||||
|     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_menubar_mouse_event(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 handle_client_request(const WSAPIClientRequest&); | ||||
|     void set_hovered_window(WSWindow*); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling