Make the GAL responsible for the native cursor management

The native cursor must be set on the GAL canvas wx object,
not its frame (otherwise on GTK the cursor is only set
when we get a request for it from the WM and not immediately).

Fixes https://gitlab.com/kicad/code/kicad/issues/6421
This commit is contained in:
Ian McInerney 2021-04-05 02:35:01 +01:00
parent ecba8b5578
commit e08387ce3d
14 changed files with 115 additions and 40 deletions

View File

@ -33,6 +33,7 @@ set( GAL_SRCS
newstroke_font.cpp newstroke_font.cpp
painter.cpp painter.cpp
gal/color4d.cpp gal/color4d.cpp
gal/cursors.cpp
gal/dpi_scaling.cpp gal/dpi_scaling.cpp
gal/gal_display_options.cpp gal/gal_display_options.cpp
gal/graphics_abstraction_layer.cpp gal/graphics_abstraction_layer.cpp
@ -321,7 +322,6 @@ set( COMMON_SRCS
common.cpp common.cpp
config_params.cpp config_params.cpp
confirm.cpp confirm.cpp
cursors.cpp
dialog_shim.cpp dialog_shim.cpp
gr_text.cpp gr_text.cpp
dsnlexer.cpp dsnlexer.cpp

View File

@ -30,7 +30,6 @@
#include <kiface_i.h> #include <kiface_i.h>
#include <macros.h> #include <macros.h>
#include <settings/app_settings.h> #include <settings/app_settings.h>
#include <cursors.h>
#include <trace_helpers.h> #include <trace_helpers.h>
#include <class_draw_panel_gal.h> #include <class_draw_panel_gal.h>
@ -38,6 +37,7 @@
#include <view/wx_view_controls.h> #include <view/wx_view_controls.h>
#include <painter.h> #include <painter.h>
#include <base_screen.h> #include <base_screen.h>
#include <gal/cursors.h>
#include <gal/graphics_abstraction_layer.h> #include <gal/graphics_abstraction_layer.h>
#include <gal/opengl/opengl_gal.h> #include <gal/opengl/opengl_gal.h>
#include <gal/cairo/cairo_gal.h> #include <gal/cairo/cairo_gal.h>
@ -71,8 +71,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
m_stealsFocus( true ) m_stealsFocus( true )
{ {
m_parent = aParentWindow; m_parent = aParentWindow;
m_currentKiCursor = KICURSOR::DEFAULT;
SetCurrentCursor( KICURSOR::ARROW );
SetLayoutDirection( wxLayout_LeftToRight ); SetLayoutDirection( wxLayout_LeftToRight );
@ -99,8 +97,6 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this ); Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this );
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this ); Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this );
Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( EDA_DRAW_PANEL_GAL::onLostFocus ), NULL, this ); Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( EDA_DRAW_PANEL_GAL::onLostFocus ), NULL, this );
Connect( wxEVT_SET_CURSOR, wxSetCursorEventHandler( EDA_DRAW_PANEL_GAL::onSetCursor ), NULL,
this );
const wxEventType events[] = { const wxEventType events[] = {
// Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events, // Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events,
@ -450,15 +446,6 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
// trigger update of the gal options in case they differ from the defaults // trigger update of the gal options in case they differ from the defaults
m_options.NotifyChanged(); m_options.NotifyChanged();
wxWindow* galWindow = dynamic_cast<wxWindow*>( new_gal );
if( galWindow )
{
galWindow->Connect( wxEVT_SET_CURSOR,
wxSetCursorEventHandler( EDA_DRAW_PANEL_GAL::onSetCursor ), NULL,
this );
}
delete m_gal; delete m_gal;
m_gal = new_gal; m_gal = new_gal;
@ -472,6 +459,9 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
m_gal->SetGridVisibility( grid_visibility ); m_gal->SetGridVisibility( grid_visibility );
// Make sure the cursor is set on the new canvas
SetCurrentCursor( KICURSOR::ARROW );
if( m_painter ) if( m_painter )
m_painter->SetGAL( m_gal ); m_painter->SetGAL( m_gal );
@ -565,21 +555,10 @@ void EDA_DRAW_PANEL_GAL::onShowTimer( wxTimerEvent& aEvent )
} }
void EDA_DRAW_PANEL_GAL::SetCurrentCursor( KICURSOR cursor ) void EDA_DRAW_PANEL_GAL::SetCurrentCursor( KICURSOR aCursor )
{ {
if( m_currentKiCursor == cursor ) if( m_gal )
return; m_gal->SetNativeCursorStyle( aCursor );
m_currentCursor = CURSOR_STORE::GetCursor( cursor );
m_currentKiCursor = cursor;
SetCursor( m_currentCursor );
}
void EDA_DRAW_PANEL_GAL::onSetCursor( wxSetCursorEvent& event )
{
event.SetCursor( m_currentCursor );
} }

