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 */
|
||||
|
||||
if (getenv("GDK_NATIVE_WINDOWS"))
|
||||
_gdk_native_windows = TRUE;
|
||||
|
||||
g_type_init ();
|
||||
|
||||
/* Do any setup particular to the windowing system
|
||||
|
@ -836,6 +836,10 @@ synthesize_crossing_events (GdkDisplay *display,
|
||||
GdkWindow *src_toplevel, *dest_toplevel;
|
||||
GdkModifierType state;
|
||||
int x, y;
|
||||
|
||||
/* We use the native crossing events if all native */
|
||||
if (_gdk_native_windows)
|
||||
return;
|
||||
|
||||
if (src_window)
|
||||
src_toplevel = gdk_window_get_toplevel (src_window);
|
||||
|
@ -39,6 +39,7 @@ GList *_gdk_default_filters = NULL;
|
||||
gchar *_gdk_display_name = NULL;
|
||||
gint _gdk_screen_number = -1;
|
||||
gchar *_gdk_display_arg_name = NULL;
|
||||
gboolean _gdk_native_windows = FALSE;
|
||||
|
||||
GSList *_gdk_displays = NULL;
|
||||
|
||||
|
@ -107,6 +107,7 @@ extern gint _gdk_error_code;
|
||||
extern gint _gdk_error_warnings;
|
||||
|
||||
extern guint _gdk_debug_flags;
|
||||
extern gboolean _gdk_native_windows;
|
||||
|
||||
#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);
|
||||
|
||||
/* Remove all overlapping children from parent */
|
||||
remove_child_area (private->parent, private, FALSE, new_clip);
|
||||
/* Remove all overlapping children from parent.
|
||||
* 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 */
|
||||
@ -1093,8 +1099,11 @@ find_native_sibling_above (GdkWindowObject *parent,
|
||||
static GdkEventMask
|
||||
get_native_event_mask (GdkWindowObject *private)
|
||||
{
|
||||
if (private->window_type != GDK_WINDOW_ROOT &&
|
||||
private->window_type != GDK_WINDOW_FOREIGN)
|
||||
if (_gdk_native_windows ||
|
||||
private->window_type == GDK_WINDOW_ROOT ||
|
||||
private->window_type == GDK_WINDOW_FOREIGN)
|
||||
return private->event_mask;
|
||||
else
|
||||
{
|
||||
return
|
||||
/* 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_BUTTON3_MOTION_MASK));
|
||||
}
|
||||
else
|
||||
return private->event_mask;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
This is useful if some operation changed the stacking order. */
|
||||
* in the hierarchy, given the position it has in the client side data.
|
||||
* 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
|
||||
sync_native_window_stack_position (GdkWindow *window)
|
||||
{
|
||||
@ -1187,6 +1196,13 @@ gdk_window_new (GdkWindow *parent,
|
||||
if (GDK_WINDOW_DESTROYED (parent))
|
||||
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);
|
||||
private = (GdkWindowObject *) window;
|
||||
|
||||
@ -1288,7 +1304,7 @@ gdk_window_new (GdkWindow *parent,
|
||||
if (private->parent)
|
||||
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)
|
||||
native = TRUE; /* Always use native windows for toplevels */
|
||||
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
|
||||
* 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
|
||||
{
|
||||
@ -1432,7 +1449,7 @@ gdk_window_reparent (GdkWindow *window,
|
||||
GdkWindowObject *new_parent_private;
|
||||
GdkWindowObject *old_parent;
|
||||
GdkScreen *screen;
|
||||
gboolean show, was_toplevel, was_mapped;
|
||||
gboolean show, was_mapped;
|
||||
gboolean do_reparent_to_impl;
|
||||
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
@ -1476,7 +1493,6 @@ gdk_window_reparent (GdkWindow *window,
|
||||
private->redirect = NULL;
|
||||
}
|
||||
|
||||
was_toplevel = private->parent == NULL;
|
||||
was_mapped = GDK_WINDOW_IS_MAPPED (window);
|
||||
show = FALSE;
|
||||
|
||||
@ -1576,7 +1592,8 @@ gdk_window_reparent (GdkWindow *window,
|
||||
/* 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,
|
||||
* so restack */
|
||||
sync_native_window_stack_position (window);
|
||||
if (!gdk_window_has_impl (new_parent_private))
|
||||
sync_native_window_stack_position (window);
|
||||
}
|
||||
|
||||
if (show)
|
||||
@ -1645,8 +1662,9 @@ gdk_window_ensure_native (GdkWindow *window)
|
||||
change_impl (private, private, new_impl);
|
||||
|
||||
/* Native window creation 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 */
|
||||
* native parent, which may be wrong wrt the position of the previous
|
||||
* non-native window wrt to the other non-native children, so correct this.
|
||||
*/
|
||||
above = find_native_sibling_above (private->parent, private);
|
||||
if (above)
|
||||
{
|
||||
@ -2361,6 +2379,9 @@ gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
|
||||
|
||||
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))
|
||||
return FALSE; /* Implementation does double buffering */
|
||||
|
||||
@ -3263,8 +3284,8 @@ start_draw_helper (GdkDrawable *drawable,
|
||||
guarantee ordering. */
|
||||
gdk_window_flush ((GdkWindow *)drawable);
|
||||
|
||||
/* Don't clip when drawing to root */
|
||||
if (private->window_type != GDK_WINDOW_ROOT)
|
||||
/* Don't clip when drawing to root or all native */
|
||||
if (!_gdk_native_windows && private->window_type != GDK_WINDOW_ROOT)
|
||||
{
|
||||
if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN)
|
||||
clip = private->clip_region_with_children;
|
||||
@ -5928,7 +5949,13 @@ gdk_window_raise_internal (GdkWindow *window)
|
||||
|
||||
/* Just do native raise for toplevels */
|
||||
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);
|
||||
}
|
||||
@ -6203,7 +6230,13 @@ gdk_window_lower_internal (GdkWindow *window)
|
||||
|
||||
/* Just do native lower for toplevels */
|
||||
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);
|
||||
}
|
||||
@ -7244,7 +7277,8 @@ gdk_window_set_cursor (GdkWindow *window,
|
||||
if (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)
|
||||
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))
|
||||
@ -9005,6 +9039,11 @@ _gdk_display_set_window_under_pointer (GdkDisplay *display,
|
||||
{
|
||||
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;
|
||||
|
||||
if (display->pointer_info.window_under_pointer)
|
||||
@ -9073,7 +9112,10 @@ gdk_pointer_grab (GdkWindow * window,
|
||||
!gdk_window_is_viewable (window))
|
||||
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))
|
||||
{
|
||||
native = gdk_offscreen_window_get_embedder (native);
|
||||
@ -9178,6 +9220,9 @@ _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
|
||||
GdkWindow *toplevel;
|
||||
GdkWindowObject *toplevel_priv;
|
||||
|
||||
if (_gdk_native_windows)
|
||||
return; /* We use the native crossing events if all native */
|
||||
|
||||
display = gdk_drawable_get_display (changed_window);
|
||||
|
||||
toplevel = get_event_toplevel (changed_window);
|
||||
@ -9650,6 +9695,42 @@ _gdk_windowing_got_event (GdkDisplay *display,
|
||||
if (!event_window)
|
||||
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);
|
||||
|
||||
#ifdef DEBUG_WINDOW_PRINTING
|
||||
|
Loading…
Reference in New Issue
Block a user