From a7c8cea1b50112bf7ebf5e7fbb7617ead5e6d413 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Fri, 7 Jun 2002 03:18:46 +0000 Subject: [PATCH] implement 2002-06-06 Havoc Pennington * src/screen.c (meta_screen_get_current_xinerama): implement * src/place.c (meta_window_place): cascade windows on the active Xinerama screen * src/window.c (meta_window_move_resize_internal): strip out the #if 0 cruft about guessing fullscreen mode (constrain_position, constrain_size): fullscreen/maximize to the Xinerama head, not the whole screen (meta_window_get_work_area): autocreate struts at the Xinerama physical screen edges for the screen the window is on. * src/screen.c (meta_screen_get_xinerama_for_window): someone snuck in a for loop, fix it. ;-) --- ChangeLog | 17 +++++++++ src/display.c | 7 ++-- src/display.h | 3 ++ src/place.c | 13 ++++--- src/screen.c | 95 +++++++++++++++++++++++++++++++++++++++++---------- src/screen.h | 3 ++ src/window.c | 95 ++++++++++++++++++++++++--------------------------- 7 files changed, 157 insertions(+), 76 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7bfb1a460..9bd5c34b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2002-06-06 Havoc Pennington + + * src/screen.c (meta_screen_get_current_xinerama): implement + + * src/place.c (meta_window_place): cascade windows on the active + Xinerama screen + + * src/window.c (meta_window_move_resize_internal): strip out the + #if 0 cruft about guessing fullscreen mode + (constrain_position, constrain_size): fullscreen/maximize to the + Xinerama head, not the whole screen + (meta_window_get_work_area): autocreate struts at the Xinerama + physical screen edges for the screen the window is on. + + * src/screen.c (meta_screen_get_xinerama_for_window): someone + snuck in a for loop, fix it. ;-) + 2002-06-06 James M. Cape * src/themes/Esco/metacity-theme-1.xml: Increase the border size diff --git a/src/display.c b/src/display.c index ef2a3602d..2620e4c51 100644 --- a/src/display.c +++ b/src/display.c @@ -331,6 +331,8 @@ meta_display_open (const char *name) */ display->leader_window = None; display->no_focus_window = None; + + display->xinerama_cache_invalidated = TRUE; screens = NULL; @@ -873,10 +875,11 @@ event_callback (XEvent *event, if (dump_events) meta_spew_event (display, event); - + filter_out_event = FALSE; display->current_time = event_get_time (display, event); - + display->xinerama_cache_invalidated = TRUE; + modified = event_get_modified_window (display, event); if (event->type == ButtonPress) diff --git a/src/display.h b/src/display.h index d4214ff31..92a94a09b 100644 --- a/src/display.h +++ b/src/display.h @@ -210,6 +210,9 @@ struct _MetaDisplay unsigned int ignored_modifier_mask; unsigned int num_lock_mask; unsigned int scroll_lock_mask; + + /* Xinerama cache */ + unsigned int xinerama_cache_invalidated : 1; }; gboolean meta_display_open (const char *name); diff --git a/src/place.c b/src/place.c index a9ffd6ba8..18d70ea06 100644 --- a/src/place.c +++ b/src/place.c @@ -246,6 +246,7 @@ meta_window_place (MetaWindow *window, int *new_y) { GList *windows; + const MetaXineramaScreenInfo *xi; /* frame member variables should NEVER be used in here, only * MetaFrameGeometry. But remember fgeom == NULL @@ -360,10 +361,9 @@ meta_window_place (MetaWindow *window, { /* Center on screen */ int w, h; - const MetaXineramaScreenInfo *xi; - /* I think whole screen will look nicer than workarea */ - xi = meta_screen_get_current_xinerama (window->screen); + /* Warning, this function is a round trip! */ + xi = meta_screen_get_current_xinerama (window->screen); w = xi->width; h = xi->height; @@ -404,10 +404,13 @@ meta_window_place (MetaWindow *window, tmp = tmp->next; } } + + /* Warning, this is a round trip! */ + xi = meta_screen_get_current_xinerama (window->screen); /* "Origin" placement algorithm */ - x = 0; - y = 0; + x = xi->x_origin; + y = xi->y_origin; /* Cascade */ find_next_cascade (window, fgeom, windows, x, y, &x, &y); diff --git a/src/screen.c b/src/screen.c index 60ad783a9..a983d9fb0 100644 --- a/src/screen.c +++ b/src/screen.c @@ -236,6 +236,8 @@ meta_screen_new (MetaDisplay *display, screen->xinerama_infos = NULL; screen->n_xinerama_infos = 0; + screen->last_xinerama_index = 0; + #ifdef HAVE_XINERAMA if (XineramaQueryExtension (display->xdisplay, &xinerama_event_base, @@ -265,6 +267,14 @@ meta_screen_new (MetaDisplay *display, screen->xinerama_infos[i].y_origin = infos[i].y_org; screen->xinerama_infos[i].width = infos[i].width; screen->xinerama_infos[i].height = infos[i].height; + + meta_topic (META_DEBUG_XINERAMA, + "Xinerama %d is %d,%d %d x %d\n", + screen->xinerama_infos[i].number, + screen->xinerama_infos[i].x_origin, + screen->xinerama_infos[i].y_origin, + screen->xinerama_infos[i].width, + screen->xinerama_infos[i].height); ++i; } @@ -809,24 +819,28 @@ meta_screen_get_xinerama_for_window (MetaScreen *screen, best_xinerama = 0; xinerama_score = 0; - - for (i = 0; i < screen->n_xinerama_infos; i++) { - MetaRectangle dest, screen_info; - screen_info.x = screen->xinerama_infos[i].x_origin; - screen_info.y = screen->xinerama_infos[i].y_origin; - screen_info.width = screen->xinerama_infos[i].width; - screen_info.height = screen->xinerama_infos[i].height; + i = 0; + while (i < screen->n_xinerama_infos) + { + MetaRectangle dest, screen_info; + + screen_info.x = screen->xinerama_infos[i].x_origin; + screen_info.y = screen->xinerama_infos[i].y_origin; + screen_info.width = screen->xinerama_infos[i].width; + screen_info.height = screen->xinerama_infos[i].height; + + if (meta_rectangle_intersect (&screen_info, &window->rect, &dest)) + { + if (dest.width * dest.height > xinerama_score) + { + xinerama_score = dest.width * dest.height; + best_xinerama = i; + } + } - if (meta_rectangle_intersect (&screen_info, &window->rect, &dest)) - { - if (dest.width * dest.height > xinerama_score) - { - xinerama_score = dest.width * dest.height; - best_xinerama = i; - } - } - } + ++i; + } return &screen->xinerama_infos[best_xinerama]; } @@ -834,9 +848,54 @@ meta_screen_get_xinerama_for_window (MetaScreen *screen, const MetaXineramaScreenInfo* meta_screen_get_current_xinerama (MetaScreen *screen) { - /* FIXME how do we decide which is current? */ + if (screen->n_xinerama_infos == 1) + return 0; + + /* Sadly, we have to do it this way. Yuck. + */ - return &screen->xinerama_infos[0]; + if (screen->display->xinerama_cache_invalidated) + { + Window root_return, child_return; + int root_x_return, root_y_return; + int win_x_return, win_y_return; + unsigned int mask_return; + int i; + + screen->display->xinerama_cache_invalidated = FALSE; + + XQueryPointer (screen->display->xdisplay, + screen->xroot, + &root_return, + &child_return, + &root_x_return, + &root_y_return, + &win_x_return, + &win_y_return, + &mask_return); + + screen->last_xinerama_index = 0; + i = 0; + while (i < screen->n_xinerama_infos) + { + if ((root_x_return >= screen->xinerama_infos[i].x_origin && + root_x_return < (screen->xinerama_infos[i].x_origin + screen->xinerama_infos[i].width) && + root_y_return >= screen->xinerama_infos[i].y_origin && + root_y_return < (screen->xinerama_infos[i].y_origin + screen->xinerama_infos[i].height))) + { + screen->last_xinerama_index = i; + break; + } + + ++i; + } + + meta_topic (META_DEBUG_XINERAMA, + "Rechecked current Xinerama, now %d\n", + screen->last_xinerama_index); + } + + return &screen->xinerama_infos[screen->last_xinerama_index]; } #define _NET_WM_ORIENTATION_HORZ 0 diff --git a/src/screen.h b/src/screen.h index 9ab5e43b8..f97820373 100644 --- a/src/screen.h +++ b/src/screen.h @@ -63,6 +63,9 @@ struct _MetaScreen MetaXineramaScreenInfo *xinerama_infos; int n_xinerama_infos; + /* Cache the current Xinerama */ + int last_xinerama_index; + guint work_area_idle; int rows_of_workspaces; diff --git a/src/window.c b/src/window.c index d2e9d926f..d0b84f990 100644 --- a/src/window.c +++ b/src/window.c @@ -1862,49 +1862,10 @@ meta_window_move_resize_internal (MetaWindow *window, */ int client_move_x; int client_move_y; - const MetaXineramaScreenInfo *xinerama; is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0; do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0; is_user_action = (flags & META_USER_MOVE_RESIZE) != 0; - -#if 0 - xinerama = meta_screen_get_xinerama_for_window (window->screen, - window); - - /* Try to guess if a client meant to be fullscreen (or not) and - * toggle the real fullscreen state in response. This is - * probably a bit dubious. - */ - if (is_configure_request && - !window->decorated && - window->has_fullscreen_func && - w == xinerama->width && - h == xinerama->height && - root_x_nw == xinerama->x_origin && - root_y_nw == xinerama->y_origin) - { - /* This queues a move resize again, which is why it's - * called before the following unqueue_move_resize - */ - meta_topic (META_DEBUG_GEOMETRY, - "Guessing that window %s meant to be fullscreen\n", - window->desc); - meta_window_make_fullscreen (window); - } - else if (is_configure_request && - window->fullscreen && - (w != xinerama->width || - h != xinerama->height || - root_x_nw != xinerama->x_origin || - root_y_nw != xinerama->y_origin)) - { - meta_topic (META_DEBUG_GEOMETRY, - "Guessing that window %s no longer wants to be fullscreen\n", - window->desc); - meta_window_unmake_fullscreen (window); - } -#endif /* We don't need it in the idle queue anymore. */ meta_window_unqueue_move_resize (window); @@ -4999,10 +4960,21 @@ constrain_size (MetaWindow *window, meta_window_get_work_area (window, &work_area); /* Get the allowed size ranges, considering maximized, etc. */ - if (window->fullscreen || - window->type == META_WINDOW_DESKTOP || - window->type == META_WINDOW_DOCK) + if (window->fullscreen) { + const MetaXineramaScreenInfo *xinerama; + + xinerama = meta_screen_get_xinerama_for_window (window->screen, + window); + + + fullw = xinerama->width; + fullh = xinerama->height; + } + else if (window->type == META_WINDOW_DESKTOP || + window->type == META_WINDOW_DOCK) + { + fullw = window->screen->width; fullh = window->screen->height; } @@ -5137,16 +5109,28 @@ constrain_position (MetaWindow *window, } else if (window->fullscreen) { - x = 0; - y = 0; + const MetaXineramaScreenInfo *xinerama; + + xinerama = meta_screen_get_xinerama_for_window (window->screen, + window); + + x = xinerama->x_origin; + y = xinerama->y_origin; /* If the window's geometry gridding (e.g. for a terminal) * prevents fullscreen, center the window within * the screen area. */ - x += (window->screen->width - window->rect.width) / 2; + x += (xinerama->width - window->rect.width) / 2; + y += (xinerama->height - window->rect.height) / 2; - y += (window->screen->height - window->rect.height) / 2; + /* If the window is somehow larger than the screen be paranoid + * and fix the resulting negative coords + */ + if (x < xinerama->x_origin) + x = xinerama->x_origin; + if (y < xinerama->y_origin) + y = xinerama->y_origin; } else if (window->maximized) { @@ -5670,12 +5654,21 @@ meta_window_get_work_area (MetaWindow *window, { MetaRectangle space_area; GList *tmp; + const MetaXineramaScreenInfo *xinerama; + + int left_strut; + int right_strut; + int top_strut; + int bottom_strut; - int left_strut = 0; - int right_strut = 0; - int top_strut = 0; - int bottom_strut = 0; + xinerama = meta_screen_get_xinerama_for_window (window->screen, + window); + left_strut = xinerama->x_origin; + right_strut = window->screen->width - xinerama->width - xinerama->x_origin; + top_strut = xinerama->y_origin; + bottom_strut = window->screen->height - xinerama->height - xinerama->y_origin; + tmp = meta_window_get_workspaces (window); while (tmp != NULL) @@ -5691,7 +5684,7 @@ meta_window_get_work_area (MetaWindow *window, tmp = tmp->next; } - + area->x = left_strut; area->y = top_strut; area->width = window->screen->width - left_strut - right_strut;