View File

@ -1230,6 +1230,10 @@ CAIRO_GAL::CAIRO_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
m_mouseListener = aMouseListener; m_mouseListener = aMouseListener;
m_paintListener = aPaintListener; m_paintListener = aPaintListener;
// Connect the native cursor handler
Connect( wxEVT_SET_CURSOR, wxSetCursorEventHandler( CAIRO_GAL::onSetNativeCursor ), NULL,
this );
// Connecting the event handlers // Connecting the event handlers
Connect( wxEVT_PAINT, wxPaintEventHandler( CAIRO_GAL::onPaint ) ); Connect( wxEVT_PAINT, wxPaintEventHandler( CAIRO_GAL::onPaint ) );
@ -1534,6 +1538,27 @@ bool CAIRO_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
} }
bool CAIRO_GAL::SetNativeCursorStyle( KICURSOR aCursor )
{
// Store the current cursor type and get the wxCursor for it
if( !GAL::SetNativeCursorStyle( aCursor ) )
return false;
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
// Update the cursor in the wx control
wxWindow::SetCursor( m_currentwxCursor );
return true;
}
void CAIRO_GAL::onSetNativeCursor( wxSetCursorEvent& aEvent )
{
aEvent.SetCursor( m_currentwxCursor );
}
void CAIRO_GAL_BASE::DrawGrid() void CAIRO_GAL_BASE::DrawGrid()
{ {
SetTarget( TARGET_NONCACHED ); SetTarget( TARGET_NONCACHED );

View File

@ -23,8 +23,10 @@
#include <vector> #include <vector>
#include <cursors.h> #include <gal/cursors.h>
#include <kiplatform/ui.h> #include <kiplatform/ui.h>
// Cursor files
#include <cursors/cursor-add.xpm> #include <cursors/cursor-add.xpm>
#include <cursors/cursor-component.xpm> #include <cursors/cursor-component.xpm>
#include <cursors/cursor-eraser.xpm> #include <cursors/cursor-eraser.xpm>

View File

@ -74,6 +74,9 @@ GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
m_forceDisplayCursor = false; m_forceDisplayCursor = false;
SetCursorEnabled( false ); SetCursorEnabled( false );
// Initialize the native widget to an arrow cursor
SetNativeCursorStyle( KICURSOR::ARROW );
// Initialize text properties // Initialize text properties
ResetTextAttributes(); ResetTextAttributes();
@ -250,3 +253,14 @@ COLOR4D GAL::getCursorColor() const
return color; return color;
} }
bool GAL::SetNativeCursorStyle( KICURSOR aCursor )
{
if( m_currentNativeCursor == aCursor )
return false;
m_currentNativeCursor = aCursor;
return true;
}

View File

