]> Pileus Git - ~andy/gtk/blobdiff - gdk/x11/gdkwindow-x11.c
Moveresize emulation for all edges. (#52833)
[~andy/gtk] / gdk / x11 / gdkwindow-x11.c
index 4e77cd7957d179c34f593e3609d1663d9fd9891a..f44dd3441baa87486c596c798eda16551dd2508c 100644 (file)
@@ -228,7 +228,7 @@ gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
   impl = GDK_WINDOW_IMPL_X11 (drawable);
   draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
 
-  if (GDK_WINDOW_DESTROYED (draw_impl->wrapper))
+  if (cmap && GDK_WINDOW_DESTROYED (draw_impl->wrapper))
     return;
 
   /* chain up */
@@ -294,7 +294,8 @@ _gdk_windowing_window_init (GdkScreen * screen)
 
   g_assert (screen_x11->root_window == NULL);
 
-  screen_x11->default_colormap = gdk_screen_get_system_colormap (screen);
+  gdk_screen_set_default_colormap (screen,
+                                  gdk_screen_get_system_colormap (screen));
 
   XGetGeometry (screen_x11->xdisplay, screen_x11->xroot_window,
                &screen_x11->xroot_window, &x, &y, &width, &height, &border_width, &depth);
@@ -309,6 +310,7 @@ _gdk_windowing_window_init (GdkScreen * screen)
   draw_impl->xid = screen_x11->xroot_window;
   draw_impl->wrapper = GDK_DRAWABLE (private);
   draw_impl->colormap = gdk_screen_get_system_colormap (screen);
+  g_object_ref (draw_impl->colormap);
   
   private->window_type = GDK_WINDOW_ROOT;
   private->depth = depth;
@@ -732,6 +734,8 @@ x_event_mask_to_gdk_event_mask (long mask)
  * 
  * Return value: the newly-created #GdkWindow wrapper for the 
  *    native window or %NULL if the window has been destroyed.
+ *
+ * Since: 2.2
  **/
 GdkWindow *
 gdk_window_foreign_new_for_display (GdkDisplay     *display,
@@ -818,6 +822,8 @@ gdk_window_foreign_new_for_display (GdkDisplay     *display,
  *
  * Return value: the #GdkWindow wrapper for the native window, 
  *    or %NULL if there is none.
+ *
+ * Since: 2.2
  **/
 GdkWindow *
 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
@@ -1662,7 +1668,7 @@ gdk_window_set_type_hint (GdkWindow        *window,
       atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY");
       break;
     case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
-      atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASHSCREEN");
+      atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH");
       break;
     case GDK_WINDOW_TYPE_HINT_DOCK:
       atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK");
@@ -1759,6 +1765,8 @@ gdk_window_set_modal_hint (GdkWindow *window,
  * function should NOT be called in addition, instead you should allow
  * the window to be treated according to standard policy for its
  * semantic type.
+ *
+ * Since: 2.2
  **/
 void
 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
@@ -1796,6 +1804,8 @@ gdk_window_set_skip_taskbar_hint (GdkWindow *window,
  * already fully describes the window, this function should NOT be
  * called in addition, instead you should allow the window to be
  * treated according to standard policy for its semantic type.
+ *
+ * Since: 2.2
  **/
 void
 gdk_window_set_skip_pager_hint (GdkWindow *window,
@@ -3593,6 +3603,7 @@ gdk_window_unmaximize (GdkWindow *window)
  * most standard window managers, and GDK makes a best effort to get
  * it to happen.
  *
+ * Since: 2.2
  **/
 void
 gdk_window_fullscreen (GdkWindow *window)
@@ -3626,8 +3637,9 @@ gdk_window_fullscreen (GdkWindow *window)
  * don't have a concept of "fullscreen"; so you can't rely on the
  * unfullscreenification actually happening. But it will happen with
  * most standard window managers, and GDK makes a best effort to get
- * it to happen.
- * 
+ * it to happen. 
+ *
+ * Since: 2.2
  **/
 void
 gdk_window_unfullscreen (GdkWindow *window)
@@ -4544,19 +4556,54 @@ update_pos (MoveResizeData *mv_resize,
 
   if (mv_resize->is_resize)
     {
-      gint w, h;
+      gint x, y, w, h;
+
+      x = mv_resize->moveresize_orig_x;
+      y = mv_resize->moveresize_orig_y;
 
       w = mv_resize->moveresize_orig_width;
       h = mv_resize->moveresize_orig_height;
 
       switch (mv_resize->resize_edge)
        {
+       case GDK_WINDOW_EDGE_NORTH_WEST:
+         x += dx;
+         y += dy;
+         w -= dx;
+         h -= dy;
+         break;
+       case GDK_WINDOW_EDGE_NORTH:
+         y += dy;
+         h -= dy;
+         break;
+       case GDK_WINDOW_EDGE_NORTH_EAST:
+         y += dy;
+         h -= dy;
+         w += dx;
+         break;
+       case GDK_WINDOW_EDGE_SOUTH_WEST:
+         h += dy;
+         x += dx;
+         w -= dx;
+         break;
        case GDK_WINDOW_EDGE_SOUTH_EAST:
          w += dx;
          h += dy;
          break;
+       case GDK_WINDOW_EDGE_SOUTH:
+         h += dy;
+         break;
+       case GDK_WINDOW_EDGE_EAST:
+         w += dx;
+         break;
+       case GDK_WINDOW_EDGE_WEST:
+         x += dx;
+         w -= dx;
+         break;
        }
 
+      x = MAX (x, 0);
+      y = MAX (y, 0);
       w = MAX (w, 1);
       h = MAX (h, 1);
 
@@ -4567,7 +4614,7 @@ update_pos (MoveResizeData *mv_resize,
                                     w, h, &w, &h);
        }
 
-      gdk_window_resize (mv_resize->moveresize_window, w, h);
+      gdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h);
     }
   else
     {
@@ -4650,7 +4697,7 @@ _gdk_moveresize_handle_event (XEvent *event)
 {
   guint button_mask = 0;
   GdkWindowObject *window_private;
-  GdkDisplay *display= gdk_x11_lookup_xdisplay (event->xany.display);
+  GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display);
   MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
 
   if (!mv_resize || !mv_resize->moveresize_window)
@@ -4771,6 +4818,78 @@ create_moveresize_window (MoveResizeData *mv_resize,
   mv_resize->moveresize_process_time = 0;
 }
 
+/* 
+   Calculate mv_resize->moveresize_orig_x and mv_resize->moveresize_orig_y
+   so that calling XMoveWindow with these coordinates will not move the 
+   window.
+   Note that this depends on the WM to implement ICCCM-compliant reference
+   point handling.
+*/
+static void 
+calculate_unmoving_origin (MoveResizeData *mv_resize)
+{
+  GdkRectangle rect;
+  gint width, height;
+
+  if (mv_resize->moveresize_geom_mask & GDK_HINT_WIN_GRAVITY &&
+      mv_resize->moveresize_geometry.win_gravity == GDK_GRAVITY_STATIC)
+    {
+      gdk_window_get_origin (mv_resize->moveresize_window,
+                            &mv_resize->moveresize_orig_x,
+                            &mv_resize->moveresize_orig_y);
+    }
+  else
+    {
+      gdk_window_get_frame_extents (mv_resize->moveresize_window, &rect);
+      gdk_window_get_geometry (mv_resize->moveresize_window, 
+                              NULL, NULL, &width, &height, NULL);
+      
+      switch (mv_resize->moveresize_geometry.win_gravity) 
+       {
+       case GDK_GRAVITY_NORTH_WEST:
+         mv_resize->moveresize_orig_x = rect.x;
+         mv_resize->moveresize_orig_y = rect.y;
+         break;
+       case GDK_GRAVITY_NORTH:
+         mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
+         mv_resize->moveresize_orig_y = rect.y;
+         break;          
+       case GDK_GRAVITY_NORTH_EAST:
+         mv_resize->moveresize_orig_x = rect.x + rect.width - width;
+         mv_resize->moveresize_orig_y = rect.y;
+         break;
+       case GDK_GRAVITY_WEST:
+         mv_resize->moveresize_orig_x = rect.x;
+         mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
+         break;
+       case GDK_GRAVITY_CENTER:
+         mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
+         mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
+         break;
+       case GDK_GRAVITY_EAST:
+         mv_resize->moveresize_orig_x = rect.x + rect.width - width;
+         mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
+         break;
+       case GDK_GRAVITY_SOUTH_WEST:
+         mv_resize->moveresize_orig_x = rect.x;
+         mv_resize->moveresize_orig_y = rect.y + rect.height - height;
+         break;
+       case GDK_GRAVITY_SOUTH:
+         mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
+         mv_resize->moveresize_orig_y = rect.y + rect.height - height;
+         break;
+       case GDK_GRAVITY_SOUTH_EAST:
+         mv_resize->moveresize_orig_x = rect.x + rect.width - width;
+         mv_resize->moveresize_orig_y = rect.y + rect.height - height;
+         break;
+       default:
+         mv_resize->moveresize_orig_x = rect.x;
+         mv_resize->moveresize_orig_y = rect.y;
+         break; 
+       }
+    }  
+}
+
 static void
 emulate_resize_drag (GdkWindow     *window,
                      GdkWindowEdge  edge,
@@ -4797,6 +4916,8 @@ emulate_resize_drag (GdkWindow     *window,
                                 &mv_resize->moveresize_geometry,
                                 &mv_resize->moveresize_geom_mask);
 
+  calculate_unmoving_origin (mv_resize);
+
   create_moveresize_window (mv_resize, timestamp);
 }
 
@@ -4816,9 +4937,7 @@ emulate_move_drag (GdkWindow     *window,
 
   mv_resize->moveresize_window = g_object_ref (window);
 
-  gdk_window_get_deskrelative_origin (mv_resize->moveresize_window,
-                                     &mv_resize->moveresize_orig_x,
-                                     &mv_resize->moveresize_orig_y);
+  calculate_unmoving_origin (mv_resize);
 
   create_moveresize_window (mv_resize, timestamp);
 }