quartz: Process motion events within windows bounds without window set

When an NSEvent does not have the window field set, we already assumed
the event was not for us and discarded it.  But for NSMouseMoved events
we now make an exception, because such events generated after
using/clicking the main menu bar have the window field set to NULL while
the application window still has focus.

We used to experience a loss of motion events after using the menu bar,
this could be seen in buttons that stopped prelighting and first
clicks often being ignored unless you clicked somewhere else first.
These issues are fixed by this patch.
This commit is contained in:
Kristian Rietveld 2011-11-06 09:25:16 +01:00
parent 7269cdf315
commit 9f45c37be7

View File

@ -57,6 +57,12 @@ static GdkModifierType current_button_state;
static void append_event (GdkEvent *event,
gboolean windowing);
static GdkWindow *find_toplevel_under_pointer (GdkDisplay *display,
NSPoint screen_point,
gint *x,
gint *y);
void
_gdk_quartz_events_init (void)
{
@ -329,19 +335,34 @@ get_toplevel_from_ns_event (NSEvent *nsevent,
gint *x,
gint *y)
{
GdkQuartzView *view;
GdkWindow *toplevel;
NSPoint point;
view = (GdkQuartzView *)[[nsevent window] contentView];
if ([nsevent window])
{
GdkQuartzView *view;
NSPoint point;
toplevel = [view gdkWindow];
view = (GdkQuartzView *)[[nsevent window] contentView];
point = [nsevent locationInWindow];
*screen_point = [[nsevent window] convertBaseToScreen:point];
toplevel = [view gdkWindow];
*x = point.x;
*y = toplevel->height - point.y;
point = [nsevent locationInWindow];
*screen_point = [[nsevent window] convertBaseToScreen:point];
*x = point.x;
*y = toplevel->height - point.y;
}
else
{
/* Fallback used when no NSWindow set. This happens e.g. when
* we allow motion events without a window set in gdk_event_translate()
* that occur immediately after the main menu bar was clicked/used.
*/
*screen_point = [NSEvent mouseLocation];
toplevel = find_toplevel_under_pointer (_gdk_display,
*screen_point,
x, y);
}
return toplevel;
}
@ -1164,10 +1185,33 @@ gdk_event_translate (GdkEvent *event,
nswindow = [nsevent window];
/* Ignore events for no window or ones not created by GDK. */
if (!nswindow || ![[nswindow contentView] isKindOfClass:[GdkQuartzView class]])
/* Ignore events for windows not created by GDK. */
if (nswindow && ![[nswindow contentView] isKindOfClass:[GdkQuartzView class]])
return FALSE;
/* Ignore events for ones with no windows */
if (!nswindow)
{
GdkWindow *toplevel = NULL;
if (event_type == NSMouseMoved)
{
/* Motion events received after clicking the menu bar do not have the
* window field set. Instead of giving up on the event immediately,
* we first check whether this event is within our window bounds.
*/
NSPoint screen_point = [NSEvent mouseLocation];
gint x_tmp, y_tmp;
toplevel = find_toplevel_under_pointer (_gdk_display,
screen_point,
&x_tmp, &y_tmp);
}
if (!toplevel)
return FALSE;
}
/* Ignore events and break grabs while the window is being
* dragged. This is a workaround for the window getting events for
* the window title.