Hello,
I've found out that implementation of GDK_WINDOW_OFFSCREEN has some unimplemented functions. This approach makes debbuging and searching for bugs really hard.
IMHO all function should be implemented, even if an implementation is dummy.
A proposed patch is attached. It's only proposal, but it works for me.
How did I get this opinion?
I use KDE desktop with oxygen-gtk widget style for GTK+ apps. I wanted to use glade-3.13.0 but glade is always crashing after clicking on the Window icon from the Toplevels toolbar.
What happens: 1. glade creates an offscreen window glade_design_layout_realize() : gladeui/glade-design-layout.c : 1630 attributes.window_type = GDK_WINDOW_OFFSCREEN;
2. glade_design_layout_realize() : gladeui/glade-design-layout.c : 1644 ipriv->offscreen_window = gdk_window_new (gtk_widget_get_root_window (widget), &attributes, attributes_mask);
3. gdk_window_new () : gdk/gdkwindow.c 11375 if (gdk_window_is_offscreen (window)) { _gdk_offscreen_window_new (window, attributes, attributes_mask);
4. gdk_window_is_offscreen() : gdk/gdkwindow.c : 11375 static gboolean gdk_window_is_offscreen (GdkWindow *window) { return window->window_type == GDK_WINDOW_OFFSCREEN; }
5. _gdk_offscreen_window_new() : gdk/gdkoffscreenwindow.c : 803 window->impl = g_object_new (GDK_TYPE_OFFSCREEN_WINDOW, NULL);
6. gdk_offscreen_window_class_init() : gdk/gdkoffscreenwindow.c : 766 impl_class->get_frame_extents = NULL;
-- Set implementation function to NULL.
-- And finally.
7. Gtk::gdk_toplevel_get_frame_size() : src/oxygengtkutils.cpp : 882 gdk_window_get_frame_extents( topLevel, &rect );
8. gdk_window_get_frame_extents() : gdk/gdkwindow.c : 10443 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_frame_extents (window, rect);
-- Ooops, get_frame_extents is NULL here
I'm not sure if implementation of oxygen-gtk should have special casing for GDK_WINDOW_OFFSCREEN like the following:
if( GdkWindow* topLevel = gdk_window_get_toplevel( window ) ) { if( GTK_IS_OFFSCREEN_WINDOW( topLevel ) ) { if( w ) *w = gdk_window_get_width(topLevel); if( h ) *h = gdk_window_get_height(topLevel); } else { GdkRectangle rect = {0, 0, -1, -1}; gdk_window_get_frame_extents( topLevel, &rect );
if( w ) *w = rect.width; if( h ) *h = rect.height; } }
Regards, Jakub |
>From f181760fbcd5511bacf4b9a041497c8fd63506e4 Mon Sep 17 00:00:00 2001 From: Jakub Filak <jfilak redhat com> Date: Mon, 11 Jun 2012 08:11:10 +0200 Subject: [PATCH] implement all methods of offscreen window impl class Signed-off-by: Jakub Filak <jfilak redhat com> --- gdk/gdkoffscreenwindow.c | 366 +++++++++++++++++++++++++++++++++++---- gdk/gdkwindow.h | 3 +- gdk/quartz/GdkQuartzNSWindow.c | 1 + gdk/quartz/gdkwindow-quartz.c | 2 + gdk/wayland/gdkwindow-wayland.c | 1 + gdk/x11/gdkwindow-x11.c | 3 + 6 files changed, 342 insertions(+), 34 deletions(-) diff --git a/gdk/gdkoffscreenwindow.c b/gdk/gdkoffscreenwindow.c index aed09e0..dfe77c2 100644 --- a/gdk/gdkoffscreenwindow.c +++ b/gdk/gdkoffscreenwindow.c @@ -674,36 +674,49 @@ gdk_offscreen_window_get_embedder (GdkWindow *window) static void gdk_offscreen_window_do_nothing (GdkWindow *window) { + g_warning ("GDK_WINDOW_OFFSCREEN not implements called function\n"); +} + +static void +gdk_offscreen_window_focus (GdkWindow *window, + guint32 timestamp) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'window_focus'\n"); } static void gdk_offscreen_window_set_boolean (GdkWindow *window, gboolean setting) { + g_warning ("GDK_WINDOW_OFFSCREEN not implements called function\n"); } static void gdk_offscreen_window_set_string (GdkWindow *window, const gchar *setting) { + g_warning ("GDK_WINDOW_OFFSCREEN not implements called function\n"); } static void gdk_offscreen_window_set_list (GdkWindow *window, GList *list) { + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'set_list'\n"); } static void gdk_offscreen_window_set_wmfunctions (GdkWindow *window, GdkWMFunction functions) { + g_warning ("GDK_WINDOW_OFFSCREEN not implements wmfunctions\n"); } static void gdk_offscreen_window_set_transient_for (GdkWindow *window, GdkWindow *another) { + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'transient_for'\n"); } static void @@ -714,6 +727,292 @@ gdk_offscreen_window_process_updates_recurse (GdkWindow *window, } static void +gdk_offscreen_window_restack_under (GdkWindow *window, + GList *native_siblings) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'restack_under'\n"); +} + +static void +gdk_offscreen_window_restack_toplevel (GdkWindow *window, + GdkWindow *sibling, + gboolean above) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'restack_toplevel'\n"); +} + +static void +gdk_offscreen_window_destroy_foreign (GdkWindow *window) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'destroy_foreign'\n"); +} + +static cairo_region_t * +gdk_offscreen_window_get_shape (GdkWindow *window) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'get_shape'\n"); + return NULL; +} + +static cairo_region_t * +gdk_offscreen_window_get_input_shape (GdkWindow *window) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'get_input_shape'\n"); + return NULL; +} + +static gboolean +gdk_offscreen_window_beep (GdkWindow *window) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'beep'\n"); + return FALSE; +} + +static void +gdk_offscreen_window_set_type_hint (GdkWindow *window, + GdkWindowTypeHint hint) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'set_type_hint'\n"); +} + +static GdkWindowTypeHint +gdk_offscreen_window_get_type_hint (GdkWindow *window) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'get_type_hint'\n"); + return GDK_WINDOW_TYPE_HINT_OFFSCREEN; +} + +static void +gdk_offscreen_window_set_modal_hint (GdkWindow *window, + gboolean modal) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'set_modal_hint'\n"); +} + +static void +gdk_offscreen_window_set_geometry_hints (GdkWindow *window, + const GdkGeometry *geometry, + GdkWindowHints geom_mask) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'geometry_hints'\n"); +} + +static void +gdk_offscreen_window_get_root_origin (GdkWindow *window, + gint *x, + gint *y) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (!GDK_IS_OFFSCREEN_WINDOW (window->impl)) + return; + + if (x) + *x = 0; + + if (y) + *y = 0; +} + +static void +gdk_offscreen_window_get_frame_extents (GdkWindow *window, + GdkRectangle *rect) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (!GDK_IS_OFFSCREEN_WINDOW (window->impl)) + return; + + if (rect) + { + rect->x = 0; + rect->y = 0; + rect->width = window->width; + rect->height = window->height; + } +} + +static void +gdk_offscreen_window_override_redirect (GdkWindow *window, + gboolean override_redirect) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'override_redirect'\n"); +} + +static void +gdk_offscreen_window_accept_focus (GdkWindow *window, + gboolean accept_focus) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'accept_focus'\n"); +} + +static GdkWindow * +gdk_offscreen_window_get_group (GdkWindow *window) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'get_group'\n"); + return window; +} + +static void +gdk_offscreen_window_set_group (GdkWindow *window, + GdkWindow *leader) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'set_group'\n"); +} + +static gboolean +gdk_offscreen_window_get_decorations (GdkWindow *window, + GdkWMDecoration *decorations) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'get_decorations'\n"); + return FALSE; +} + +static void +gdk_offscreen_window_set_decorations (GdkWindow *window, + GdkWMDecoration decorations) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'set_decorations'\n"); +} + +static void +gdk_offscreen_window_begin_resize_drag (GdkWindow *window, + GdkWindowEdge edge, + GdkDevice *device, + gint button, + gint root_x, + gint root_y, + guint32 timestamp) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'begin_resize_drag'\n"); +} + +static void +gdk_offscreen_window_move_drag (GdkWindow *window, + GdkDevice *device, + gint button, + gint root_x, + gint root_y, + guint32 timestamp) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'move_drag'\n"); +} + +static void +gdk_offscreen_window_configure_finished (GdkWindow *window) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'configure_finished'\n"); +} + +static void +gdk_offscreen_window_set_opacity (GdkWindow *window, + gdouble opacity) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'set_opacity'\n"); +} + +static void +gdk_offscreen_window_set_composited (GdkWindow *window, + gboolean composited) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'set_composited'\n"); +} + +static void +gdk_offscreen_window_set_destroy_notify (GdkWindow *window) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'set_destroy_notify'\n"); +} + +static GdkDragProtocol +gdk_offscreen_window_get_drag_protocol (GdkWindow *window, + GdkWindow **target) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'get_drag_protocol'\n"); + return GDK_DRAG_PROTO_NONE; +} + +static GdkDragContext * +gdk_offscreen_window_drag_begin (GdkWindow *window, + GdkDevice *device, + GList *targets) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'drag_begin'\n"); + return NULL; +} + +static void +gdk_offscreen_window_sync_rendering (GdkWindow *window) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'sync_rendering'\n"); +} + +static gboolean +gdk_offscreen_window_simulate_key (GdkWindow *window, + gint x, + gint y, + guint keyval, + GdkModifierType modifiers, + GdkEventType event_type) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'simulate_key'\n"); + return FALSE; +} + +static gboolean +gdk_offscreen_window_simulate_button (GdkWindow *window, + gint x, + gint y, + guint button, + GdkModifierType modifiers, + GdkEventType event_type) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'simulate_button'\n"); + return FALSE; +} + +static gboolean +gdk_offscreen_window_get_property (GdkWindow *window, + GdkAtom property, + GdkAtom type, + gulong offset, + gulong length, + gint pdelete, + GdkAtom *actual_type, + gint *actual_format, + gint *actual_length, + guchar **data) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'get_property'\n"); + return FALSE; +} + +static void +gdk_offscreen_window_change_property (GdkWindow *window, + GdkAtom property, + GdkAtom type, + gint format, + GdkPropMode mode, + const guchar *data, + gint n_elements) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'change_property'\n"); +} + +static void +gdk_offscreen_window_delete_property (GdkWindow *window, + GdkAtom property) +{ + g_warning ("GDK_WINDOW_OFFSCREEN not implements function 'delete_property'\n"); +} + +static void gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass) { GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass); @@ -729,8 +1028,8 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass) impl_class->get_events = gdk_offscreen_window_get_events; impl_class->raise = gdk_offscreen_window_raise; impl_class->lower = gdk_offscreen_window_lower; - impl_class->restack_under = NULL; - impl_class->restack_toplevel = NULL; + impl_class->restack_under = gdk_offscreen_window_restack_under; + impl_class->restack_toplevel = gdk_offscreen_window_restack_toplevel; impl_class->move_resize = gdk_offscreen_window_move_resize; impl_class->set_background = gdk_offscreen_window_set_background; impl_class->reparent = gdk_offscreen_window_reparent; @@ -744,28 +1043,28 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass) impl_class->queue_antiexpose = gdk_offscreen_window_queue_antiexpose; impl_class->translate = gdk_offscreen_window_translate; impl_class->destroy = gdk_offscreen_window_destroy; - impl_class->destroy_foreign = NULL; + impl_class->destroy_foreign = gdk_offscreen_window_destroy_foreign; impl_class->resize_cairo_surface = gdk_offscreen_window_resize_cairo_surface; - impl_class->get_shape = NULL; - impl_class->get_input_shape = NULL; - impl_class->beep = NULL; - - impl_class->focus = NULL; - impl_class->set_type_hint = NULL; - impl_class->get_type_hint = NULL; - impl_class->set_modal_hint = NULL; + impl_class->get_shape = gdk_offscreen_window_get_shape; + impl_class->get_input_shape = gdk_offscreen_window_get_input_shape; + impl_class->beep = gdk_offscreen_window_beep; + + impl_class->focus = gdk_offscreen_window_focus; + impl_class->set_type_hint = gdk_offscreen_window_set_type_hint; + impl_class->get_type_hint = gdk_offscreen_window_get_type_hint; + impl_class->set_modal_hint = gdk_offscreen_window_set_modal_hint; impl_class->set_skip_taskbar_hint = gdk_offscreen_window_set_boolean; impl_class->set_skip_pager_hint = gdk_offscreen_window_set_boolean; impl_class->set_urgency_hint = gdk_offscreen_window_set_boolean; - impl_class->set_geometry_hints = NULL; + impl_class->set_geometry_hints = gdk_offscreen_window_set_geometry_hints; impl_class->set_title = gdk_offscreen_window_set_string; impl_class->set_role = gdk_offscreen_window_set_string; impl_class->set_startup_id = gdk_offscreen_window_set_string; impl_class->set_transient_for = gdk_offscreen_window_set_transient_for; - impl_class->get_root_origin = NULL; - impl_class->get_frame_extents = NULL; - impl_class->set_override_redirect = NULL; - impl_class->set_accept_focus = NULL; + impl_class->get_root_origin = gdk_offscreen_window_get_root_origin; + impl_class->get_frame_extents = gdk_offscreen_window_get_frame_extents; + impl_class->set_override_redirect = gdk_offscreen_window_override_redirect; + impl_class->set_accept_focus = gdk_offscreen_window_accept_focus; impl_class->set_focus_on_map = gdk_offscreen_window_set_boolean; impl_class->set_icon_list = gdk_offscreen_window_set_list; impl_class->set_icon_name = gdk_offscreen_window_set_string; @@ -779,25 +1078,26 @@ gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass) impl_class->unfullscreen = gdk_offscreen_window_do_nothing; impl_class->set_keep_above = gdk_offscreen_window_set_boolean; impl_class->set_keep_below = gdk_offscreen_window_set_boolean; - impl_class->get_group = NULL; - impl_class->set_group = NULL; - impl_class->set_decorations = NULL; - impl_class->get_decorations = NULL; + impl_class->get_group = gdk_offscreen_window_get_group; + impl_class->set_group = gdk_offscreen_window_set_group; + impl_class->set_decorations = gdk_offscreen_window_set_decorations; + impl_class->get_decorations = gdk_offscreen_window_get_decorations; impl_class->set_functions = gdk_offscreen_window_set_wmfunctions; - impl_class->begin_resize_drag = NULL; - impl_class->begin_move_drag = NULL; + impl_class->begin_resize_drag = gdk_offscreen_window_begin_resize_drag; + impl_class->begin_move_drag = gdk_offscreen_window_move_drag; impl_class->enable_synchronized_configure = gdk_offscreen_window_do_nothing; - impl_class->configure_finished = NULL; - impl_class->set_opacity = NULL; - impl_class->set_composited = NULL; - impl_class->destroy_notify = NULL; + impl_class->configure_finished = gdk_offscreen_window_configure_finished; + impl_class->set_opacity = gdk_offscreen_window_set_opacity; + impl_class->set_composited = gdk_offscreen_window_set_composited; + impl_class->destroy_notify = gdk_offscreen_window_set_destroy_notify; + impl_class->get_drag_protocol = gdk_offscreen_window_get_drag_protocol; impl_class->register_dnd = gdk_offscreen_window_do_nothing; - impl_class->drag_begin = NULL; + impl_class->drag_begin = gdk_offscreen_window_drag_begin; impl_class->process_updates_recurse = gdk_offscreen_window_process_updates_recurse; - impl_class->sync_rendering = NULL; - impl_class->simulate_key = NULL; - impl_class->simulate_button = NULL; - impl_class->get_property = NULL; - impl_class->change_property = NULL; - impl_class->delete_property = NULL; + impl_class->sync_rendering = gdk_offscreen_window_sync_rendering; + impl_class->simulate_key = gdk_offscreen_window_simulate_key; + impl_class->simulate_button = gdk_offscreen_window_simulate_button; + impl_class->get_property = gdk_offscreen_window_get_property; + impl_class->change_property = gdk_offscreen_window_change_property; + impl_class->delete_property = gdk_offscreen_window_delete_property; } diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index fded029..5669f39 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -196,7 +196,8 @@ typedef enum GDK_WINDOW_TYPE_HINT_TOOLTIP, GDK_WINDOW_TYPE_HINT_NOTIFICATION, GDK_WINDOW_TYPE_HINT_COMBO, - GDK_WINDOW_TYPE_HINT_DND + GDK_WINDOW_TYPE_HINT_DND, + GDK_WINDOW_TYPE_HINT_OFFSCREEN } GdkWindowTypeHint; /* The next two enumeration values current match the diff --git a/gdk/quartz/GdkQuartzNSWindow.c b/gdk/quartz/GdkQuartzNSWindow.c index 76a759c..f2bb503 100644 --- a/gdk/quartz/GdkQuartzNSWindow.c +++ b/gdk/quartz/GdkQuartzNSWindow.c @@ -226,6 +226,7 @@ case GDK_WINDOW_TYPE_HINT_NOTIFICATION: case GDK_WINDOW_TYPE_HINT_COMBO: case GDK_WINDOW_TYPE_HINT_DND: + case GDK_WINDOW_TYPE_HINT_OFFSCREEN: return NO; } diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index fcfe7c1..cdc6e0f 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -2342,6 +2342,7 @@ gint window_type_hint_to_level (GdkWindowTypeHint hint) case GDK_WINDOW_TYPE_HINT_DIALOG: /* Dialog window */ case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */ case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */ + case GDK_WINDOW_TYPE_HINT_OFFSCREEN: /* N/A */ break; default: @@ -2372,6 +2373,7 @@ window_type_hint_to_shadow (GdkWindowTypeHint hint) case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */ case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */ case GDK_WINDOW_TYPE_HINT_DND: + case GDK_WINDOW_TYPE_HINT_OFFSCREEN: break; default: diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 4f56ccb..996bfb7 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -936,6 +936,7 @@ gdk_wayland_window_set_type_hint (GdkWindow *window, case GDK_WINDOW_TYPE_HINT_NOTIFICATION: case GDK_WINDOW_TYPE_HINT_COMBO: case GDK_WINDOW_TYPE_HINT_DND: + case GDK_WINDOW_TYPE_HINT_OFFSCREEN: break; default: g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint); diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 4ef6f46..03de22a 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -1895,6 +1895,9 @@ gdk_x11_window_set_type_hint (GdkWindow *window, case GDK_WINDOW_TYPE_HINT_DND: atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND"); break; + case GDK_WINDOW_TYPE_HINT_OFFSCREEN: + g_warning ("GDK_WINDOW_TYPE_HINT_OFFSCREEN passed to gdk_window_set_type_hint"); + break; default: g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint); /* Fall thru */ -- 1.7.10.2