[gtk-vnc] Don't call into GDK when we don't have a GdkWindow yet



commit 910c4d40e32ba4c00f8e40ef8bb7e8f83c354045
Author: Christophe Fergeau <cfergeau redhat com>
Date:   Wed Aug 6 12:40:07 2014 +0200

    Don't call into GDK when we don't have a GdkWindow yet
    
    In some situations, virt-viewer will call some gtk-vnc methods while
    the gtk-vnc widget is not realized. This means it has no associated
    GdkWindow and that it's not possible to do GDK calls on this widget.
    Some of these gtk-vnc were trying to call into GDK without checking
    this, causing runtime warnings such as:
    
    (virt-viewer:29150): Gdk-CRITICAL **: gdk_window_set_cursor: assertion
    'GDK_IS_WINDOW (window)' failed
    
    or
    
    (virt-viewer:20076): Gdk-CRITICAL **: gdk_window_get_width: assertion
    `GDK_IS_WINDOW (window)' failed
    
    (virt-viewer:20076): Gdk-CRITICAL **: gdk_window_get_height: assertion
    `GDK_IS_WINDOW (window)' failed
    
      #0  g_logv (log_domain=0x3247a74066 "Gdk", log_level=G_LOG_LEVEL_CRITICAL,
          format=<optimized out>, args=args entry=0x7fffffffd1b0) at gmessages.c:1038
      #1  0x0000003a97450eff in g_log (
          log_domain=log_domain entry=0x3247a74066 "Gdk",
          log_level=log_level entry=G_LOG_LEVEL_CRITICAL,
          format=format entry=0x3a974bee3a "%s: assertion '%s' failed")
          at gmessages.c:1071
      #2  0x0000003a97450f39 in g_return_if_fail_warning (
          log_domain=log_domain entry=0x3247a74066 "Gdk",
          pretty_function=pretty_function entry=0x3247a8a320 <__FUNCTION__.33032> "gdk_window_get_width",
          expression=expression entry=0x3247a74794 "GDK_IS_WINDOW (window)")
          at gmessages.c:1080
      #3  0x0000003247a35ed4 in gdk_window_get_width (window=0x0) at gdkwindow.c:6093
      #4  0x00007ffff7dc5e73 in gdk_drawable_get_size (w=0x0, ww=0x7fffffffd2f0,
          wh=0x7fffffffd2f4) at vncdisplay.c:140
      #5  0x00007ffff7dcc183 in vnc_display_set_scaling (obj=0x9661e0 [VncDisplay],
          enable=1) at vncdisplay.c:2446
      #6  0x0000000000425555 in virt_viewer_display_vnc_new (
          vnc=0x9661e0 [VncDisplay]) at virt-viewer-display-vnc.c:191
      #7  0x00000000004241b3 in virt_viewer_session_vnc_disconnected (
          vnc=0x9661e0 [VncDisplay], session=0x962560 [VirtViewerSessionVnc])
          at virt-viewer-session-vnc.c:114
      #8  0x0000003944a10747 in _g_closure_invoke_va (
          closure=closure entry=0x6d2480, return_value=return_value entry=0x0,
          instance=instance entry=0x9661e0, args=args entry=0x7fffffffd560,
          n_params=0, param_types=0x0) at gclosure.c:831
      #9  0x0000003944a299d7 in g_signal_emit_valist (instance=0x9661e0,
          signal_id=<optimized out>, detail=0,
          var_args=var_args entry=0x7fffffffd560) at gsignal.c:3215
      #10 0x0000003944a2a63f in g_signal_emit (instance=<optimized out>,
          signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3363
      #11 0x00007ffff7dc9a60 in on_disconnected (conn=0x975cc0 [VncConnection],
          opaque=0x9661e0) at vncdisplay.c:1568
      #12 0x0000003944a10747 in _g_closure_invoke_va (
          closure=closure entry=0x6d2190, return_value=return_value entry=0x0,
          instance=instance entry=0x975cc0, args=args entry=0x7fffffffd850,
          n_params=0, param_types=0x0) at gclosure.c:831
      #13 0x0000003944a299d7 in g_signal_emit_valist (instance=0x975cc0,
          signal_id=<optimized out>, detail=0,
          var_args=var_args entry=0x7fffffffd850) at gsignal.c:3215
      #14 0x0000003944a2a63f in g_signal_emit (instance=<optimized out>,
          signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3363
      #15 0x00007ffff7ba419c in do_vnc_connection_emit_main_context (
          opaque=0x7fffed16ef40) at vncconnection.c:578
      #16 0x0000003a97449c3a in g_main_dispatch (context=0x68d280) at gmain.c:3064
      #17 g_main_context_dispatch (context=context entry=0x68d280) at gmain.c:3663
      #18 0x0000003a97449f88 in g_main_context_iterate (context=0x68d280,
          block=block entry=1, dispatch=dispatch entry=1, self=<optimized out>)
          at gmain.c:3734
      #19 0x0000003a9744a25a in g_main_loop_run (loop=0x74c560) at gmain.c:3928
    
    https://bugzilla.gnome.org/show_bug.cgi?id=734348

 src/vncdisplay.c |   42 +++++++++++++++++++++++++++++++++++++-----
 1 files changed, 37 insertions(+), 5 deletions(-)
