Add support for enabling only native windows
Some applications make weird assumtions on Gtk+ that do not work anymore with the new client-side windows support. For instance SWT/Eclipse reorders the stacking order of the X windows directly without telling gdk this, which breaks gdk drawing as gdk now relies on knowing the stacking order for window clipping. This introduces a GDK_NATIVE_WINDOWS environment variable, which if set causes Gtk+ to always use native windows. Its more compatible with pre-csw Gtk+ behaviour if you do weird X-specific hacks, although it does limit the size of GdkWindows to 65535x65535.
This commit is contained in:
parent
deda8b97f6
commit
a79f929dd6
@ -206,6 +206,9 @@ gdk_pre_parse_libgtk_only (void)
|
|||||||
}
|
}
|
||||||
#endif /* G_ENABLE_DEBUG */
|
#endif /* G_ENABLE_DEBUG */
|
||||||
|
|
||||||
|
if (getenv("GDK_NATIVE_WINDOWS"))
|
||||||
|
_gdk_native_windows = TRUE;
|
||||||
|
|
||||||
g_type_init ();
|
g_type_init ();
|
||||||
|
|
||||||
/* Do any setup particular to the windowing system
|
/* Do any setup particular to the windowing system
|
||||||
|
@ -836,6 +836,10 @@ synthesize_crossing_events (GdkDisplay *display,
|
|||||||
GdkWindow *src_toplevel, *dest_toplevel;
|
GdkWindow *src_toplevel, *dest_toplevel;
|
||||||
GdkModifierType state;
|
GdkModifierType state;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
|
/* We use the native crossing events if all native */
|
||||||
|
if (_gdk_native_windows)
|
||||||
|
return;
|
||||||
|
|
||||||
if (src_window)
|
if (src_window)
|
||||||
src_toplevel = gdk_window_get_toplevel (src_window);
|
src_toplevel = gdk_window_get_toplevel (src_window);
|
||||||
|
@ -39,6 +39,7 @@ GList *_gdk_default_filters = NULL;
|
|||||||
gchar *_gdk_display_name = NULL;
|
gchar *_gdk_display_name = NULL;
|
||||||
gint _gdk_screen_number = -1;
|
gint _gdk_screen_number = -1;
|
||||||
gchar *_gdk_display_arg_name = NULL;
|
gchar *_gdk_display_arg_name = NULL;
|
||||||
|
gboolean _gdk_native_windows = FALSE;
|
||||||
|
|
||||||
GSList *_gdk_displays = NULL;
|
GSList *_gdk_displays = NULL;
|
||||||
|
|
||||||
|
@ -107,6 +107,7 @@ extern gint _gdk_error_code;
|
|||||||
extern gint _gdk_error_warnings;
|
extern gint _gdk_error_warnings;
|
||||||
|
|
||||||
extern guint _gdk_debug_flags;
|
extern guint _gdk_debug_flags;
|
||||||
|
extern gboolean _gdk_native_windows;
|
||||||
|
|
||||||
#ifdef G_ENABLE_DEBUG
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
|
||||||
|
123
gdk/gdkwindow.c
123
gdk/gdkwindow.c
@ -866,8 +866,14 @@ recompute_visible_regions_internal (GdkWindowObject *private,
|
|||||||
{
|
{
|
||||||
gdk_region_intersect (new_clip, private->parent->clip_region);
|
gdk_region_intersect (new_clip, private->parent->clip_region);
|
||||||
|
|
||||||
/* Remove all overlapping children from parent */
|
/* Remove all overlapping children from parent.
|
||||||
remove_child_area (private->parent, private, FALSE, new_clip);
|
* Unless we're all native, because then we don't need to take
|
||||||
|
* siblings into account since X does that clipping for us.
|
||||||
|
* This makes things like SWT that modify the raw X stacking
|
||||||
|
* order without GDKs knowledge work.
|
||||||
|
*/
|
||||||
|
if (!_gdk_native_windows)
|
||||||
|
remove_child_area (private->parent, private, FALSE, new_clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert from parent coords to window coords */
|
/* Convert from parent coords to window coords */
|
||||||
@ -1093,8 +1099,11 @@ find_native_sibling_above (GdkWindowObject *parent,
|
|||||||
static GdkEventMask
|
static GdkEventMask
|
||||||
get_native_event_mask (GdkWindowObject *private)
|
get_native_event_mask (GdkWindowObject *private)
|
||||||
{
|
{
|
||||||
if (private->window_type != GDK_WINDOW_ROOT &&
|
if (_gdk_native_windows ||
|
||||||
private->window_type != GDK_WINDOW_FOREIGN)
|
private->window_type == GDK_WINDOW_ROOT ||
|
||||||
|
private->window_type == GDK_WINDOW_FOREIGN)
|
||||||
|
return private->event_mask;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
/* We need thse for all native window so we can emulate
|
/* We need thse for all native window so we can emulate
|
||||||
@ -1116,13 +1125,13 @@ get_native_event_mask (GdkWindowObject *private)
|
|||||||
GDK_BUTTON2_MOTION_MASK |
|
GDK_BUTTON2_MOTION_MASK |
|
||||||
GDK_BUTTON3_MOTION_MASK));
|
GDK_BUTTON3_MOTION_MASK));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return private->event_mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Puts the native window in the right order wrt the other native windows
|
/* Puts the native window in the right order wrt the other native windows
|
||||||
in the hierarchy, given the position it has in the client side data.
|
* in the hierarchy, given the position it has in the client side data.
|
||||||
This is useful if some operation changed the stacking order. */
|
* This is useful if some operation changed the stacking order.
|
||||||
|
* This calls assumes the native window is now topmost in its native parent.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
sync_native_window_stack_position (GdkWindow *window)
|
sync_native_window_stack_position (GdkWindow *window)
|
||||||
{
|
{
|
||||||
@ -1187,6 +1196,13 @@ gdk_window_new (GdkWindow *parent,
|
|||||||
if (GDK_WINDOW_DESTROYED (parent))
|
if (GDK_WINDOW_DESTROYED (parent))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
|
||||||
|
_gdk_native_windows)
|
||||||
|
{
|
||||||
|
g_warning ("Offscreen windows not supported with native-windows gdk");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
window = g_object_new (GDK_TYPE_WINDOW, NULL);
|
window = g_object_new (GDK_TYPE_WINDOW, NULL);
|
||||||
private = (GdkWindowObject *) window;
|
private = (GdkWindowObject *) window;
|
||||||
|
|
||||||
@ -1288,7 +1304,7 @@ gdk_window_new (GdkWindow *parent,
|
|||||||
if (private->parent)
|
if (private->parent)
|
||||||
private->parent->children = g_list_prepend (private->parent->children, window);
|
private->parent->children = g_list_prepend (private->parent->children, window);
|
||||||
|
|
||||||
native = FALSE; /* Default */
|
native = _gdk_native_windows; /* Default */
|
||||||
if (private->parent->window_type == GDK_WINDOW_ROOT)
|
if (private->parent->window_type == GDK_WINDOW_ROOT)
|
||||||
native = TRUE; /* Always use native windows for toplevels */
|
native = TRUE; /* Always use native windows for toplevels */
|
||||||
else if (!private->input_only &&
|
else if (!private->input_only &&
|
||||||
@ -1313,7 +1329,8 @@ gdk_window_new (GdkWindow *parent,
|
|||||||
|
|
||||||
/* This will put the native window topmost in the native parent, which may
|
/* This will put the native window topmost in the native parent, which may
|
||||||
* be wrong wrt other native windows in the non-native hierarchy, so restack */
|
* be wrong wrt other native windows in the non-native hierarchy, so restack */
|
||||||
sync_native_window_stack_position (window);
|
if (!_gdk_window_has_impl (real_parent))
|
||||||
|
sync_native_window_stack_position (window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1432,7 +1449,7 @@ gdk_window_reparent (GdkWindow *window,
|
|||||||
GdkWindowObject *new_parent_private;
|
GdkWindowObject *new_parent_private;
|
||||||
GdkWindowObject *old_parent;
|
GdkWindowObject *old_parent;
|
||||||
GdkScreen *screen;
|
GdkScreen *screen;
|
||||||
gboolean show, was_toplevel, was_mapped;
|
gboolean show, was_mapped;
|
||||||
gboolean do_reparent_to_impl;
|
gboolean do_reparent_to_impl;
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||||
@ -1476,7 +1493,6 @@ gdk_window_reparent (GdkWindow *window,
|
|||||||
private->redirect = NULL;
|
private->redirect = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
was_toplevel = private->parent == NULL;
|
|
||||||
was_mapped = GDK_WINDOW_IS_MAPPED (window);
|
was_mapped = GDK_WINDOW_IS_MAPPED (window);
|
||||||
show = FALSE;
|
show = FALSE;
|
||||||
|
|
||||||
@ -1576,7 +1592,8 @@ gdk_window_reparent (GdkWindow *window,
|
|||||||
/* The reparent will have put the native window topmost in the native parent,
|
/* The reparent will have put the native window topmost in the native parent,
|
||||||
* which may be wrong wrt other native windows in the non-native hierarchy,
|
* which may be wrong wrt other native windows in the non-native hierarchy,
|
||||||
* so restack */
|
* so restack */
|
||||||
sync_native_window_stack_position (window);
|
if (!gdk_window_has_impl (new_parent_private))
|
||||||
|
sync_native_window_stack_position (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show)
|
if (show)
|
||||||
@ -1645,8 +1662,9 @@ gdk_window_ensure_native (GdkWindow *window)
|
|||||||
change_impl (private, private, new_impl);
|
change_impl (private, private, new_impl);
|
||||||
|
|
||||||
/* Native window creation will put the native window topmost in the
|
/* Native window creation will put the native window topmost in the
|
||||||
* native parent, which may be wrong wrt other native windows in the
|
* native parent, which may be wrong wrt the position of the previous
|
||||||
* non-native hierarchy, so restack */
|
* non-native window wrt to the other non-native children, so correct this.
|
||||||
|
*/
|
||||||
above = find_native_sibling_above (private->parent, private);
|
above = find_native_sibling_above (private->parent, private);
|
||||||
if (above)
|
if (above)
|
||||||
{
|
{
|
||||||
@ -2361,6 +2379,9 @@ gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
|
|||||||
|
|
||||||
g_assert (gdk_window_has_impl (private));
|
g_assert (gdk_window_has_impl (private));
|
||||||
|
|
||||||
|
if (_gdk_native_windows)
|
||||||
|
return FALSE; /* No need for implicit paints since we can't merge draws anyway */
|
||||||
|
|
||||||
if (GDK_IS_PAINTABLE (private->impl))
|
if (GDK_IS_PAINTABLE (private->impl))
|
||||||
return FALSE; /* Implementation does double buffering */
|
return FALSE; /* Implementation does double buffering */
|
||||||
|
|
||||||
@ -3263,8 +3284,8 @@ start_draw_helper (GdkDrawable *drawable,
|
|||||||
guarantee ordering. */
|
guarantee ordering. */
|
||||||
gdk_window_flush ((GdkWindow *)drawable);
|
gdk_window_flush ((GdkWindow *)drawable);
|
||||||
|
|
||||||
/* Don't clip when drawing to root */
|
/* Don't clip when drawing to root or all native */
|
||||||
if (private->window_type != GDK_WINDOW_ROOT)
|
if (!_gdk_native_windows && private->window_type != GDK_WINDOW_ROOT)
|
||||||
{
|
{
|
||||||
if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
|
if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
|
||||||
clip = private->clip_region_with_children;
|
clip = private->clip_region_with_children;
|
||||||
@ -5928,7 +5949,13 @@ gdk_window_raise_internal (GdkWindow *window)
|
|||||||
|
|
||||||
/* Just do native raise for toplevels */
|
/* Just do native raise for toplevels */
|
||||||
if (private->parent == NULL ||
|
if (private->parent == NULL ||
|
||||||
private->parent->window_type == GDK_WINDOW_ROOT)
|
private->parent->window_type == GDK_WINDOW_ROOT ||
|
||||||
|
/* The restack_under codepath should work correctly even if the parent
|
||||||
|
is native, but it relies on the order of ->children to be correct,
|
||||||
|
and some apps like SWT reorder the x windows without gdks knowledge,
|
||||||
|
so we use raise directly in order to make these behave as before
|
||||||
|
when using native windows */
|
||||||
|
(gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
|
||||||
{
|
{
|
||||||
GDK_WINDOW_IMPL_GET_IFACE (private->impl)->raise (window);
|
GDK_WINDOW_IMPL_GET_IFACE (private->impl)->raise (window);
|
||||||
}
|
}
|
||||||
@ -6203,7 +6230,13 @@ gdk_window_lower_internal (GdkWindow *window)
|
|||||||
|
|
||||||
/* Just do native lower for toplevels */
|
/* Just do native lower for toplevels */
|
||||||
if (private->parent == NULL ||
|
if (private->parent == NULL ||
|
||||||
private->parent->window_type == GDK_WINDOW_ROOT)
|
private->parent->window_type == GDK_WINDOW_ROOT ||
|
||||||
|
/* The restack_under codepath should work correctly even if the parent
|
||||||
|
is native, but it relies on the order of ->children to be correct,
|
||||||
|
and some apps like SWT reorder the x windows without gdks knowledge,
|
||||||
|
so we use lower directly in order to make these behave as before
|
||||||
|
when using native windows */
|
||||||
|
(gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
|
||||||
{
|
{
|
||||||
GDK_WINDOW_IMPL_GET_IFACE (private->impl)->lower (window);
|
GDK_WINDOW_IMPL_GET_IFACE (private->impl)->lower (window);
|
||||||
}
|
}
|
||||||
@ -7244,7 +7277,8 @@ gdk_window_set_cursor (GdkWindow *window,
|
|||||||
if (cursor)
|
if (cursor)
|
||||||
private->cursor = gdk_cursor_ref (cursor);
|
private->cursor = gdk_cursor_ref (cursor);
|
||||||
|
|
||||||
if (private->window_type == GDK_WINDOW_ROOT ||
|
if (_gdk_native_windows ||
|
||||||
|
private->window_type == GDK_WINDOW_ROOT ||
|
||||||
private->window_type == GDK_WINDOW_FOREIGN)
|
private->window_type == GDK_WINDOW_FOREIGN)
|
||||||
GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_cursor (window, cursor);
|
GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_cursor (window, cursor);
|
||||||
else if (_gdk_window_event_parent_of (window, display->pointer_info.window_under_pointer))
|
else if (_gdk_window_event_parent_of (window, display->pointer_info.window_under_pointer))
|
||||||
@ -9005,6 +9039,11 @@ _gdk_display_set_window_under_pointer (GdkDisplay *display,
|
|||||||
{
|
{
|
||||||
GdkWindowObject *private;
|
GdkWindowObject *private;
|
||||||
|
|
||||||
|
/* We don't track this if all native, and it can cause issues
|
||||||
|
with the update_cursor call below */
|
||||||
|
if (_gdk_native_windows)
|
||||||
|
return;
|
||||||
|
|
||||||
private = (GdkWindowObject *)window;
|
private = (GdkWindowObject *)window;
|
||||||
|
|
||||||
if (display->pointer_info.window_under_pointer)
|
if (display->pointer_info.window_under_pointer)
|
||||||
@ -9073,7 +9112,10 @@ gdk_pointer_grab (GdkWindow * window,
|
|||||||
!gdk_window_is_viewable (window))
|
!gdk_window_is_viewable (window))
|
||||||
return GDK_GRAB_NOT_VIEWABLE;
|
return GDK_GRAB_NOT_VIEWABLE;
|
||||||
|
|
||||||
native = gdk_window_get_toplevel (window);
|
if (_gdk_native_windows)
|
||||||
|
native = window;
|
||||||
|
else
|
||||||
|
native = gdk_window_get_toplevel (window);
|
||||||
while (gdk_window_is_offscreen ((GdkWindowObject *)native))
|
while (gdk_window_is_offscreen ((GdkWindowObject *)native))
|
||||||
{
|
{
|
||||||
native = gdk_offscreen_window_get_embedder (native);
|
native = gdk_offscreen_window_get_embedder (native);
|
||||||
@ -9178,6 +9220,9 @@ _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
|
|||||||
GdkWindow *toplevel;
|
GdkWindow *toplevel;
|
||||||
GdkWindowObject *toplevel_priv;
|
GdkWindowObject *toplevel_priv;
|
||||||
|
|
||||||
|
if (_gdk_native_windows)
|
||||||
|
return; /* We use the native crossing events if all native */
|
||||||
|
|
||||||
display = gdk_drawable_get_display (changed_window);
|
display = gdk_drawable_get_display (changed_window);
|
||||||
|
|
||||||
toplevel = get_event_toplevel (changed_window);
|
toplevel = get_event_toplevel (changed_window);
|
||||||
@ -9650,6 +9695,42 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
|||||||
if (!event_window)
|
if (!event_window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_gdk_native_windows)
|
||||||
|
{
|
||||||
|
if (event->type == GDK_BUTTON_PRESS &&
|
||||||
|
_gdk_display_has_pointer_grab (display, serial) == NULL)
|
||||||
|
{
|
||||||
|
_gdk_display_add_pointer_grab (display,
|
||||||
|
event_window,
|
||||||
|
event_window,
|
||||||
|
FALSE,
|
||||||
|
gdk_window_get_events (event_window),
|
||||||
|
serial,
|
||||||
|
gdk_event_get_time (event),
|
||||||
|
TRUE);
|
||||||
|
_gdk_display_pointer_grab_update (display,
|
||||||
|
serial);
|
||||||
|
}
|
||||||
|
if (event->type == GDK_BUTTON_RELEASE)
|
||||||
|
{
|
||||||
|
button_release_grab =
|
||||||
|
_gdk_display_has_pointer_grab (display, serial);
|
||||||
|
if (button_release_grab &&
|
||||||
|
button_release_grab->implicit &&
|
||||||
|
(event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
|
||||||
|
{
|
||||||
|
button_release_grab->serial_end = serial;
|
||||||
|
button_release_grab->implicit_ungrab = TRUE;
|
||||||
|
_gdk_display_pointer_grab_update (display, serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event->type == GDK_BUTTON_PRESS)
|
||||||
|
_gdk_event_button_generate (display, event);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event_private = GDK_WINDOW_OBJECT (event_window);
|
event_private = GDK_WINDOW_OBJECT (event_window);
|
||||||
|
|
||||||
#ifdef DEBUG_WINDOW_PRINTING
|
#ifdef DEBUG_WINDOW_PRINTING
|
||||||
|
Loading…
Reference in New Issue
Block a user