@ -236,6 +236,10 @@ OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
m_isGrouping = false; m_isGrouping = false;
m_groupCounter = 0; m_groupCounter = 0;
// Connect the native cursor handler
Connect( wxEVT_SET_CURSOR, wxSetCursorEventHandler( OPENGL_GAL::onSetNativeCursor ), NULL,
this );
// Connecting the event handlers // Connecting the event handlers
Connect( wxEVT_PAINT, wxPaintEventHandler( OPENGL_GAL::onPaint ) ); Connect( wxEVT_PAINT, wxPaintEventHandler( OPENGL_GAL::onPaint ) );
@ -1718,6 +1722,27 @@ bool OPENGL_GAL::HasTarget( RENDER_TARGET aTarget )
} }
bool OPENGL_GAL::SetNativeCursorStyle( KICURSOR aCursor )
{
// Store the current cursor type and get the wxCursor for it
if( !GAL::SetNativeCursorStyle( aCursor ) )
return false;
m_currentwxCursor = CURSOR_STORE::GetCursor( m_currentNativeCursor );
// Update the cursor in the wx control
HIDPI_GL_CANVAS::SetCursor( m_currentwxCursor );
return true;
}
void OPENGL_GAL::onSetNativeCursor( wxSetCursorEvent& aEvent )
{
aEvent.SetCursor( m_currentwxCursor );
}
void OPENGL_GAL::DrawCursor( const VECTOR2D& aCursorPosition ) void OPENGL_GAL::DrawCursor( const VECTOR2D& aCursorPosition )
{ {
// Now we should only store the position of the mouse cursor // Now we should only store the position of the mouse cursor

View File

@ -56,7 +56,6 @@ SCH_DRAW_PANEL::SCH_DRAW_PANEL( wxWindow* aParentWindow, wxWindowID aWindowId,
KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType ) KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType )
: EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalType ) : EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalType )
{ {
m_currentCursor = wxCURSOR_ARROW;
m_view = new KIGFX::SCH_VIEW( true, dynamic_cast<SCH_BASE_FRAME*>( GetParentEDAFrame() ) ); m_view = new KIGFX::SCH_VIEW( true, dynamic_cast<SCH_BASE_FRAME*>( GetParentEDAFrame() ) );
m_view->SetGAL( m_gal ); m_view->SetGAL( m_gal );

View File

@ -31,7 +31,7 @@
#include <tools/ee_selection.h> #include <tools/ee_selection.h>
#include <ee_collectors.h> #include <ee_collectors.h>
#include <sch_symbol.h> #include <sch_symbol.h>
#include <cursors.h> #include <gal/cursors.h>
class SCH_BASE_FRAME; class SCH_BASE_FRAME;
class SCH_ITEM; class SCH_ITEM;

View File

@ -35,7 +35,8 @@
#include <math/vector2d.h> #include <math/vector2d.h>
#include <widgets/msgpanel.h> #include <widgets/msgpanel.h>
#include <memory> #include <memory>
#include <cursors.h>
#include <gal/cursors.h>
class BOARD; class BOARD;
class EDA_DRAW_FRAME; class EDA_DRAW_FRAME;
@ -190,7 +191,7 @@ public:
/** /**
* Set the current cursor shape for this panel. * Set the current cursor shape for this panel.
*/ */
void SetCurrentCursor( KICURSOR cursor ); void SetCurrentCursor( KICURSOR aCursor );
/** /**
* Return the bounding box of the view that should be used if model is not valid. * Return the bounding box of the view that should be used if model is not valid.
@ -232,13 +233,9 @@ protected:
void onLostFocus( wxFocusEvent& aEvent ); void onLostFocus( wxFocusEvent& aEvent );
void onRefreshTimer( wxTimerEvent& aEvent ); void onRefreshTimer( wxTimerEvent& aEvent );
void onShowTimer( wxTimerEvent& aEvent ); void onShowTimer( wxTimerEvent& aEvent );
void onSetCursor( wxSetCursorEvent& event );
static const int MinRefreshPeriod = 17; ///< 60 FPS. static const int MinRefreshPeriod = 17; ///< 60 FPS.
wxCursor m_currentCursor; ///< Current mouse cursor shape id.
KICURSOR m_currentKiCursor;
wxWindow* m_parent; ///< Pointer to the parent window wxWindow* m_parent; ///< Pointer to the parent window
EDA_DRAW_FRAME* m_edaFrame; ///< Parent EDA_DRAW_FRAME (if available) EDA_DRAW_FRAME* m_edaFrame; ///< Parent EDA_DRAW_FRAME (if available)

View File

@ -407,6 +407,9 @@ public:
m_paintListener = aPaintListener; m_paintListener = aPaintListener;
} }
/// @copydoc GAL::SetNativeCursorStyle()
bool SetNativeCursorStyle( KICURSOR aCursor ) override;
/// @copydoc GAL::BeginDrawing() /// @copydoc GAL::BeginDrawing()
void beginDrawing() override; void beginDrawing() override;
@ -443,6 +446,13 @@ public:
*/ */
void skipMouseEvent( wxMouseEvent& aEvent ); void skipMouseEvent( wxMouseEvent& aEvent );
/**
* Give the correct cursor image when the native widget asks for it.
*
* @param aEvent is the cursor event to plac the cursor into.
*/
void onSetNativeCursor( wxSetCursorEvent& aEvent );
///< Cairo-specific update handlers ///< Cairo-specific update handlers
bool updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions ) override; bool updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions ) override;
@ -467,6 +477,7 @@ protected:
int m_wxBufferWidth; int m_wxBufferWidth;
bool m_isInitialized; ///< Are Cairo image & surface ready to use bool m_isInitialized; ///< Are Cairo image & surface ready to use
COLOR4D m_backgroundColor; ///< Background color COLOR4D m_backgroundColor; ///< Background color
wxCursor m_currentwxCursor; ///< wxCursor showing the current native cursor
}; };
} // namespace KIGFX } // namespace KIGFX

