From: Thomas Debesse Date: Tue, 21 Jun 2022 01:38:14 +0000 (+0200) Subject: Merge commit 'a764616a9c1b2f9148e3381f808b600c512592c9' into master-merge X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=3e5ca8cc2ebb375e0502cb44446c633a810a5976;p=xonotic%2Fnetradiant.git Merge commit 'a764616a9c1b2f9148e3381f808b600c512592c9' into master-merge --- 3e5ca8cc2ebb375e0502cb44446c633a810a5976 diff --cc libs/gtkutil/cursor.cpp index 46f227fc,48a00187..e4d34b7d --- a/libs/gtkutil/cursor.cpp +++ b/libs/gtkutil/cursor.cpp @@@ -99,71 -72,8 +99,79 @@@ gboolean FreezePointer::motion_delta(ui self->last_y = current_y; if ( dx != 0 || dy != 0 ) { //globalOutputStream() << "motion x: " << dx << ", y: " << dy << "\n"; +#if defined(WORKAROUND_MACOS_GTK2_LAGGYPOINTER) + ui::Dimensions dimensions = widget.dimensions(); + int window_x, window_y; + int translated_x, translated_y; + + gdk_window_get_origin( gtk_widget_get_window( widget ), &window_x, &window_y); + - + translated_x = current_x - ( window_x ); + translated_y = current_y - ( window_y ); + +#if 0 + int widget_x, widget_y; + gtk_widget_translate_coordinates( GTK_WIDGET( widget ), gtk_widget_get_toplevel( GTK_WIDGET( widget ) ), 0, 0, &widget_x, &widget_y); + + globalOutputStream() + << "window_x: " << window_x + << ", window_y: " << window_y + << ", widget_x: " << widget_x + << ", widget_y: " << widget_y + << ", current x: " << current_x + << ", current_y: " << current_y + << ", translated x: " << translated_x + << ", translated_y: " << translated_y + << ", width: " << dimensions.width + << ", height: " << dimensions.height + << "\n"; +#endif + + if ( translated_x < 32 || translated_x > dimensions.width - 32 + || translated_y < 32 || translated_y > dimensions.height - 32 ) { +#if 0 + // Reposition the pointer to the widget center. + int reposition_x = window_x + dimensions.width / 2; + int reposition_y = window_y + dimensions.height / 2; +#else + // Move the pointer to the opposite side of the XY Window + // to maximize the distance that can be moved again. + int reposition_x = current_x; + int reposition_y = current_y; + + if ( translated_x < 32 ) { + reposition_x = window_x + dimensions.width - 32; + } + else if ( translated_x > dimensions.width - 32 ) { + reposition_x = window_x + 32; + } + + if ( translated_y < 32 ) { + reposition_y = window_y + dimensions.height - 32; + } + else if ( translated_y > dimensions.height - 32 ) { + reposition_y = window_y + 32; + } +#endif + + Sys_SetCursorPos( widget, reposition_x, reposition_y ); + self->last_x = reposition_x; + self->last_y = reposition_y; + } ++#else ++#if 0 // NetRadiantCustom ++ int ddx = current_x - self->center_x; ++ int ddy = current_y - self->center_y; +#else + int ddx = current_x - self->recorded_x; + int ddy = current_y - self->recorded_y; ++#endif if (ddx < -32 || ddx > 32 || ddy < -32 || ddy > 32) { ++#if 0 // NetRadiantCustom + Sys_SetCursorPos( widget, self->center_x, self->center_y ); ++#else + Sys_SetCursorPos( widget, self->recorded_x, self->recorded_y ); ++#endif self->last_x = self->recorded_x; self->last_y = self->recorded_y; } @@@ -173,25 -82,8 +181,26 @@@ return FALSE; } - // Note: NetRadiantCustom pass both parent and widget. -void FreezePointer::freeze_pointer(ui::Window window, ui::Widget widget, FreezePointer::MotionDeltaFunction function, void *data) ++/* NetRadiantCustom did this instead: ++void FreezePointer::freeze_pointer(ui::Window window, ui::Widget widget, FreezePointer::MotionDeltaFunction function, void *data) */ +void FreezePointer::freeze_pointer(ui::Widget widget, FreezePointer::MotionDeltaFunction function, void *data) { + /* FIXME: This bug can happen if the pointer goes outside of the + XY Window while the right mouse button is not released, + the XY Window loses focus and can't read the right mouse button + release event and then cannot unfreeze the pointer, meaning the + user can attempt to freeze the pointer in another XY window. + + This can happen with touch screen, especially those used to drive + virtual machine pointers, the cursor can be teleported outside of + the XY Window while maintaining pressure on the right mouse button. + This can also happen when the render is slow. + + The bug also occurs with the Camera Window. + + FIXME: It's would be possible to tell the user to save the map + at assert time before crashing because this bug does not corrupt + map saving. */ ASSERT_MESSAGE( m_function == 0, "can't freeze pointer" ); const GdkEventMask mask = static_cast( GDK_POINTER_MOTION_MASK @@@ -204,27 -96,31 +213,50 @@@ | GDK_BUTTON_RELEASE_MASK | GDK_VISIBILITY_NOTIFY_MASK ); - //GdkCursor* cursor = create_blank_cursor(); - GdkCursor* cursor = gdk_cursor_new( GDK_BLANK_CURSOR ); +#if defined(WORKAROUND_MACOS_GTK2_LAGGYPOINTER) + /* Keep the pointer visible during the move operation. + Because of a bug, it remains visible even if we give + the order to hide it anyway. + Other parts of the code assume the pointer is visible, + so make sure it is consistently visible accross + third-party updates that may fix the mouse pointer + visibility issue. */ +#else ++#if 0 // NetRadiantCustom + GdkCursor* cursor = create_blank_cursor(); //GdkGrabStatus status = + /* fixes cursor runaways during srsly quick drags in camera + drags with pressed buttons have no problem at all w/o this */ - gdk_pointer_grab( gtk_widget_get_window(window), TRUE, mask, 0, cursor, GDK_CURRENT_TIME ); ++ gdk_pointer_grab( gtk_widget_get_window( widget ), TRUE, mask, 0, cursor, GDK_CURRENT_TIME ); + //gdk_window_set_cursor ( GTK_WIDGET( window )->window, cursor ); + /* is needed to fix activating neighbour widgets, that happens, if using upper one */ + gtk_grab_add( widget ); + weedjet = widget; - ++#else ++ GdkCursor* cursor = create_blank_cursor(); ++ //GdkGrabStatus status = + gdk_pointer_grab( gtk_widget_get_window( widget ), TRUE, mask, 0, cursor, GDK_CURRENT_TIME ); gdk_cursor_unref( cursor ); ++#endif +#endif - Sys_GetCursorPos( window, ¢er_x, ¢er_y ); + Sys_GetCursorPos( widget, &recorded_x, &recorded_y ); - Sys_SetCursorPos( widget, recorded_x, recorded_y ); ++#if 0 // NetRadiantCustom + /* using center for tracking for max safety */ + gdk_window_get_origin( GTK_WIDGET( widget )->window, ¢er_x, ¢er_y ); + auto allocation = widget.dimensions(); + center_y += allocation.height / 2; + center_x += allocation.width / 2; + - Sys_SetCursorPos( window, center_x, center_y ); ++ Sys_SetCursorPos( widget, center_x, center_y ); + last_x = center_x; + last_y = center_y; ++#else + last_x = recorded_x; + last_y = recorded_y; ++#endif m_function = function; m_data = data; @@@ -239,13 -135,9 +271,21 @@@ void FreezePointer::unfreeze_pointer(ui m_function = 0; m_data = 0; -// Sys_SetCursorPos( window, center_x, center_y ); +#if defined(WORKAROUND_MACOS_GTK2_LAGGYPOINTER) + /* The pointer was visible during all the move operation, + so, keep the current position. */ +#else - // Note: NetRadiantCustom still uses window instead of widget. ++ // NetRadiantCustom still uses window instead of widget. ++#if 0 // NetRadiantCustom ++// Sys_SetCursorPos( widget, center_x, center_y ); ++#else + Sys_SetCursorPos( widget, recorded_x, recorded_y ); ++#endif +#endif gdk_pointer_ungrab( GDK_CURRENT_TIME ); + ++#if 0 // NetRadiantCustom + gtk_grab_remove( weedjet ); ++#endif } diff --cc libs/gtkutil/cursor.h index db0234d7,81767d2e..f7a66a37 --- a/libs/gtkutil/cursor.h +++ b/libs/gtkutil/cursor.h @@@ -30,10 -29,8 +30,10 @@@ typedef struct _GdkCursor GdkCursor; typedef struct _GdkEventMotion GdkEventMotion; - // Note: NetRadiantCustom disables them but we still make use of them. -#if 0 ++// NetRadiantCustom disables them but we still make use of them. +#if 1 GdkCursor* create_blank_cursor(); +void set_cursor( ui::Widget widget, GdkCursorType cursor_type ); void blank_cursor( ui::Widget widget ); void default_cursor( ui::Widget widget ); #endif @@@ -117,11 -117,11 +118,17 @@@ void* m_data public: FreezePointer() : handle_motion( 0 ), m_function( 0 ), m_data( 0 ){ } -static gboolean motion_delta( ui::Window widget, GdkEventMotion *event, FreezePointer* self ); ++/* NetRadiantCustom does this instead: ++static gboolean motion_delta( ui::Window widget, GdkEventMotion *event, FreezePointer* self ); */ +static gboolean motion_delta( ui::Widget widget, GdkEventMotion *event, FreezePointer* self ); -void freeze_pointer( ui::Window window, ui::Widget widget, MotionDeltaFunction function, void* data ); ++/* NetRadiantCustom does this instead: ++void freeze_pointer( ui::Window window, ui::Widget widget, MotionDeltaFunction function, void* data ); */ +void freeze_pointer( ui::Widget widget, MotionDeltaFunction function, void* data ); -void unfreeze_pointer( ui::Window window ); ++/* NetRadiantCustom does this instead: ++void unfreeze_pointer( ui::Window window ); */ +void unfreeze_pointer( ui::Widget widget ); }; #endif diff --cc radiant/camwindow.cpp index ee6634e6,7784ea3f..6ccf3ec6 --- a/radiant/camwindow.cpp +++ b/radiant/camwindow.cpp @@@ -1324,9 -1319,7 +1324,9 @@@ void CamWnd::EnableFreeMove() gtk_window_set_focus( m_parent, m_gl_widget ); m_freemove_handle_focusout = m_gl_widget.connect( "focus_out_event", G_CALLBACK( camwindow_freemove_focusout ), this ); - /* Note: We chose to replace m_parent by m_gl_widget but NetRadiantCustom does: - m_freezePointer.freeze_pointer( m_parent, m_gl_widget, Camera_motionDelta, &m_Camera ); ++ /* We chose to replace m_parent by m_gl_widget but NetRadiantCustom does: + m_freezePointer.freeze_pointer( m_parent, m_gl_widget, Camera_motionDelta, &m_Camera ); */ + m_freezePointer.freeze_pointer( m_gl_widget, Camera_motionDelta, &m_Camera ); CamWnd_Update( *this ); } diff --cc radiant/texwindow.cpp index 27baf5ed,82e73203..451f94a6 --- a/radiant/texwindow.cpp +++ b/radiant/texwindow.cpp @@@ -1176,10 -1123,7 +1176,10 @@@ void TextureBrowser_trackingDelta( int void TextureBrowser_Tracking_MouseUp( TextureBrowser& textureBrowser ){ textureBrowser.m_move_started = false; - /* Note: NetRadiantCustom did this instead: - textureBrowser.m_freezePointer.unfreeze_pointer( textureBrowser.m_parent ); ++ /* NetRadiantCustom did this instead: + textureBrowser.m_freezePointer.unfreeze_pointer( textureBrowser.m_gl_widget ); */ + + textureBrowser.m_freezePointer.unfreeze_pointer( textureBrowser.m_gl_widget ); } void TextureBrowser_Tracking_MouseDown( TextureBrowser& textureBrowser ){ @@@ -1187,9 -1131,7 +1187,9 @@@ TextureBrowser_Tracking_MouseUp( textureBrowser ); } textureBrowser.m_move_started = true; - /* Note: NetRadiantCustom did this instead: - textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_parent, textureBrowser.m_gl_widget, TextureBrowser_trackingDelta, &textureBrowser ); ++ /* NetRadiantCustom did this instead: + textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_parent, textureBrowser.m_gl_widget, TextureBrowser_trackingDelta, &textureBrowser ); */ + textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_gl_widget, TextureBrowser_trackingDelta, &textureBrowser ); } void TextureBrowser_Selection_MouseDown( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy ){ diff --cc radiant/xywindow.cpp index 4c07a7fe,ae99174b..0d8625fa --- a/radiant/xywindow.cpp +++ b/radiant/xywindow.cpp @@@ -1215,9 -1210,7 +1215,9 @@@ void XYWnd::Move_Begin() Move_End(); } m_move_started = true; - /* Note: NetRadiantCustom did this instead: - g_xywnd_freezePointer.freeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_moveDelta, this ); ++ /* NetRadiantCustom did this instead: + g_xywnd_freezePointer.freeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_moveDelta, this ); */ + g_xywnd_freezePointer.freeze_pointer( m_gl_widget, XYWnd_moveDelta, this ); m_move_focusOut = m_gl_widget.connect( "focus_out_event", G_CALLBACK( XYWnd_Move_focusOut ), this ); } @@@ -1262,9 -1255,7 +1262,9 @@@ void XYWnd::Zoom_Begin() } m_zoom_started = true; g_dragZoom = 0; - /* Note: NetRadiantCustom did this instead: - g_xywnd_freezePointer.freeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_zoomDelta, this ); ++ /* NetRadiantCustom did this instead: + g_xywnd_freezePointer.freeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), m_gl_widget, XYWnd_zoomDelta, this ); */ + g_xywnd_freezePointer.freeze_pointer( m_parent ? m_parent : MainFrame_getWindow(), XYWnd_zoomDelta, this ); m_zoom_focusOut = m_gl_widget.connect( "focus_out_event", G_CALLBACK( XYWnd_Zoom_focusOut ), this ); }