Generate wxEVT_ENTER_WINDOW in icon part of wxSearchCtrl in wxGTK
Mouse motion events happening over GtkEntry icons are consumed by this class "event" callback, which simply returns GDK_EVENT_STOP for them if the icon is insensitive (which is the case for GtkSearchEntry) and so our "enter-notify-event" callback is never called. Fix this by handling "event" signal ourselves and generating wxEVT_ENTER_WINDOW from it if necessary. Doing this required adding a global pointer to the window currently under mouse, which is also used for generating wxEVT_LEAVE_WINDOW if necessary. See #24245.
This commit is contained in:
parent
a8b4753d1d
commit
9205da74db
3 changed files with 74 additions and 0 deletions
|
|
@ -88,6 +88,12 @@ template<typename T> void InitMouseEvent(wxWindowGTK *win,
|
||||||
event.SetTimestamp( gdk_event->time );
|
event.SetTimestamp( gdk_event->time );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the window currently known to be under the mouse pointer.
|
||||||
|
//
|
||||||
|
// Returns true if it was updated, false if this window was already known to
|
||||||
|
// contain the mouse pointer.
|
||||||
|
bool SetWindowUnderMouse(wxWindowGTK* win);
|
||||||
|
|
||||||
} // namespace wxGTKImpl
|
} // namespace wxGTKImpl
|
||||||
|
|
||||||
#endif // _GTK_PRIVATE_EVENT_H_
|
#endif // _GTK_PRIVATE_EVENT_H_
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
#include "wx/gtk/private.h"
|
#include "wx/gtk/private.h"
|
||||||
|
#include "wx/gtk/private/event.h"
|
||||||
#include "wx/gtk/private/gtk3-compat.h"
|
#include "wx/gtk/private/gtk3-compat.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -93,6 +94,28 @@ wx_gtk_icon_press(GtkEntry* WXUNUSED(entry),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
wx_gtk_entry_event(GtkEntry* WXUNUSED(entry),
|
||||||
|
GdkEvent* event,
|
||||||
|
wxSearchCtrl* ctrl)
|
||||||
|
{
|
||||||
|
if ( event->type == GDK_MOTION_NOTIFY )
|
||||||
|
{
|
||||||
|
// GtkEntry "event" signal handler ignores motion events happening over
|
||||||
|
// inactive icons, but we want to notify the window about the mouse
|
||||||
|
// entering it when they happen.
|
||||||
|
if ( wxGTKImpl::SetWindowUnderMouse(ctrl) )
|
||||||
|
{
|
||||||
|
wxMouseEvent mouseEvent(wxEVT_ENTER_WINDOW);
|
||||||
|
wxGTKImpl::InitMouseEvent(ctrl, mouseEvent, (GdkEventMotion*)event);
|
||||||
|
|
||||||
|
ctrl->GTKProcessEvent(mouseEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
@ -209,6 +232,8 @@ void wxSearchCtrl::GTKCreateSearchEntryWidget()
|
||||||
}
|
}
|
||||||
|
|
||||||
g_signal_connect(m_entry, "icon-press", G_CALLBACK(wx_gtk_icon_press), this);
|
g_signal_connect(m_entry, "icon-press", G_CALLBACK(wx_gtk_icon_press), this);
|
||||||
|
|
||||||
|
g_signal_connect(m_entry, "event", G_CALLBACK(wx_gtk_entry_event), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkEditable *wxSearchCtrl::GetEditable() const
|
GtkEditable *wxSearchCtrl::GetEditable() const
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,23 @@ static wxWindowGTK *gs_deferredFocusOut = nullptr;
|
||||||
GdkEvent *g_lastMouseEvent = nullptr;
|
GdkEvent *g_lastMouseEvent = nullptr;
|
||||||
int g_lastButtonNumber = 0;
|
int g_lastButtonNumber = 0;
|
||||||
|
|
||||||
|
static wxWindowGTK* g_windowUnderMouse = nullptr;
|
||||||
|
|
||||||
|
namespace wxGTKImpl
|
||||||
|
{
|
||||||
|
|
||||||
|
bool SetWindowUnderMouse(wxWindowGTK* win)
|
||||||
|
{
|
||||||
|
if ( g_windowUnderMouse == win )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
g_windowUnderMouse = win;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace wxGTKImpl
|
||||||
|
|
||||||
#ifdef wxHAS_XKB
|
#ifdef wxHAS_XKB
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
@ -2251,6 +2268,26 @@ gtk_window_enter_callback( GtkWidget* widget,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( g_windowUnderMouse == win )
|
||||||
|
{
|
||||||
|
// This can happen if the enter event was generated from another
|
||||||
|
// callback, as is the case for wxSearchCtrl, for example.
|
||||||
|
wxLogTrace(TRACE_MOUSE, "Reentering window %s", wxDumpWindow(win));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( g_windowUnderMouse )
|
||||||
|
{
|
||||||
|
// We must not have got the leave event for the previous window, so
|
||||||
|
// generate it now -- better late than never.
|
||||||
|
wxMouseEvent event( wxEVT_LEAVE_WINDOW );
|
||||||
|
InitMouseEvent(g_windowUnderMouse, event, gdk_event);
|
||||||
|
|
||||||
|
(void)g_windowUnderMouse->GTKProcessEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_windowUnderMouse = win;
|
||||||
|
|
||||||
wxMouseEvent event( wxEVT_ENTER_WINDOW );
|
wxMouseEvent event( wxEVT_ENTER_WINDOW );
|
||||||
InitMouseEvent(win, event, gdk_event);
|
InitMouseEvent(win, event, gdk_event);
|
||||||
|
|
||||||
|
|
@ -2285,6 +2322,9 @@ gtk_window_leave_callback( GtkWidget* widget,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( win == g_windowUnderMouse )
|
||||||
|
g_windowUnderMouse = nullptr;
|
||||||
|
|
||||||
wxMouseEvent event( wxEVT_LEAVE_WINDOW );
|
wxMouseEvent event( wxEVT_LEAVE_WINDOW );
|
||||||
InitMouseEvent(win, event, gdk_event);
|
InitMouseEvent(win, event, gdk_event);
|
||||||
|
|
||||||
|
|
@ -2914,6 +2954,9 @@ wxWindowGTK::~wxWindowGTK()
|
||||||
if ( g_captureWindow == this )
|
if ( g_captureWindow == this )
|
||||||
g_captureWindow = nullptr;
|
g_captureWindow = nullptr;
|
||||||
|
|
||||||
|
if ( g_windowUnderMouse == this )
|
||||||
|
g_windowUnderMouse = nullptr;
|
||||||
|
|
||||||
if (m_wxwindow)
|
if (m_wxwindow)
|
||||||
{
|
{
|
||||||
GTKDisconnect(m_wxwindow);
|
GTKDisconnect(m_wxwindow);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue