]> Pileus Git - ~andy/gtk/blobdiff - gdk/gdkwindow.c
Fix a compatibility problem
[~andy/gtk] / gdk / gdkwindow.c
index b8055e9ee0fd8b0574207c624d88c11adeea3c0e..046dae927537ff5da98870e0597e8b747e0789a4 100644 (file)
@@ -276,6 +276,7 @@ static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
 static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable,
                                                         int width,
                                                         int height);
+static void             gdk_window_drop_cairo_surface (GdkWindowObject *private);
 static void             gdk_window_set_cairo_clip    (GdkDrawable *drawable,
                                                      cairo_t *cr);
 
@@ -480,6 +481,15 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
 
 
   /* Properties */
+
+  /**
+   * GdkWindow:cursor:
+   *
+   * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
+   * gdk_window_get_cursor() for details.
+   *
+   * Since: 2.18
+   */
   g_object_class_install_property (object_class,
                                    PROP_CURSOR,
                                    g_param_spec_boxed ("cursor",
@@ -1205,8 +1215,15 @@ get_native_event_mask (GdkWindowObject *private)
        * important thing, because in X only one client can do
        * so, and we don't want to unexpectedly prevent another
        * client from doing it.
+       *
+       * We also need to do the same if the app selects for button presses
+       * because then we will get implicit grabs for this window, and the
+       * event mask used for that grab is based on the rest of the mask
+       * for the window, but we might need more events than this window
+       * lists due to some non-native child window.
        */
-      if (gdk_window_is_toplevel (private))
+      if (gdk_window_is_toplevel (private) ||
+         mask & GDK_BUTTON_PRESS_MASK)
        mask |=
          GDK_POINTER_MOTION_MASK |
          GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
@@ -1256,7 +1273,7 @@ sync_native_window_stack_position (GdkWindow *window)
 
 /**
  * gdk_window_new:
- * @parent: a #GdkWindow, or %NULL to create the window as a child of
+ * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
  *   the default root window for the default display.
  * @attributes: attributes of the new window
  * @attributes_mask: mask indicating which fields in @attributes are valid
@@ -1266,7 +1283,7 @@ sync_native_window_stack_position (GdkWindow *window)
  * more details.  Note: to use this on displays other than the default
  * display, @parent must be specified.
  *
- * Return value: the new #GdkWindow
+ * Return value: (transfer none): the new #GdkWindow
  **/
 GdkWindow*
 gdk_window_new (GdkWindow     *parent,
@@ -1587,14 +1604,9 @@ gdk_window_reparent (GdkWindow *window,
   if (is_parent_of (window, new_parent))
     return;
 
-  if (private->cairo_surface)
-    {
-      /* This might be wrong in the new parent, e.g. for non-native surfaces.
-        To make sure we're ok, just wipe it. */
-      cairo_surface_finish (private->cairo_surface);
-      cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
-                                  NULL, NULL);
-    }
+  /* This might be wrong in the new parent, e.g. for non-native surfaces.
+     To make sure we're ok, just wipe it. */
+  gdk_window_drop_cairo_surface (private);
 
   impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
   old_parent = private->parent;
@@ -1754,7 +1766,7 @@ temporary_disable_extension_events (GdkWindowObject *window)
       child = l->data;
 
       if (window->impl_window == child->impl_window)
-       res |= temporary_disable_extension_events (window);
+       res |= temporary_disable_extension_events (child);
     }
 
   return res;
@@ -1846,6 +1858,8 @@ gdk_window_ensure_native (GdkWindow *window)
   if (impl_window->input_window)
     disabled_extension_events = temporary_disable_extension_events (private);
 
+  gdk_window_drop_cairo_surface (private);
+
   screen = gdk_drawable_get_screen (window);
   visual = gdk_drawable_get_visual (window);
 
@@ -1900,7 +1914,7 @@ gdk_window_ensure_native (GdkWindow *window)
     impl_iface->show (window, FALSE);
 
   if (disabled_extension_events)
-    temporary_enable_extension_events (private);
+    reenable_extension_events (private);
 
   return TRUE;
 }
@@ -2054,13 +2068,7 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
 
          _gdk_window_clear_update_area (window);
 
-         if (private->cairo_surface)
-           {
-             cairo_surface_finish (private->cairo_surface);
-             cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
-                                          NULL, NULL);
-           }
-
+         gdk_window_drop_cairo_surface (private);
 
          impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
 
@@ -2220,6 +2228,8 @@ gdk_window_get_window_type (GdkWindow *window)
  * Check to see if a window is destroyed..
  *
  * Return value: %TRUE if the window is destroyed
+ *
+ * Since: 2.18
  **/
 gboolean
 gdk_window_is_destroyed (GdkWindow *window)
@@ -2611,6 +2621,17 @@ gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
       private->implicit_paint != NULL)
     return FALSE; /* Don't stack implicit paints */
 
+  if (private->outstanding_surfaces != 0)
+    return FALSE; /* May conflict with direct drawing to cairo surface */
+
+  /* Never do implicit paints for foreign windows, they don't need
+   * double buffer combination since they have no client side children,
+   * and creating pixmaps for them is risky since they could disappear
+   * at any time
+   */
+  if (private->window_type == GDK_WINDOW_FOREIGN)
+    return FALSE;
+
   paint = g_new (GdkWindowPaint, 1);
   paint->region = gdk_region_new (); /* Empty */
   paint->x_offset = rect->x;
@@ -2660,7 +2681,7 @@ gdk_window_flush_implicit_paint (GdkWindow *window)
   gdk_region_offset (region, private->abs_x, private->abs_y);
   gdk_region_intersect (region, paint->region);
 
-  if (!gdk_region_empty (region))
+  if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (region))
     {
       /* Remove flushed region from the implicit paint */
       gdk_region_subtract (paint->region, region);
@@ -2693,7 +2714,7 @@ gdk_window_end_implicit_paint (GdkWindow *window)
 
   private->implicit_paint = NULL;
 
-  if (!gdk_region_empty (paint->region))
+  if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (paint->region))
     {
       /* Some regions are valid, push these to window now */
       tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE);
@@ -3308,7 +3329,7 @@ move_region_on_impl (GdkWindowObject *impl_window,
       gdk_region_destroy (exposing);
     }
 
-  if (1) /* Enable flicker free handling of moves. */
+  if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
     append_move_region (impl_window, region, dx, dy);
   else
     do_move_region_bits_on_impl (impl_window,
@@ -3448,12 +3469,12 @@ gdk_window_get_offsets (GdkWindow *window,
 /**
  * gdk_window_get_internal_paint_info:
  * @window: a #GdkWindow
- * @real_drawable: location to store the drawable to which drawing should be
+ * @real_drawable: (out): location to store the drawable to which drawing should be
  *            done.
- * @x_offset: location to store the X offset between coordinates in @window,
+ * @x_offset: (out): location to store the X offset between coordinates in @window,
  *            and the underlying window system primitive coordinates for
  *            *@real_drawable.
- * @y_offset: location to store the Y offset between coordinates in @window,
+ * @y_offset: (out): location to store the Y offset between coordinates in @window,
  *            and the underlying window system primitive coordinates for
  *            *@real_drawable.
  *
@@ -4559,7 +4580,7 @@ gdk_window_clear_area_internal (GdkWindow *window,
   region = gdk_region_rectangle (&rect);
   gdk_window_clear_region_internal (window,
                                    region,
-                                   FALSE);
+                                   send_expose);
   gdk_region_destroy (region);
 
 }
@@ -4821,12 +4842,24 @@ gdk_window_copy_to_image (GdkDrawable     *drawable,
                                     width, height);
 }
 
+static void
+gdk_window_drop_cairo_surface (GdkWindowObject *private)
+{
+  if (private->cairo_surface)
+    {
+      cairo_surface_finish (private->cairo_surface);
+      cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
+                                  NULL, NULL);
+    }
+}
+
 static void
 gdk_window_cairo_surface_destroy (void *data)
 {
   GdkWindowObject *private = (GdkWindowObject*) data;
 
   private->cairo_surface = NULL;
+  private->impl_window->outstanding_surfaces--;
 }
 
 static cairo_surface_t *
@@ -4870,11 +4903,12 @@ gdk_window_ref_cairo_surface (GdkDrawable *drawable)
 
          source = _gdk_drawable_get_source_drawable (drawable);
 
-         /* TODO: Avoid the typecheck crap by adding virtual call */
          private->cairo_surface = _gdk_drawable_create_cairo_surface (source, width, height);
 
          if (private->cairo_surface)
            {
+             private->impl_window->outstanding_surfaces++;
+
              cairo_surface_set_device_offset (private->cairo_surface,
                                               private->abs_x,
                                               private->abs_y);
@@ -6191,18 +6225,18 @@ gdk_window_constrain_size (GdkGeometry *geometry,
 /**
  * gdk_window_get_pointer:
  * @window: a #GdkWindow
- * @x: return location for X coordinate of pointer or %NULL to not
+ * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
  *      return the X coordinate
- * @y: return location for Y coordinate of pointer or %NULL to not
+ * @y: (out) (allow-none):  return location for Y coordinate of pointer or %NULL to not
  *      return the Y coordinate
- * @mask: return location for modifier mask or %NULL to not return the
+ * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
  *      modifier mask
  *
  * Obtains the current pointer position and modifier state.
  * The position is given in coordinates relative to the upper left
  * corner of @window.
  *
- * Return value: the window containing the pointer (as with
+ * Return value: (transfer none): the window containing the pointer (as with
  * gdk_window_at_pointer()), or %NULL if the window containing the
  * pointer isn't known to GDK
  **/
@@ -6251,8 +6285,8 @@ gdk_window_get_pointer (GdkWindow   *window,
 
 /**
  * gdk_window_at_pointer:
- * @win_x: return location for origin of the window under the pointer
- * @win_y: return location for origin of the window under the pointer
+ * @win_x: (out) (allow-none): return location for origin of the window under the pointer
+ * @win_y: (out) (allow-none): return location for origin of the window under the pointer
  *
  * Obtains the window underneath the mouse pointer, returning the
  * location of that window in @win_x, @win_y. Returns %NULL if the
@@ -6263,7 +6297,7 @@ gdk_window_get_pointer (GdkWindow   *window,
  * NOTE: For multihead-aware widgets or applications use
  * gdk_display_get_window_at_pointer() instead.
  *
- * Return value: window under the mouse pointer
+ * Return value: (transfer none): window under the mouse pointer
  **/
 GdkWindow*
 gdk_window_at_pointer (gint *win_x,
@@ -8012,6 +8046,8 @@ gdk_window_get_origin (GdkWindow *window,
  * window coordinates. This is similar to
  * gdk_window_get_origin() but allows you go pass
  * in any position in the window, not just the origin.
+ *
+ * Since: 2.18
  */
 void
 gdk_window_get_root_coords (GdkWindow *window,