[metacity] window placement in xinerama (second)



Here is a second patch, which will in some cases place the new window on
the current xinerama screen rather than on the screen 0. This seems more
user-friendly, and addresses a FIXME comment in the code.

This patch includes a second, more controversial part: I have added a
constant which will force the window to always be placed on the current
xinerama screen, even if it has to overlap some existing window. The
default here will keep the current metacity behavior. However, this
behavior is sometimes inappropriate. For instance: I am working on a
laptop. At work, I have two screens, so my X server is setup for these
two screens. When I go home, I just unplug the second screen, and only
use the laptop's screen at home. It is therefore a problem for me if
metacity keeps placing window on the part of xinerama screen which isn't
visible.

regards,
Emmanuel,  GtkAda team

*** ../place.c	Tue Feb  4 23:33:25 2003
--- src/place.c	Wed Feb  5 00:16:00 2003
***************
*** 28,33 ****
--- 28,38 ----
  #include <math.h>
  #include <stdlib.h>
  
+ /* 1 if we always want to place new windows on the current xinerama,
+    0 if it is acceptable to place it on other screens */
+ static gboolean force_placement_on_current_xinerama = 1;
+ 
+ 
  static gint
  northwestcmp (gconstpointer a, gconstpointer b)
  {
***************
*** 79,86 ****
                     MetaFrameGeometry *fgeom,
                     /* visible windows on relevant workspaces */
                     GList      *windows,
!                    int         x,
!                    int         y,
                     int        *new_x,
                     int        *new_y)
  {
--- 84,90 ----
                     MetaFrameGeometry *fgeom,
                     /* visible windows on relevant workspaces */
                     GList      *windows,
! 		   const MetaXineramaScreenInfo* current_xinerama,
                     int        *new_x,
                     int        *new_y)
  {
***************
*** 121,132 ****
     * of NW corner of window frame.
     */
    
!   /* FIXME this is bogus because we get the current xinerama
!    * for the window based on its position, but we haven't
!    * placed it yet.
!    */
!   meta_window_get_work_area (window, TRUE, &work_area);
!   
    cascade_x = MAX (0, work_area.x);
    cascade_y = MAX (0, work_area.y);
    
--- 125,135 ----
     * of NW corner of window frame.
     */
    
!   work_area.x = current_xinerama->x_origin;
!   work_area.y = current_xinerama->y_origin;
!   work_area.width = current_xinerama->width;
!   work_area.height = current_xinerama->height;
! 
    cascade_x = MAX (0, work_area.x);
    cascade_y = MAX (0, work_area.y);
    
***************
*** 365,371 ****
  
  static gboolean
  fit_rect_in_xinerama (MetaScreen    *screen,
!                       MetaRectangle *rect)
  {
    int i;
    int best_index;
--- 368,375 ----
  
  static gboolean
  fit_rect_in_xinerama (MetaScreen    *screen,
!                       MetaRectangle *rect,
! 		      const MetaXineramaScreenInfo* force_xinerama_screen)
  {
    int i;
    int best_index;
***************
*** 410,415 ****
--- 414,424 ----
    g_assert (best_index >= 0);
  
    xsi = &screen->xinerama_infos[best_index];
+ 
+   /* Force on a specific screen */
+   if (force_xinerama_screen != NULL
+       && force_xinerama_screen->number != xsi->number)
+     return 0;
    
    if (rect->x < xsi->x_origin)
      rect->x = xsi->x_origin;
***************
*** 453,458 ****
--- 461,473 ----
    GList *tmp;
    MetaRectangle rect;
    int i;
+ 
+   /* Xinerama screen on which we want to force the placement */
+   const MetaXineramaScreenInfo* force_xinerama = current_xinerama;
+ 
+   if (!force_placement_on_current_xinerama) {
+     force_xinerama = NULL;
+   }
    
    retval = FALSE;
    sorted = NULL;
***************
*** 497,509 ****
      {
        MetaWindow *w = tmp->data;
        MetaRectangle outer_rect;
!       
        meta_window_get_outer_rect (w, &outer_rect);
  
        rect.x = outer_rect.x;
        rect.y = outer_rect.y + outer_rect.height;
!       
!       if (fit_rect_in_xinerama (window->screen, &rect) &&
            !rectangle_overlaps_some_window (&rect, sorted))
          {
            *new_x = rect.x;
--- 512,524 ----
      {
        MetaWindow *w = tmp->data;
        MetaRectangle outer_rect;
! 
        meta_window_get_outer_rect (w, &outer_rect);
  
        rect.x = outer_rect.x;
        rect.y = outer_rect.y + outer_rect.height;
! 
!       if (fit_rect_in_xinerama (window->screen, &rect, force_xinerama) &&
            !rectangle_overlaps_some_window (&rect, sorted))
          {
            *new_x = rect.x;
***************
*** 537,543 ****
        rect.x = outer_rect.x + outer_rect.width;
        rect.y = outer_rect.y;
        
!       if (fit_rect_in_xinerama (window->screen, &rect) &&
            !rectangle_overlaps_some_window (&rect, sorted))
          {
            *new_x = rect.x;
--- 552,558 ----
        rect.x = outer_rect.x + outer_rect.width;
        rect.y = outer_rect.y;
        
!       if (fit_rect_in_xinerama (window->screen, &rect, force_xinerama) &&
            !rectangle_overlaps_some_window (&rect, sorted))
          {
            *new_x = rect.x;
***************
*** 839,848 ****
    x = xi->x_origin;
    y = xi->y_origin;
  
    if (find_first_fit (window, fgeom, windows, x, y, &x, &y))
      goto done;
    
!   find_next_cascade (window, fgeom, windows, x, y, &x, &y);
    
   done:
    g_list_free (windows);
--- 858,867 ----
    x = xi->x_origin;
    y = xi->y_origin;
  
    if (find_first_fit (window, fgeom, windows, x, y, &x, &y))
      goto done;
    
!   find_next_cascade (window, fgeom, windows, xi, &x, &y);
    
   done:
    g_list_free (windows);





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