View File

@ -34,6 +34,7 @@
#include <math/matrix3x3.h> #include <math/matrix3x3.h>
#include <gal/color4d.h> #include <gal/color4d.h>
#include <gal/cursors.h>
#include <gal/definitions.h> #include <gal/definitions.h>
#include <gal/stroke_font.h> #include <gal/stroke_font.h>
#include <gal/gal_display_options.h> #include <gal/gal_display_options.h>
@ -965,6 +966,14 @@ public:
return VECTOR2D( m_worldScreenMatrix * aPoint ); return VECTOR2D( m_worldScreenMatrix * aPoint );
} }
/**
* Set the cursor in the native panel.
*
* @param aCursor is the cursor to use in the native panel
* @return true if the cursor was updated, false if the cursor given was already set
*/
virtual bool SetNativeCursorStyle( KICURSOR aCursor );
/** /**
* Enable/disable cursor. * Enable/disable cursor.
* *
@ -1158,6 +1167,7 @@ protected:
STROKE_FONT m_strokeFont; ///< Instance of object that stores information STROKE_FONT m_strokeFont; ///< Instance of object that stores information
///< about how to draw texts ///< about how to draw texts
KICURSOR m_currentNativeCursor; ///< Current cursor
private: private:
struct TEXT_PROPERTIES struct TEXT_PROPERTIES
{ {

View File

@ -43,6 +43,7 @@
#include <unordered_map> #include <unordered_map>
#include <boost/smart_ptr/shared_array.hpp> #include <boost/smart_ptr/shared_array.hpp>
#include <memory> #include <memory>
#include <wx/event.h>
#ifndef CALLBACK #ifndef CALLBACK
#define CALLBACK #define CALLBACK
@ -246,6 +247,9 @@ public:
// Cursor // Cursor
// ------- // -------
/// @copydoc GAL::SetNativeCursorStyle()
bool SetNativeCursorStyle( KICURSOR aCursor ) override;
/// @copydoc GAL::DrawCursor() /// @copydoc GAL::DrawCursor()
void DrawCursor( const VECTOR2D& aCursorPosition ) override; void DrawCursor( const VECTOR2D& aCursorPosition ) override;
@ -333,6 +337,8 @@ private:
GLint ufm_screenPixelSize; GLint ufm_screenPixelSize;
GLint ufm_pixelSizeMultiplier; GLint ufm_pixelSizeMultiplier;
wxCursor m_currentwxCursor; ///< wxCursor showing the current native cursor
std::unique_ptr<GL_BITMAP_CACHE> m_bitmapCache; std::unique_ptr<GL_BITMAP_CACHE> m_bitmapCache;
// Polygon tesselation // Polygon tesselation
@ -468,6 +474,13 @@ private:
*/ */
void skipMouseEvent( wxMouseEvent& aEvent ); void skipMouseEvent( wxMouseEvent& aEvent );
/**
* Give the correct cursor image when the native widget asks for it.
*
* @param aEvent is the cursor event to plac the cursor into.
*/
void onSetNativeCursor( wxSetCursorEvent& aEvent );
/** /**
* Blit cursor into the current screen. * Blit cursor into the current screen.
*/ */

View File

@ -25,10 +25,10 @@
#ifndef PICKER_TOOL_H #ifndef PICKER_TOOL_H
#define PICKER_TOOL_H #define PICKER_TOOL_H
#include <boost/optional/optional.hpp> #include <core/optional.h>
#include <gal/cursors.h>
#include <math/vector2d.h> #include <math/vector2d.h>
#include <tool/tool_interactive.h> #include <tool/tool_interactive.h>
#include <cursors.h>
class EDA_DRAW_FRAME; class EDA_DRAW_FRAME;