---
diff --git a/src/vncdisplay.c b/src/vncdisplay.c
index 259c352..6f114a0 100644
--- a/src/vncdisplay.c
+++ b/src/vncdisplay.c
@@ -400,6 +400,9 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *expose)
 #if !GTK_CHECK_VERSION(3, 0, 0)
 static void do_keyboard_grab_all(GdkWindow *window)
 {
+    if (window == NULL)
+        return;
+
     gdk_keyboard_grab(window,
                       FALSE,
                       GDK_CURRENT_TIME);
@@ -411,6 +414,9 @@ static void do_keyboard_ungrab_all(GdkWindow *window G_GNUC_UNUSED)
 static void do_pointer_grab_all(GdkWindow *window,
                                 GdkCursor *cursor)
 {
+    if (window == NULL)
+        return;
+
     gdk_pointer_grab(window,
                      FALSE, /* All events to come to our window directly */
                      GDK_POINTER_MOTION_MASK |
@@ -527,15 +533,24 @@ static void do_keyboard_ungrab(VncDisplay *obj, gboolean quiet)
 static void do_pointer_hide(VncDisplay *obj)
 {
     VncDisplayPrivate *priv = obj->priv;
-    gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(obj)),
+    GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(obj));
+
+    if (window == NULL)
+        return;
+
+    gdk_window_set_cursor(window,
                           priv->remote_cursor ? priv->remote_cursor : priv->null_cursor);
 }
 
 static void do_pointer_show(VncDisplay *obj)
 {
     VncDisplayPrivate *priv = obj->priv;
-    gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(obj)),
-                          priv->remote_cursor);
+    GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(obj));
+
+    if (window == NULL)
+        return;
+
+    gdk_window_set_cursor(window, priv->remote_cursor);
 }
 
 static void do_pointer_grab(VncDisplay *obj, gboolean quiet)
@@ -1011,6 +1026,7 @@ static gboolean focus_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSE
     return TRUE;
 }
 
+
 static void grab_notify(GtkWidget *widget, gboolean was_grabbed)
 {
     if (was_grabbed == FALSE)
@@ -1018,6 +1034,16 @@ static void grab_notify(GtkWidget *widget, gboolean was_grabbed)
 }
 
 
+static void realize_event(GtkWidget *widget)
+{
+    VncDisplay *obj = VNC_DISPLAY(widget);
+    VncDisplayPrivate *priv = obj->priv;
+
+    gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(obj)),
+                          priv->remote_cursor ? priv->remote_cursor : priv->null_cursor);
+}
+
+
 static void on_framebuffer_update(VncConnection *conn G_GNUC_UNUSED,
                                   int x, int y, int w, int h,
                                   gpointer opaque)
@@ -1829,6 +1855,7 @@ static void vnc_display_class_init(VncDisplayClass *klass)
     gtkwidget_class->leave_notify_event = leave_event;
     gtkwidget_class->focus_out_event = focus_event;
     gtkwidget_class->grab_notify = grab_notify;
+    gtkwidget_class->realize = realize_event;
 
     object_class->finalize = vnc_display_finalize;
     object_class->get_property = vnc_display_get_property;
@@ -2452,8 +2479,13 @@ gboolean vnc_display_set_scaling(VncDisplay *obj,
     obj->priv->allow_scaling = enable;
 
     if (obj->priv->fb != NULL) {
-        gdk_drawable_get_size(gtk_widget_get_window(GTK_WIDGET(obj)), &ww, &wh);
-        gtk_widget_queue_draw_area(GTK_WIDGET(obj), 0, 0, ww, wh);
+        GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(obj));
+
+        if (window != NULL) {
+            gdk_drawable_get_size(gtk_widget_get_window(GTK_WIDGET(obj)),
+                                  &ww, &wh);
+            gtk_widget_queue_draw_area(GTK_WIDGET(obj), 0, 0, ww, wh);
+        }
     }
 
     return TRUE;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]