metacity r4021 - in trunk: . src/core src/include



Author: tthurman
Date: Mon Nov 17 02:57:20 2008
New Revision: 4021
URL: http://svn.gnome.org/viewvc/metacity?rev=4021&view=rev

Log:
 	This change adds support for the new _NET_WM_FULLSCREEN_MONITORS
 	property and client message.  This allows client applications to request
 	that a fullscreen window cover more than one monitor.
 	* src/include/boxes.h:
	* src/core/boxes.c: Add meta_rectangle_union
 	* src/core/window-private.h:
	* src/core/window.c:
 	(meta_window_new_with_attrs, meta_window_free, set_net_wm_state,
 	meta_window_update_fullscreen_monitors, meta_window_client_message): Add
 	MetaWindow property to store fullscreen monitors field, update
 	_NET_WM_FULLSCREEN_MONITORS property on windows, and handle client
 	message.
 	* src/core/atomnames.h: Add _NET_WM_FULLSCREEN_MONITORS atom.
 	* src/core/constraints.c (setup_constraint_info): If
 	_NET_WM_FULLSCREEN_MONITORS is interesting, use the data stored in
 	MetaWindow::fullscreen_monitors to determine the fullscreen area instead
 	of the basic xinerama_info area.



Modified:
   trunk/ChangeLog
   trunk/src/core/atomnames.h
   trunk/src/core/boxes.c
   trunk/src/core/constraints.c
   trunk/src/core/window-private.h
   trunk/src/core/window.c
   trunk/src/include/boxes.h

Modified: trunk/src/core/atomnames.h
==============================================================================
--- trunk/src/core/atomnames.h	(original)
+++ trunk/src/core/atomnames.h	Mon Nov 17 02:57:20 2008
@@ -155,6 +155,7 @@
 item(_NET_WM_ACTION_ABOVE)
 item(_NET_WM_ACTION_BELOW)
 item(_NET_WM_STATE_STICKY)
+item(_NET_WM_FULLSCREEN_MONITORS)
 
 #if 0
 /* We apparently never use: */

Modified: trunk/src/core/boxes.c
==============================================================================
--- trunk/src/core/boxes.c	(original)
+++ trunk/src/core/boxes.c	Mon Nov 17 02:57:20 2008
@@ -197,6 +197,40 @@
           (src1->height == src2->height));
 }
 
+void
+meta_rectangle_union (const MetaRectangle *rect1,
+                      const MetaRectangle *rect2,
+                      MetaRectangle       *dest)
+{
+  int dest_x, dest_y;
+  int dest_w, dest_h;
+
+  dest_x = rect1->x;
+  dest_y = rect1->y;
+  dest_w = rect1->width;
+  dest_h = rect1->height;
+
+  if (rect2->x < dest_x)
+    {
+      dest_w += dest_x - rect2->x;
+      dest_x = rect2->x;
+    }
+  if (rect2->y < dest_y)
+    {
+      dest_h += dest_y - rect2->y;
+      dest_y = rect2->y;
+    }
+  if (rect2->x + rect2->width > dest_x + dest_w)
+    dest_w = rect2->x + rect2->width - dest_x;
+  if (rect2->y + rect2->height > dest_y + dest_h)
+    dest_h = rect2->y + rect2->height - dest_y;
+
+  dest->x = dest_x;
+  dest->y = dest_y;
+  dest->width = dest_w;
+  dest->height = dest_h;
+}
+
 gboolean
 meta_rectangle_overlap (const MetaRectangle *rect1,
                         const MetaRectangle *rect2)

Modified: trunk/src/core/constraints.c
==============================================================================
--- trunk/src/core/constraints.c	(original)
+++ trunk/src/core/constraints.c	Mon Nov 17 02:57:20 2008
@@ -392,7 +392,27 @@
   meta_window_get_work_area_for_xinerama (window,
                                           xinerama_info->number,
                                           &info->work_area_xinerama);
-  info->entire_xinerama = xinerama_info->rect;
+
+  if (!window->fullscreen || window->fullscreen_monitors[0] == -1)
+    {
+      info->entire_xinerama = xinerama_info->rect;
+    }
+  else
+    {
+      int i = 0;
+      long monitor;
+
+      monitor = window->fullscreen_monitors[i];
+      info->entire_xinerama =
+        window->screen->xinerama_infos[monitor].rect;
+      for (i = 1; i <= 3; i++)
+        {
+          monitor = window->fullscreen_monitors[i];
+          meta_rectangle_union (&info->entire_xinerama,
+                                &window->screen->xinerama_infos[monitor].rect,
+                                &info->entire_xinerama);
+        }
+    }
 
   cur_workspace = window->screen->active_workspace;
   info->usable_screen_region   = 
@@ -784,7 +804,9 @@
   /* Determine whether constraint applies; exit if it doesn't */
   if (!window->fullscreen)
     return TRUE;
+
   xinerama = info->entire_xinerama;
+
   get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
   too_big =   !meta_rectangle_could_fit_rect (&xinerama, &min_size);
   too_small = !meta_rectangle_could_fit_rect (&max_size, &xinerama);

Modified: trunk/src/core/window-private.h
==============================================================================
--- trunk/src/core/window-private.h	(original)
+++ trunk/src/core/window-private.h	Mon Nov 17 02:57:20 2008
@@ -143,6 +143,12 @@
 
   /* Whether we're fullscreen */
   guint fullscreen : 1;
+
+  /* Area to cover when in fullscreen mode.  If _NET_WM_FULLSCREEN_MONITORS has
+   * been overridden (via a client message), the window will cover the union of
+   * these monitors.  If not, this is the single monitor which the window's
+   * origin is on. */
+  long fullscreen_monitors[4];
   
   /* Whether we're trying to constrain the window to be fully onscreen */
   guint require_fully_onscreen : 1;
@@ -420,6 +426,11 @@
 void        meta_window_make_fullscreen_internal (MetaWindow    *window);
 void        meta_window_make_fullscreen    (MetaWindow  *window);
 void        meta_window_unmake_fullscreen  (MetaWindow  *window);
+void        meta_window_update_fullscreen_monitors (MetaWindow    *window,
+                                                    unsigned long  top,
+                                                    unsigned long  bottom,
+                                                    unsigned long  left,
+                                                    unsigned long  right);
 
 /* args to move are window pos, not frame pos */
 void        meta_window_move               (MetaWindow  *window,

Modified: trunk/src/core/window.c
==============================================================================
--- trunk/src/core/window.c	(original)
+++ trunk/src/core/window.c	Mon Nov 17 02:57:20 2008
@@ -249,7 +249,7 @@
   gulong existing_wm_state;
   gulong event_mask;
   MetaMoveResizeFlags flags;
-#define N_INITIAL_PROPS 18
+#define N_INITIAL_PROPS 19
   Atom initial_props[N_INITIAL_PROPS];
   int i;
   gboolean has_shape;
@@ -461,6 +461,7 @@
   window->maximize_vertically_after_placement = FALSE;
   window->minimize_after_placement = FALSE;
   window->fullscreen = FALSE;
+  window->fullscreen_monitors[0] = -1;
   window->require_fully_onscreen = TRUE;
   window->require_on_single_xinerama = TRUE;
   window->require_titlebar_visible = TRUE;
@@ -591,6 +592,7 @@
   initial_props[i++] = display->atom__MOTIF_WM_HINTS;
   initial_props[i++] = XA_WM_TRANSIENT_FOR;
   initial_props[i++] = display->atom__NET_WM_USER_TIME_WINDOW;
+  initial_props[i++] = display->atom__NET_WM_FULLSCREEN_MONITORS;
   g_assert (N_INITIAL_PROPS == i);
   
   meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
@@ -1115,6 +1117,9 @@
       XDeleteProperty (window->display->xdisplay,
                        window->xwindow,
                        window->display->atom__NET_WM_STATE);
+      XDeleteProperty (window->display->xdisplay,
+                       window->xwindow,
+                       window->display->atom__NET_WM_FULLSCREEN_MONITORS);
       set_wm_state (window, WithdrawnState);
       meta_error_trap_pop (window->display, FALSE);
     }
@@ -1300,6 +1305,23 @@
                    XA_ATOM,
                    32, PropModeReplace, (guchar*) data, i);
   meta_error_trap_pop (window->display, FALSE);
+
+  if (window->fullscreen)
+    {
+      data[0] = window->fullscreen_monitors[0];
+      data[1] = window->fullscreen_monitors[1];
+      data[2] = window->fullscreen_monitors[2];
+      data[3] = window->fullscreen_monitors[3];
+
+      meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n");
+      meta_error_trap_push (window->display);
+      XChangeProperty (window->display->xdisplay,
+                       window->xwindow,
+                       window->display->atom__NET_WM_FULLSCREEN_MONITORS,
+                       XA_CARDINAL, 32, PropModeReplace,
+                       (guchar*) data, 4);
+      meta_error_trap_pop (window->display, FALSE);
+    }
 }
 
 gboolean
@@ -2795,6 +2817,34 @@
 }
 
 void
+meta_window_update_fullscreen_monitors (MetaWindow    *window,
+                                        unsigned long  top,
+                                        unsigned long  bottom,
+                                        unsigned long  left,
+                                        unsigned long  right)
+{
+  if ((int)top < window->screen->n_xinerama_infos &&
+      (int)bottom < window->screen->n_xinerama_infos &&
+      (int)left < window->screen->n_xinerama_infos &&
+      (int)right < window->screen->n_xinerama_infos)
+    {
+      window->fullscreen_monitors[0] = top;
+      window->fullscreen_monitors[1] = bottom;
+      window->fullscreen_monitors[2] = left;
+      window->fullscreen_monitors[3] = right;
+    }
+  else
+    {
+      window->fullscreen_monitors[0] = -1;
+    }
+
+  if (window->fullscreen)
+    {
+      meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
+    }
+}
+
+void
 meta_window_shade (MetaWindow  *window,
                    guint32      timestamp)
 {
@@ -5144,6 +5194,23 @@
       window_activate (window, timestamp, source_indication, NULL);
       return TRUE;
     }
+  else if (event->xclient.message_type ==
+           display->atom__NET_WM_FULLSCREEN_MONITORS)
+    {
+      MetaClientType source_indication;
+      gulong top, bottom, left, right;
+
+      meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n",
+                    window->desc);
+
+      top = event->xclient.data.l[0];
+      bottom = event->xclient.data.l[1];
+      left = event->xclient.data.l[2];
+      right = event->xclient.data.l[3];
+      source_indication = event->xclient.data.l[4];
+
+      meta_window_update_fullscreen_monitors (window, top, bottom, left, right);
+    }
   
   return FALSE;
 }

Modified: trunk/src/include/boxes.h
==============================================================================
--- trunk/src/include/boxes.h	(original)
+++ trunk/src/include/boxes.h	Mon Nov 17 02:57:20 2008
@@ -103,6 +103,11 @@
 gboolean meta_rectangle_equal           (const MetaRectangle *src1,
                                          const MetaRectangle *src2);
 
+/* Find the bounding box of the union of two rectangles */
+void     meta_rectangle_union           (const MetaRectangle *rect1,
+                                         const MetaRectangle *rect2,
+                                         MetaRectangle       *dest);
+
 /* overlap is similar to intersect but doesn't provide location of
  * intersection information.
  */



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