forked from AuroraMiddleware/gtk
Defer the generated event to the mainloop and don't generate one at all if
2008-03-28 Richard Hult <richard@imendio.com> * gdk/quartz/gdkevents-quartz.c: (gdk_event_translate), (_gdk_quartz_events_trigger_crossing_events): Defer the generated event to the mainloop and don't generate one at all if the toplevel didn't change. Use the actual window and not the toplevel as event window. These changes make the generated crossing events match the X11 behavior and fixes issues with e.g. tooltips, comboboxes and menus. * gdk/quartz/GdkQuartzView.c: Don't update the tracking rect if the view has no window, it will be updated as soon as it's put inside a window. * gdk/quartz/gdkwindow-quartz.c: (_gdk_quartz_window_debug_highlight): Make it possible to track multiple windows with debug highlighting. (show_window_internal): Remove workaround for tooltips and popups that is no longer needed with the above changes. svn path=/trunk/; revision=19951
This commit is contained in:
parent
129c717a71
commit
a63c87c5da
20
ChangeLog
20
ChangeLog
@ -1,3 +1,23 @@
|
||||
2008-03-28 Richard Hult <richard@imendio.com>
|
||||
|
||||
* gdk/quartz/gdkevents-quartz.c: (gdk_event_translate),
|
||||
(_gdk_quartz_events_trigger_crossing_events): Defer the generated
|
||||
event to the mainloop and don't generate one at all if the
|
||||
toplevel didn't change. Use the actual window and not the toplevel
|
||||
as event window. These changes make the generated crossing events
|
||||
match the X11 behavior and fixes issues with e.g. tooltips,
|
||||
comboboxes and menus.
|
||||
|
||||
* gdk/quartz/GdkQuartzView.c: Don't update the tracking rect if
|
||||
the view has no window, it will be updated as soon as it's put
|
||||
inside a window.
|
||||
|
||||
* gdk/quartz/gdkwindow-quartz.c:
|
||||
(_gdk_quartz_window_debug_highlight): Make it possible to track
|
||||
multiple windows with debug highlighting.
|
||||
(show_window_internal): Remove workaround for tooltips and popups
|
||||
that is no longer needed with the above changes.
|
||||
|
||||
2008-03-26 Federico Mena Quintero <federico@novell.com>
|
||||
|
||||
* gtk/gtkfilechooserentry.c (commit_completion_and_refresh): New
|
||||
|
@ -179,7 +179,9 @@
|
||||
-(void)setFrame:(NSRect)frame
|
||||
{
|
||||
[super setFrame:frame];
|
||||
[self updateTrackingRect];
|
||||
|
||||
if ([self window])
|
||||
[self updateTrackingRect];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -888,7 +888,7 @@ _gdk_quartz_events_update_mouse_window (GdkWindow *window)
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
|
||||
_gdk_quartz_window_debug_highlight (window);
|
||||
_gdk_quartz_window_debug_highlight (window, 0);
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
if (window)
|
||||
@ -1092,18 +1092,34 @@ find_mouse_window_for_ns_event (NSEvent *nsevent,
|
||||
* window.
|
||||
*/
|
||||
void
|
||||
_gdk_quartz_events_trigger_crossing_events (void)
|
||||
_gdk_quartz_events_trigger_crossing_events (gboolean defer_to_mainloop)
|
||||
{
|
||||
NSPoint point;
|
||||
gint x;
|
||||
gint y;
|
||||
gint x, y;
|
||||
gint x_toplevel, y_toplevel;
|
||||
GdkWindow *mouse_window;
|
||||
GdkWindow *toplevel;
|
||||
GdkWindowImplQuartz *impl;
|
||||
guint flags = 0;
|
||||
NSTimeInterval timestamp = 0;
|
||||
NSEvent *current_event;
|
||||
NSEvent *nsevent;
|
||||
|
||||
if (defer_to_mainloop)
|
||||
{
|
||||
nsevent = [NSEvent otherEventWithType:NSApplicationDefined
|
||||
location:NSZeroPoint
|
||||
modifierFlags:0
|
||||
timestamp:0
|
||||
windowNumber:0
|
||||
context:nil
|
||||
subtype:GDK_QUARTZ_EVENT_SUBTYPE_FAKE_CROSSING
|
||||
data1:0
|
||||
data2:0];
|
||||
[NSApp postEvent:nsevent atStart:NO];
|
||||
return;
|
||||
}
|
||||
|
||||
point = [NSEvent mouseLocation];
|
||||
x = point.x;
|
||||
y = _gdk_quartz_window_get_inverted_screen_y (point.y);
|
||||
@ -1112,16 +1128,24 @@ _gdk_quartz_events_trigger_crossing_events (void)
|
||||
if (!mouse_window || mouse_window == _gdk_root)
|
||||
return;
|
||||
|
||||
/* NSMouseEntered always happens on the toplevel. */
|
||||
mouse_window = gdk_window_get_toplevel (mouse_window);
|
||||
toplevel = gdk_window_get_toplevel (mouse_window);
|
||||
|
||||
/* We ignore crossing within the same toplevel since that is already
|
||||
* handled elsewhere.
|
||||
*/
|
||||
if (toplevel == gdk_window_get_toplevel (current_mouse_window))
|
||||
return;
|
||||
|
||||
get_converted_window_coordinates (_gdk_root,
|
||||
x, y,
|
||||
toplevel,
|
||||
&x_toplevel, &y_toplevel);
|
||||
|
||||
get_converted_window_coordinates (_gdk_root,
|
||||
x, y,
|
||||
mouse_window,
|
||||
&x, &y);
|
||||
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (mouse_window)->impl);
|
||||
|
||||
/* Fix up the event to be less fake if possible. */
|
||||
current_event = [NSApp currentEvent];
|
||||
if (current_event)
|
||||
@ -1130,8 +1154,12 @@ _gdk_quartz_events_trigger_crossing_events (void)
|
||||
timestamp = [current_event timestamp];
|
||||
}
|
||||
|
||||
if (timestamp == 0)
|
||||
timestamp = GetCurrentEventTime ();
|
||||
|
||||
impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
|
||||
nsevent = [NSEvent otherEventWithType:NSApplicationDefined
|
||||
location:NSMakePoint(x, impl->height - y)
|
||||
location:NSMakePoint (x_toplevel, impl->height - y_toplevel)
|
||||
modifierFlags:flags
|
||||
timestamp:timestamp
|
||||
windowNumber:[impl->toplevel windowNumber]
|
||||
@ -1141,7 +1169,7 @@ _gdk_quartz_events_trigger_crossing_events (void)
|
||||
data2:0];
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
/*_gdk_quartz_window_debug_highlight (mouse_window);*/
|
||||
/*_gdk_quartz_window_debug_highlight (mouse_window, 0);*/
|
||||
#endif
|
||||
|
||||
synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, x, y);
|
||||
@ -1702,6 +1730,14 @@ gdk_event_translate (NSEvent *nsevent)
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle our generated "fake" crossing events. */
|
||||
if ([nsevent type] == NSApplicationDefined &&
|
||||
[nsevent subtype] == GDK_QUARTZ_EVENT_SUBTYPE_FAKE_CROSSING)
|
||||
{
|
||||
_gdk_quartz_events_trigger_crossing_events (FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Keep track of button state, since we don't get that information
|
||||
* for key events.
|
||||
*/
|
||||
|
@ -144,7 +144,8 @@ void _gdk_quartz_window_attach_to_parent (GdkWindow *window);
|
||||
void _gdk_quartz_window_detach_from_parent (GdkWindow *window);
|
||||
void _gdk_quartz_window_did_become_main (GdkWindow *window);
|
||||
void _gdk_quartz_window_did_resign_main (GdkWindow *window);
|
||||
void _gdk_quartz_window_debug_highlight (GdkWindow *window);
|
||||
void _gdk_quartz_window_debug_highlight (GdkWindow *window,
|
||||
gint number);
|
||||
|
||||
/* Events */
|
||||
typedef enum {
|
||||
@ -159,7 +160,7 @@ void _gdk_quartz_events_update_mouse_window (GdkWindow *window);
|
||||
void _gdk_quartz_events_update_cursor (GdkWindow *window);
|
||||
void _gdk_quartz_events_send_map_events (GdkWindow *window);
|
||||
GdkEventMask _gdk_quartz_events_get_current_event_mask (void);
|
||||
void _gdk_quartz_events_trigger_crossing_events(void);
|
||||
void _gdk_quartz_events_trigger_crossing_events(gboolean defer_to_mainloop);
|
||||
|
||||
extern GdkWindow *_gdk_quartz_keyboard_grab_window;
|
||||
extern GdkWindow *_gdk_quartz_pointer_grab_window;
|
||||
|
@ -538,22 +538,31 @@ get_ancestor_coordinates_from_child (GdkWindow *child_window,
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_quartz_window_debug_highlight (GdkWindow *window)
|
||||
_gdk_quartz_window_debug_highlight (GdkWindow *window, gint number)
|
||||
{
|
||||
GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
|
||||
GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
|
||||
gint x, y;
|
||||
GdkWindow *toplevel;
|
||||
gint tx, ty;
|
||||
static NSWindow *debug_window;
|
||||
static NSRect old_rect;
|
||||
static NSWindow *debug_window[10];
|
||||
static NSRect old_rect[10];
|
||||
NSRect rect;
|
||||
NSColor *color;
|
||||
|
||||
g_return_if_fail (number >= 0 && number <= 9);
|
||||
|
||||
if (window == _gdk_root)
|
||||
return;
|
||||
|
||||
if (window == NULL)
|
||||
return;
|
||||
{
|
||||
if (debug_window[number])
|
||||
[debug_window[number] close];
|
||||
debug_window[number] = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
toplevel = gdk_window_get_toplevel (window);
|
||||
get_ancestor_coordinates_from_child (window, 0, 0, toplevel, &x, &y);
|
||||
@ -562,37 +571,56 @@ _gdk_quartz_window_debug_highlight (GdkWindow *window)
|
||||
x += tx;
|
||||
y += ty;
|
||||
|
||||
rect = NSMakeRect (x,
|
||||
_gdk_quartz_window_get_inverted_screen_y (y + impl->height),
|
||||
impl->width, impl->height);
|
||||
rect = NSMakeRect (x,
|
||||
_gdk_quartz_window_get_inverted_screen_y (y + impl->height),
|
||||
impl->width, impl->height);
|
||||
|
||||
if (debug_window &&
|
||||
rect.origin.x == old_rect.origin.x &&
|
||||
rect.origin.y == old_rect.origin.y &&
|
||||
rect.size.width == old_rect.size.width &&
|
||||
rect.size.height == old_rect.size.height)
|
||||
if (debug_window[number] && NSEqualRects (rect, old_rect[number]))
|
||||
return;
|
||||
|
||||
old_rect[number] = rect;
|
||||
|
||||
if (debug_window[number])
|
||||
[debug_window[number] close];
|
||||
|
||||
debug_window[number] = [[NSWindow alloc] initWithContentRect:rect
|
||||
styleMask:NSBorderlessWindowMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
|
||||
switch (number)
|
||||
{
|
||||
return;
|
||||
case 0:
|
||||
color = [NSColor redColor];
|
||||
break;
|
||||
case 1:
|
||||
color = [NSColor blueColor];
|
||||
break;
|
||||
case 2:
|
||||
color = [NSColor greenColor];
|
||||
break;
|
||||
case 3:
|
||||
color = [NSColor yellowColor];
|
||||
break;
|
||||
case 4:
|
||||
color = [NSColor brownColor];
|
||||
break;
|
||||
case 5:
|
||||
color = [NSColor purpleColor];
|
||||
break;
|
||||
default:
|
||||
color = [NSColor blackColor];
|
||||
break;
|
||||
}
|
||||
|
||||
old_rect = rect;
|
||||
[debug_window[number] setBackgroundColor:color];
|
||||
[debug_window[number] setAlphaValue:0.4];
|
||||
[debug_window[number] setOpaque:NO];
|
||||
[debug_window[number] setReleasedWhenClosed:YES];
|
||||
[debug_window[number] setIgnoresMouseEvents:YES];
|
||||
[debug_window[number] setLevel:NSFloatingWindowLevel];
|
||||
|
||||
if (debug_window)
|
||||
[debug_window close];
|
||||
|
||||
debug_window = [[NSWindow alloc] initWithContentRect:rect
|
||||
styleMask:NSBorderlessWindowMask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
|
||||
[debug_window setBackgroundColor:[NSColor redColor]];
|
||||
[debug_window setAlphaValue:0.4];
|
||||
[debug_window setOpaque:NO];
|
||||
[debug_window setReleasedWhenClosed:YES];
|
||||
[debug_window setIgnoresMouseEvents:YES];
|
||||
[debug_window setLevel:NSFloatingWindowLevel];
|
||||
|
||||
[debug_window orderFront:nil];
|
||||
[debug_window[number] orderFront:nil];
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -1137,11 +1165,11 @@ show_window_internal (GdkWindow *window,
|
||||
if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
|
||||
_gdk_quartz_window_attach_to_parent (window);
|
||||
|
||||
/* Create a crossing event for managed windows that pop up under the
|
||||
* mouse. Part of the workarounds for problems with the tracking rect API.
|
||||
/* Create a crossing event for windows that pop up under the mouse. Part
|
||||
* of the workarounds for problems with the tracking rect API.
|
||||
*/
|
||||
if (impl->toplevel && private->window_type != GDK_WINDOW_TEMP)
|
||||
_gdk_quartz_events_trigger_crossing_events ();
|
||||
if (impl->toplevel)
|
||||
_gdk_quartz_events_trigger_crossing_events (TRUE);
|
||||
|
||||
GDK_QUARTZ_RELEASE_POOL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user