mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
Patch from Rob Adams addresses #95014 (placement issues), makes first fit
2003-02-23 Havoc Pennington <hp@pobox.com> Patch from Rob Adams addresses #95014 (placement issues), makes first fit algorithm "center tile", adds most code for per-xinerama workspaces (#86682) but disables it for now. * src/workspace.c (meta_workspace_get_work_area_for_xinerama) (meta_workspace_get_work_area_all_xineramas): new xinerama functions, maintain workspace->work_areas with a different work area for each xinerama. However for now all the work areas are the same, because haven't quite figured out how _NET_WM_STRUT is supposed to work * src/window.c: adapt to new meta_window_* xinerama APIs (meta_window_get_work_area_current_xinerama): new xinerama API (meta_window_get_work_area_for_xinerama): new xinerama API (constrain_position): be a bit more clever about which xinerama's work area we choose to use. * src/stack.c: adapt to new Xinerama API * src/screen.c (reload_xinerama_infos): invalidate all work areas (meta_screen_get_xinerama_for_rect): new function (meta_screen_window_intersects_xinerama): new function * src/place.c (find_first_fit): change to use "center tiling" (center a screen full of tiled windows, rather than aligning them top left). Adapt to new xinerama functions.
This commit is contained in:
parent
15c5ddbec4
commit
c27d89218c
31
ChangeLog
31
ChangeLog
@ -1,3 +1,34 @@
|
|||||||
|
2003-02-23 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
Patch from Rob Adams addresses #95014 (placement issues),
|
||||||
|
makes first fit algorithm "center tile", adds most code
|
||||||
|
for per-xinerama workspaces (#86682) but disables it for now.
|
||||||
|
|
||||||
|
* src/workspace.c (meta_workspace_get_work_area_for_xinerama)
|
||||||
|
(meta_workspace_get_work_area_all_xineramas): new xinerama
|
||||||
|
functions, maintain workspace->work_areas with a different
|
||||||
|
work area for each xinerama. However for now all the work
|
||||||
|
areas are the same, because haven't quite figured out how
|
||||||
|
_NET_WM_STRUT is supposed to work
|
||||||
|
|
||||||
|
* src/window.c: adapt to new meta_window_* xinerama APIs
|
||||||
|
(meta_window_get_work_area_current_xinerama): new xinerama
|
||||||
|
API
|
||||||
|
(meta_window_get_work_area_for_xinerama): new xinerama API
|
||||||
|
(constrain_position): be a bit more clever about which xinerama's
|
||||||
|
work area we choose to use.
|
||||||
|
|
||||||
|
* src/stack.c: adapt to new Xinerama API
|
||||||
|
|
||||||
|
* src/screen.c (reload_xinerama_infos): invalidate all work areas
|
||||||
|
(meta_screen_get_xinerama_for_rect): new function
|
||||||
|
(meta_screen_window_intersects_xinerama): new function
|
||||||
|
|
||||||
|
* src/place.c (find_first_fit): change to use
|
||||||
|
"center tiling" (center a screen full of tiled windows,
|
||||||
|
rather than aligning them top left). Adapt to new
|
||||||
|
xinerama functions.
|
||||||
|
|
||||||
2003-02-22 Rob Adams <robadams@ucla.edu>
|
2003-02-22 Rob Adams <robadams@ucla.edu>
|
||||||
|
|
||||||
* src/metacity.schemas.in: change toggle_maximized to
|
* src/metacity.schemas.in: change toggle_maximized to
|
||||||
|
95
src/place.c
95
src/place.c
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Havoc Pennington
|
* Copyright (C) 2001 Havoc Pennington
|
||||||
|
* Copyright (C) 2002, 2003 Red Hat, Inc.
|
||||||
|
* Copyright (C) 2003 Rob Adams
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -121,11 +123,11 @@ find_next_cascade (MetaWindow *window,
|
|||||||
* of NW corner of window frame.
|
* of NW corner of window frame.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* FIXME this is bogus because we get the current xinerama
|
/* FIXME should use xinerama with mouse pointer
|
||||||
* for the window based on its position, but we haven't
|
* (or better, xinerama where window was launched
|
||||||
* placed it yet.
|
* determined via startup notification)
|
||||||
*/
|
*/
|
||||||
meta_window_get_work_area (window, TRUE, &work_area);
|
meta_window_get_work_area_for_xinerama (window, 0, &work_area);
|
||||||
|
|
||||||
cascade_x = MAX (0, work_area.x);
|
cascade_x = MAX (0, work_area.x);
|
||||||
cascade_y = MAX (0, work_area.y);
|
cascade_y = MAX (0, work_area.y);
|
||||||
@ -363,15 +365,37 @@ topmost_cmp (gconstpointer a, gconstpointer b)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
center_tile_rect_in_area (MetaRectangle *rect,
|
||||||
|
MetaRectangle *work_area)
|
||||||
|
{
|
||||||
|
int fluff;
|
||||||
|
|
||||||
|
/* The point here is to tile a window such that "extra"
|
||||||
|
* space is equal on either side (i.e. so a full screen
|
||||||
|
* of windows tiled this way would center the windows
|
||||||
|
* as a group)
|
||||||
|
*/
|
||||||
|
|
||||||
|
fluff = (work_area->width % rect->width) / 2;
|
||||||
|
rect->x = work_area->x + fluff;
|
||||||
|
fluff = (work_area->height % rect->height) / 3;
|
||||||
|
rect->y = work_area->y + fluff;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fit_rect_in_xinerama (MetaScreen *screen,
|
fit_rect_in_xinerama (MetaWindow *window,
|
||||||
MetaRectangle *rect)
|
MetaRectangle *rect)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int best_index;
|
int best_index;
|
||||||
int best_overlap;
|
int best_overlap;
|
||||||
|
MetaScreen *screen;
|
||||||
|
MetaRectangle work_area;
|
||||||
const MetaXineramaScreenInfo *xsi;
|
const MetaXineramaScreenInfo *xsi;
|
||||||
|
|
||||||
|
screen = window->screen;
|
||||||
|
|
||||||
/* Find xinerama with best fit, then
|
/* Find xinerama with best fit, then
|
||||||
* shift rect to be entirely within it.
|
* shift rect to be entirely within it.
|
||||||
*/
|
*/
|
||||||
@ -409,17 +433,17 @@ fit_rect_in_xinerama (MetaScreen *screen,
|
|||||||
/* some overlap had to be better than -1 */
|
/* some overlap had to be better than -1 */
|
||||||
g_assert (best_index >= 0);
|
g_assert (best_index >= 0);
|
||||||
|
|
||||||
xsi = &screen->xinerama_infos[best_index];
|
meta_window_get_work_area_for_xinerama (window, best_index, &work_area);
|
||||||
|
|
||||||
if (rect->x < xsi->x_origin)
|
if ((rect->x < work_area.x) || (rect->y < work_area.y) ||
|
||||||
rect->x = xsi->x_origin;
|
(rect->x >= work_area.x + work_area.width) ||
|
||||||
if (rect->y < xsi->y_origin)
|
(rect->y >= work_area.y + work_area.height))
|
||||||
rect->y = xsi->y_origin;
|
center_tile_rect_in_area (rect, &work_area);
|
||||||
|
|
||||||
/* Now return whether we are entirely within the xinerama screen */
|
/* Now return whether we are entirely within the work area */
|
||||||
return
|
return
|
||||||
((rect->x + rect->width) < (xsi->x_origin + xsi->width)) &&
|
((rect->x + rect->width) < (work_area.x + work_area.width)) &&
|
||||||
((rect->y + rect->height) < (xsi->y_origin + xsi->height));
|
((rect->y + rect->height) < (work_area.y + work_area.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the leftmost, then topmost, empty area on the workspace
|
/* Find the leftmost, then topmost, empty area on the workspace
|
||||||
@ -447,11 +471,11 @@ find_first_fit (MetaWindow *window,
|
|||||||
* of each existing window, aligned with the left/top of the
|
* of each existing window, aligned with the left/top of the
|
||||||
* existing window in each of those cases.
|
* existing window in each of those cases.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int retval;
|
int retval;
|
||||||
GList *sorted;
|
GList *sorted;
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
MetaRectangle rect;
|
MetaRectangle rect;
|
||||||
|
MetaRectangle work_area;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
retval = FALSE;
|
retval = FALSE;
|
||||||
@ -466,11 +490,16 @@ find_first_fit (MetaWindow *window,
|
|||||||
rect.height += fgeom->top_height + fgeom->bottom_height;
|
rect.height += fgeom->top_height + fgeom->bottom_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try origin of first Xinerama */
|
/* Try center-tiling on first xinerama */
|
||||||
rect.x = window->screen->xinerama_infos[0].x_origin;
|
/* FIXME should use xinerama with mouse pointer
|
||||||
rect.y = window->screen->xinerama_infos[0].y_origin;
|
* (or better, xinerama where window was launched
|
||||||
|
* determined via startup notification)
|
||||||
|
*/
|
||||||
|
meta_window_get_work_area_for_xinerama (window, 0, &work_area);
|
||||||
|
|
||||||
if (fit_rect_in_xinerama (window->screen, &rect) &&
|
center_tile_rect_in_area (&rect, &work_area);
|
||||||
|
|
||||||
|
if (fit_rect_in_xinerama (window, &rect) &&
|
||||||
!rectangle_overlaps_some_window (&rect, windows))
|
!rectangle_overlaps_some_window (&rect, windows))
|
||||||
{
|
{
|
||||||
*new_x = rect.x;
|
*new_x = rect.x;
|
||||||
@ -503,7 +532,7 @@ find_first_fit (MetaWindow *window,
|
|||||||
rect.x = outer_rect.x;
|
rect.x = outer_rect.x;
|
||||||
rect.y = outer_rect.y + outer_rect.height;
|
rect.y = outer_rect.y + outer_rect.height;
|
||||||
|
|
||||||
if (fit_rect_in_xinerama (window->screen, &rect) &&
|
if (fit_rect_in_xinerama (window, &rect) &&
|
||||||
!rectangle_overlaps_some_window (&rect, sorted))
|
!rectangle_overlaps_some_window (&rect, sorted))
|
||||||
{
|
{
|
||||||
*new_x = rect.x;
|
*new_x = rect.x;
|
||||||
@ -537,7 +566,7 @@ find_first_fit (MetaWindow *window,
|
|||||||
rect.x = outer_rect.x + outer_rect.width;
|
rect.x = outer_rect.x + outer_rect.width;
|
||||||
rect.y = outer_rect.y;
|
rect.y = outer_rect.y;
|
||||||
|
|
||||||
if (fit_rect_in_xinerama (window->screen, &rect) &&
|
if (fit_rect_in_xinerama (window, &rect) &&
|
||||||
!rectangle_overlaps_some_window (&rect, sorted))
|
!rectangle_overlaps_some_window (&rect, sorted))
|
||||||
{
|
{
|
||||||
*new_x = rect.x;
|
*new_x = rect.x;
|
||||||
@ -556,14 +585,15 @@ find_first_fit (MetaWindow *window,
|
|||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Origin of each Xinerama screen which isn't the first */
|
/* Try center-tile on each Xinerama screen which isn't the first */
|
||||||
i = 1;
|
i = 1;
|
||||||
while (i < window->screen->n_xinerama_infos)
|
while (i < window->screen->n_xinerama_infos)
|
||||||
{
|
{
|
||||||
rect.x = window->screen->xinerama_infos[i].x_origin;
|
meta_window_get_work_area_for_xinerama (window, i, &work_area);
|
||||||
rect.y = window->screen->xinerama_infos[i].y_origin;
|
|
||||||
|
|
||||||
if (fit_rect_in_xinerama (window->screen, &rect) &&
|
center_tile_rect_in_area (&rect, &work_area);
|
||||||
|
|
||||||
|
if (fit_rect_in_xinerama (window, &rect) &&
|
||||||
!rectangle_overlaps_some_window (&rect, windows))
|
!rectangle_overlaps_some_window (&rect, windows))
|
||||||
{
|
{
|
||||||
*new_x = rect.x;
|
*new_x = rect.x;
|
||||||
@ -578,6 +608,7 @@ find_first_fit (MetaWindow *window,
|
|||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,10 +640,11 @@ constrain_placement (MetaWindow *window,
|
|||||||
* for the window based on its position, but we haven't
|
* for the window based on its position, but we haven't
|
||||||
* placed it yet.
|
* placed it yet.
|
||||||
*/
|
*/
|
||||||
meta_window_get_work_area (window, TRUE, &work_area);
|
meta_window_get_work_area_current_xinerama (window, &work_area);
|
||||||
|
|
||||||
nw_x = work_area.x;
|
nw_x = work_area.x;
|
||||||
nw_y = work_area.y;
|
nw_y = work_area.y;
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
{
|
{
|
||||||
nw_x += fgeom->left_width;
|
nw_x += fgeom->left_width;
|
||||||
@ -849,6 +881,7 @@ meta_window_place (MetaWindow *window,
|
|||||||
constrain_placement (window, fgeom, x, y, &x, &y);
|
constrain_placement (window, fgeom, x, y, &x, &y);
|
||||||
|
|
||||||
done_no_constraints:
|
done_no_constraints:
|
||||||
|
|
||||||
*new_x = x;
|
*new_x = x;
|
||||||
*new_y = y;
|
*new_y = y;
|
||||||
}
|
}
|
||||||
@ -946,13 +979,11 @@ get_vertical_edges (MetaWindow *window,
|
|||||||
edges = g_new (int, n_edges);
|
edges = g_new (int, n_edges);
|
||||||
|
|
||||||
/* workspace/screen edges */
|
/* workspace/screen edges */
|
||||||
meta_window_get_work_area (window, FALSE, &work_area);
|
meta_window_get_work_area_current_xinerama (window, &work_area);
|
||||||
|
|
||||||
edges[i] = work_area.x;
|
edges[i] = work_area.x;
|
||||||
++i;
|
++i;
|
||||||
edges[i] =
|
edges[i] = work_area.x + work_area.width;
|
||||||
work_area.x +
|
|
||||||
work_area.width;
|
|
||||||
++i;
|
++i;
|
||||||
edges[i] = 0;
|
edges[i] = 0;
|
||||||
++i;
|
++i;
|
||||||
@ -1019,13 +1050,11 @@ get_horizontal_edges (MetaWindow *window,
|
|||||||
edges = g_new (int, n_edges);
|
edges = g_new (int, n_edges);
|
||||||
|
|
||||||
/* workspace/screen edges */
|
/* workspace/screen edges */
|
||||||
meta_window_get_work_area (window, FALSE, &work_area);
|
meta_window_get_work_area_current_xinerama (window, &work_area);
|
||||||
|
|
||||||
edges[i] = work_area.y;
|
edges[i] = work_area.y;
|
||||||
++i;
|
++i;
|
||||||
edges[i] =
|
edges[i] = work_area.y + work_area.height;
|
||||||
work_area.y +
|
|
||||||
work_area.height;
|
|
||||||
++i;
|
++i;
|
||||||
edges[i] = 0;
|
edges[i] = 0;
|
||||||
++i;
|
++i;
|
||||||
|
64
src/screen.c
64
src/screen.c
@ -5,6 +5,7 @@
|
|||||||
* Copyright (C) 2002, 2003 Red Hat Inc.
|
* Copyright (C) 2002, 2003 Red Hat Inc.
|
||||||
* Some ICCCM manager selection code derived from fvwm2,
|
* Some ICCCM manager selection code derived from fvwm2,
|
||||||
* Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
|
* Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
|
||||||
|
* Copyright (C) 2003 Rob Adams
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -352,6 +353,20 @@ reload_xinerama_infos (MetaScreen *screen)
|
|||||||
|
|
||||||
g_assert (screen->n_xinerama_infos > 0);
|
g_assert (screen->n_xinerama_infos > 0);
|
||||||
g_assert (screen->xinerama_infos != NULL);
|
g_assert (screen->xinerama_infos != NULL);
|
||||||
|
|
||||||
|
{
|
||||||
|
GList *tmp;
|
||||||
|
|
||||||
|
tmp = screen->workspaces;
|
||||||
|
while (tmp != NULL)
|
||||||
|
{
|
||||||
|
MetaWorkspace *space = tmp->data;
|
||||||
|
|
||||||
|
meta_workspace_invalidate_work_area (space);
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaScreen*
|
MetaScreen*
|
||||||
@ -1283,18 +1298,15 @@ meta_screen_focus_default_window (MetaScreen *screen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const MetaXineramaScreenInfo*
|
const MetaXineramaScreenInfo*
|
||||||
meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
meta_screen_get_xinerama_for_rect (MetaScreen *screen,
|
||||||
MetaWindow *window)
|
MetaRectangle *rect)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int best_xinerama, xinerama_score;
|
int best_xinerama, xinerama_score;
|
||||||
MetaRectangle window_rect;
|
|
||||||
|
|
||||||
if (screen->n_xinerama_infos == 1)
|
if (screen->n_xinerama_infos == 1)
|
||||||
return &screen->xinerama_infos[0];
|
return &screen->xinerama_infos[0];
|
||||||
|
|
||||||
meta_window_get_outer_rect (window, &window_rect);
|
|
||||||
|
|
||||||
best_xinerama = 0;
|
best_xinerama = 0;
|
||||||
xinerama_score = 0;
|
xinerama_score = 0;
|
||||||
|
|
||||||
@ -1308,7 +1320,7 @@ meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
|||||||
screen_info.width = screen->xinerama_infos[i].width;
|
screen_info.width = screen->xinerama_infos[i].width;
|
||||||
screen_info.height = screen->xinerama_infos[i].height;
|
screen_info.height = screen->xinerama_infos[i].height;
|
||||||
|
|
||||||
if (meta_rectangle_intersect (&screen_info, &window_rect, &dest))
|
if (meta_rectangle_intersect (&screen_info, rect, &dest))
|
||||||
{
|
{
|
||||||
if (dest.width * dest.height > xinerama_score)
|
if (dest.width * dest.height > xinerama_score)
|
||||||
{
|
{
|
||||||
@ -1323,6 +1335,38 @@ meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
|||||||
return &screen->xinerama_infos[best_xinerama];
|
return &screen->xinerama_infos[best_xinerama];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MetaXineramaScreenInfo*
|
||||||
|
meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaRectangle window_rect;
|
||||||
|
|
||||||
|
meta_window_get_outer_rect (window, &window_rect);
|
||||||
|
|
||||||
|
return meta_screen_get_xinerama_for_rect (screen, &window_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_screen_window_intersects_xinerama (MetaScreen *screen,
|
||||||
|
MetaWindow *window,
|
||||||
|
int which_xinerama)
|
||||||
|
{
|
||||||
|
MetaRectangle window_rect;
|
||||||
|
MetaRectangle dest, screen_rect;
|
||||||
|
|
||||||
|
meta_window_get_outer_rect (window, &window_rect);
|
||||||
|
|
||||||
|
screen_rect.x = screen->xinerama_infos[which_xinerama].x_origin;
|
||||||
|
screen_rect.y = screen->xinerama_infos[which_xinerama].y_origin;
|
||||||
|
screen_rect.width = screen->xinerama_infos[which_xinerama].width;
|
||||||
|
screen_rect.height = screen->xinerama_infos[which_xinerama].height;
|
||||||
|
|
||||||
|
if (meta_rectangle_intersect (&screen_rect, &window_rect, &dest))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
const MetaXineramaScreenInfo*
|
const MetaXineramaScreenInfo*
|
||||||
meta_screen_get_current_xinerama (MetaScreen *screen)
|
meta_screen_get_current_xinerama (MetaScreen *screen)
|
||||||
{
|
{
|
||||||
@ -1357,9 +1401,11 @@ meta_screen_get_current_xinerama (MetaScreen *screen)
|
|||||||
while (i < screen->n_xinerama_infos)
|
while (i < screen->n_xinerama_infos)
|
||||||
{
|
{
|
||||||
if ((root_x_return >= screen->xinerama_infos[i].x_origin &&
|
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_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 &&
|
||||||
root_y_return < (screen->xinerama_infos[i].y_origin + screen->xinerama_infos[i].height)))
|
root_y_return < (screen->xinerama_infos[i].y_origin +
|
||||||
|
screen->xinerama_infos[i].height)))
|
||||||
{
|
{
|
||||||
screen->last_xinerama_index = i;
|
screen->last_xinerama_index = i;
|
||||||
break;
|
break;
|
||||||
@ -1594,7 +1640,7 @@ set_work_area_hint (MetaScreen *screen)
|
|||||||
|
|
||||||
if (workspace->screen == screen)
|
if (workspace->screen == screen)
|
||||||
{
|
{
|
||||||
meta_workspace_get_work_area (workspace, &area);
|
meta_workspace_get_work_area_all_xineramas (workspace, &area);
|
||||||
tmp[0] = area.x;
|
tmp[0] = area.x;
|
||||||
tmp[1] = area.y;
|
tmp[1] = area.y;
|
||||||
tmp[2] = area.width;
|
tmp[2] = area.width;
|
||||||
|
14
src/screen.h
14
src/screen.h
@ -133,9 +133,17 @@ void meta_screen_focus_mouse_window (MetaScreen *scre
|
|||||||
void meta_screen_focus_default_window (MetaScreen *screen,
|
void meta_screen_focus_default_window (MetaScreen *screen,
|
||||||
MetaWindow *not_this_one);
|
MetaWindow *not_this_one);
|
||||||
|
|
||||||
const MetaXineramaScreenInfo* meta_screen_get_current_xinerama (MetaScreen *screen);
|
|
||||||
const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
const MetaXineramaScreenInfo* meta_screen_get_current_xinerama (MetaScreen *screen);
|
||||||
MetaWindow *window);
|
const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_rect (MetaScreen *screen,
|
||||||
|
MetaRectangle *rect);
|
||||||
|
const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_window (MetaScreen *screen,
|
||||||
|
MetaWindow *window);
|
||||||
|
|
||||||
|
|
||||||
|
gboolean meta_screen_window_intersects_xinerama (MetaScreen *screen,
|
||||||
|
MetaWindow *window,
|
||||||
|
int which_xinerama);
|
||||||
|
|
||||||
void meta_screen_update_workspace_layout (MetaScreen *screen);
|
void meta_screen_update_workspace_layout (MetaScreen *screen);
|
||||||
void meta_screen_update_workspace_names (MetaScreen *screen);
|
void meta_screen_update_workspace_names (MetaScreen *screen);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Havoc Pennington
|
* Copyright (C) 2001 Havoc Pennington
|
||||||
* Copyright (C) 2002 Red Hat, Inc.
|
* Copyright (C) 2002, 2003 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -191,7 +191,7 @@ window_is_fullscreen_size (MetaWindow *window)
|
|||||||
*/
|
*/
|
||||||
MetaRectangle workarea;
|
MetaRectangle workarea;
|
||||||
|
|
||||||
meta_window_get_work_area (window, FALSE, &workarea);
|
meta_window_get_work_area_current_xinerama (window, &workarea);
|
||||||
if (window->rect.x <= workarea.x &&
|
if (window->rect.x <= workarea.x &&
|
||||||
window->rect.y <= workarea.y)
|
window->rect.y <= workarea.y)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -205,7 +205,7 @@ window_is_fullscreen_size (MetaWindow *window)
|
|||||||
{
|
{
|
||||||
MetaRectangle workarea;
|
MetaRectangle workarea;
|
||||||
|
|
||||||
meta_window_get_work_area (window, TRUE, &workarea);
|
meta_window_get_work_area_current_xinerama (window, &workarea);
|
||||||
if (window->rect.x <= workarea.x &&
|
if (window->rect.x <= workarea.x &&
|
||||||
window->rect.y <= workarea.y)
|
window->rect.y <= workarea.y)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
131
src/window.c
131
src/window.c
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Havoc Pennington, Anders Carlsson
|
* Copyright (C) 2001 Havoc Pennington, Anders Carlsson
|
||||||
* Copyright (C) 2002 Red Hat, Inc.
|
* Copyright (C) 2002, 2003 Red Hat, Inc.
|
||||||
|
* Copyright (C) 2003 Rob Adams
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -669,7 +670,10 @@ meta_window_new (MetaDisplay *display,
|
|||||||
MetaRectangle workarea;
|
MetaRectangle workarea;
|
||||||
MetaRectangle outer;
|
MetaRectangle outer;
|
||||||
|
|
||||||
meta_window_get_work_area (window, TRUE, &workarea);
|
if (!window->placed)
|
||||||
|
meta_warning ("Metacity issue: using position-based current xinerama prior to placement\n");
|
||||||
|
|
||||||
|
meta_window_get_work_area_current_xinerama (window, &workarea);
|
||||||
|
|
||||||
meta_window_get_outer_rect (window, &outer);
|
meta_window_get_outer_rect (window, &outer);
|
||||||
|
|
||||||
@ -2702,7 +2706,7 @@ meta_window_fill_horizontal (MetaWindow *window)
|
|||||||
w = window->rect.width;
|
w = window->rect.width;
|
||||||
h = window->rect.height;
|
h = window->rect.height;
|
||||||
|
|
||||||
meta_window_get_work_area (window, TRUE, &work_area);
|
meta_window_get_work_area_current_xinerama (window, &work_area);
|
||||||
|
|
||||||
x = work_area.x;
|
x = work_area.x;
|
||||||
w = work_area.width;
|
w = work_area.width;
|
||||||
@ -2730,7 +2734,7 @@ meta_window_fill_vertical (MetaWindow *window)
|
|||||||
w = window->rect.width;
|
w = window->rect.width;
|
||||||
h = window->rect.height;
|
h = window->rect.height;
|
||||||
|
|
||||||
meta_window_get_work_area (window, TRUE, &work_area);
|
meta_window_get_work_area_current_xinerama (window, &work_area);
|
||||||
|
|
||||||
y = work_area.y;
|
y = work_area.y;
|
||||||
h = work_area.height;
|
h = work_area.height;
|
||||||
@ -5674,7 +5678,7 @@ constrain_size (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
MetaRectangle work_area;
|
MetaRectangle work_area;
|
||||||
|
|
||||||
meta_window_get_work_area (window, TRUE, &work_area);
|
meta_window_get_work_area_current_xinerama (window, &work_area);
|
||||||
|
|
||||||
fullw = work_area.width;
|
fullw = work_area.width;
|
||||||
fullh = work_area.height;
|
fullh = work_area.height;
|
||||||
@ -5823,9 +5827,15 @@ constrain_position (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
else if (window->maximized)
|
else if (window->maximized)
|
||||||
{
|
{
|
||||||
|
const MetaXineramaScreenInfo* xsi;
|
||||||
MetaRectangle work_area;
|
MetaRectangle work_area;
|
||||||
|
|
||||||
meta_window_get_work_area (window, TRUE, &work_area);
|
xsi = meta_screen_get_xinerama_for_rect (window->screen,
|
||||||
|
&window->saved_rect);
|
||||||
|
|
||||||
|
meta_window_get_work_area_for_xinerama (window,
|
||||||
|
xsi->number,
|
||||||
|
&work_area);
|
||||||
|
|
||||||
x = work_area.x;
|
x = work_area.x;
|
||||||
y = work_area.y;
|
y = work_area.y;
|
||||||
@ -5848,8 +5858,25 @@ constrain_position (MetaWindow *window,
|
|||||||
int se_x, se_y;
|
int se_x, se_y;
|
||||||
int offscreen_w, offscreen_h;
|
int offscreen_w, offscreen_h;
|
||||||
MetaRectangle work_area;
|
MetaRectangle work_area;
|
||||||
|
MetaRectangle window_area;
|
||||||
|
const MetaXineramaScreenInfo* xsi;
|
||||||
|
|
||||||
meta_window_get_work_area (window, FALSE, &work_area);
|
/* this is the rect for the window if it were where we're moving
|
||||||
|
* it now
|
||||||
|
*/
|
||||||
|
meta_window_get_outer_rect (window, &window_area);
|
||||||
|
window_area.x = x;
|
||||||
|
window_area.y = y;
|
||||||
|
if (fgeom)
|
||||||
|
{
|
||||||
|
window_area.x -= fgeom->left_width;
|
||||||
|
window_area.y -= fgeom->top_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
xsi = meta_screen_get_xinerama_for_rect (window->screen, &window_area);
|
||||||
|
meta_window_get_work_area_for_xinerama (window,
|
||||||
|
xsi->number,
|
||||||
|
&work_area);
|
||||||
|
|
||||||
/* (FIXME instead of TITLEBAR_LENGTH_ONSCREEN, get the actual
|
/* (FIXME instead of TITLEBAR_LENGTH_ONSCREEN, get the actual
|
||||||
* size of the menu control?).
|
* size of the menu control?).
|
||||||
@ -6568,65 +6595,89 @@ meta_window_set_gravity (MetaWindow *window,
|
|||||||
meta_error_trap_pop (window->display, FALSE);
|
meta_error_trap_pop (window->display, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
meta_window_get_work_area (MetaWindow *window,
|
get_work_area (MetaWindow *window,
|
||||||
gboolean for_current_xinerama,
|
MetaRectangle *area,
|
||||||
MetaRectangle *area)
|
int which_xinerama)
|
||||||
{
|
{
|
||||||
MetaRectangle space_area;
|
MetaRectangle space_area;
|
||||||
GList *tmp;
|
GList *tmp;
|
||||||
|
|
||||||
int left_strut;
|
int left_strut;
|
||||||
int right_strut;
|
int right_strut;
|
||||||
int top_strut;
|
int top_strut;
|
||||||
int bottom_strut;
|
int bottom_strut;
|
||||||
|
int xinerama_origin_x;
|
||||||
|
int xinerama_origin_y;
|
||||||
|
int xinerama_width;
|
||||||
|
int xinerama_height;
|
||||||
|
|
||||||
if (for_current_xinerama)
|
g_assert (which_xinerama >= 0);
|
||||||
{
|
|
||||||
const MetaXineramaScreenInfo *xinerama;
|
|
||||||
|
|
||||||
xinerama = meta_screen_get_xinerama_for_window (window->screen,
|
xinerama_origin_x = window->screen->xinerama_infos[which_xinerama].x_origin;
|
||||||
window);
|
xinerama_origin_y = window->screen->xinerama_infos[which_xinerama].y_origin;
|
||||||
|
xinerama_width = window->screen->xinerama_infos[which_xinerama].width;
|
||||||
|
xinerama_height = window->screen->xinerama_infos[which_xinerama].height;
|
||||||
|
|
||||||
left_strut = xinerama->x_origin;
|
left_strut = 0;
|
||||||
right_strut = window->screen->width - xinerama->width - xinerama->x_origin;
|
right_strut = 0;
|
||||||
top_strut = xinerama->y_origin;
|
top_strut = 0;
|
||||||
bottom_strut = window->screen->height - xinerama->height - xinerama->y_origin;
|
bottom_strut = 0;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
left_strut = 0;
|
|
||||||
right_strut = 0;
|
|
||||||
top_strut = 0;
|
|
||||||
bottom_strut = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = meta_window_get_workspaces (window);
|
tmp = meta_window_get_workspaces (window);
|
||||||
|
|
||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
{
|
{
|
||||||
meta_workspace_get_work_area (tmp->data, &space_area);
|
meta_workspace_get_work_area_for_xinerama (tmp->data,
|
||||||
|
which_xinerama,
|
||||||
|
&space_area);
|
||||||
|
|
||||||
left_strut = MAX (left_strut, space_area.x);
|
left_strut = MAX (left_strut, space_area.x - xinerama_origin_x);
|
||||||
right_strut = MAX (right_strut,
|
right_strut = MAX (right_strut,
|
||||||
(window->screen->width - space_area.x - space_area.width));
|
(xinerama_width -
|
||||||
top_strut = MAX (top_strut, space_area.y);
|
(space_area.x - xinerama_origin_x) -
|
||||||
|
space_area.width));
|
||||||
|
top_strut = MAX (top_strut, space_area.y - xinerama_origin_y);
|
||||||
bottom_strut = MAX (bottom_strut,
|
bottom_strut = MAX (bottom_strut,
|
||||||
(window->screen->height - space_area.y - space_area.height));
|
(xinerama_height -
|
||||||
|
(space_area.y - xinerama_origin_y) -
|
||||||
|
space_area.height));
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
area->x = left_strut;
|
area->x = xinerama_origin_x + left_strut;
|
||||||
area->y = top_strut;
|
area->y = xinerama_origin_y + top_strut;
|
||||||
area->width = window->screen->width - left_strut - right_strut;
|
area->width = xinerama_width - left_strut - right_strut;
|
||||||
area->height = window->screen->height - top_strut - bottom_strut;
|
area->height = xinerama_height - top_strut - bottom_strut;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Window %s has work area %d,%d %d x %d\n",
|
"Window %s has work area %d,%d %d x %d\n",
|
||||||
window->desc, area->x, area->y, area->width, area->height);
|
window->desc, area->x, area->y, area->width, area->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_get_work_area_current_xinerama (MetaWindow *window,
|
||||||
|
MetaRectangle *area)
|
||||||
|
{
|
||||||
|
const MetaXineramaScreenInfo *xinerama = NULL;
|
||||||
|
xinerama = meta_screen_get_xinerama_for_window (window->screen,
|
||||||
|
window);
|
||||||
|
|
||||||
|
meta_window_get_work_area_for_xinerama (window,
|
||||||
|
xinerama->number,
|
||||||
|
area);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_get_work_area_for_xinerama (MetaWindow *window,
|
||||||
|
int which_xinerama,
|
||||||
|
MetaRectangle *area)
|
||||||
|
{
|
||||||
|
g_return_if_fail (which_xinerama >= 0);
|
||||||
|
|
||||||
|
get_work_area (window,
|
||||||
|
area,
|
||||||
|
which_xinerama);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_window_same_application (MetaWindow *window,
|
meta_window_same_application (MetaWindow *window,
|
||||||
MetaWindow *other_window)
|
MetaWindow *other_window)
|
||||||
|
10
src/window.h
10
src/window.h
@ -413,10 +413,12 @@ void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||||||
gboolean meta_window_visible_on_workspace (MetaWindow *window,
|
gboolean meta_window_visible_on_workspace (MetaWindow *window,
|
||||||
MetaWorkspace *workspace);
|
MetaWorkspace *workspace);
|
||||||
|
|
||||||
/* Get minimum work area for all workspaces we're on */
|
void meta_window_get_work_area_current_xinerama (MetaWindow *window,
|
||||||
void meta_window_get_work_area (MetaWindow *window,
|
MetaRectangle *area);
|
||||||
gboolean for_current_xinerama,
|
void meta_window_get_work_area_for_xinerama (MetaWindow *window,
|
||||||
MetaRectangle *area);
|
int which_xinerama,
|
||||||
|
MetaRectangle *area);
|
||||||
|
|
||||||
|
|
||||||
gboolean meta_window_same_application (MetaWindow *window,
|
gboolean meta_window_same_application (MetaWindow *window,
|
||||||
MetaWindow *other_window);
|
MetaWindow *other_window);
|
||||||
|
219
src/workspace.c
219
src/workspace.c
@ -42,11 +42,12 @@ meta_workspace_new (MetaScreen *screen)
|
|||||||
g_list_append (workspace->screen->workspaces, workspace);
|
g_list_append (workspace->screen->workspaces, workspace);
|
||||||
workspace->windows = NULL;
|
workspace->windows = NULL;
|
||||||
|
|
||||||
workspace->work_area.x = 0;
|
workspace->work_areas = NULL;
|
||||||
workspace->work_area.y = 0;
|
workspace->work_areas_invalid = TRUE;
|
||||||
workspace->work_area.width = screen->width;
|
workspace->all_work_areas.x = 0;
|
||||||
workspace->work_area.height = screen->height;
|
workspace->all_work_areas.y = 0;
|
||||||
workspace->work_area_invalid = TRUE;
|
workspace->all_work_areas.width = 0;
|
||||||
|
workspace->all_work_areas.height = 0;
|
||||||
|
|
||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
@ -84,6 +85,7 @@ meta_workspace_free (MetaWorkspace *workspace)
|
|||||||
workspace->screen->workspaces =
|
workspace->screen->workspaces =
|
||||||
g_list_remove (workspace->screen->workspaces, workspace);
|
g_list_remove (workspace->screen->workspaces, workspace);
|
||||||
|
|
||||||
|
g_free (workspace->work_areas);
|
||||||
g_free (workspace);
|
g_free (workspace);
|
||||||
|
|
||||||
/* don't bother to reset names, pagers can just ignore
|
/* don't bother to reset names, pagers can just ignore
|
||||||
@ -304,7 +306,7 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
|||||||
GList *tmp;
|
GList *tmp;
|
||||||
GList *windows;
|
GList *windows;
|
||||||
|
|
||||||
if (workspace->work_area_invalid)
|
if (workspace->work_areas_invalid)
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Work area for workspace %d is already invalid\n",
|
"Work area for workspace %d is already invalid\n",
|
||||||
@ -316,7 +318,10 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
|||||||
"Invalidating work area for workspace %d\n",
|
"Invalidating work area for workspace %d\n",
|
||||||
meta_workspace_index (workspace));
|
meta_workspace_index (workspace));
|
||||||
|
|
||||||
workspace->work_area_invalid = TRUE;
|
g_free (workspace->work_areas);
|
||||||
|
workspace->work_areas = NULL;
|
||||||
|
|
||||||
|
workspace->work_areas_invalid = TRUE;
|
||||||
|
|
||||||
/* redo the size/position constraints on all windows */
|
/* redo the size/position constraints on all windows */
|
||||||
windows = meta_workspace_list_windows (workspace);
|
windows = meta_workspace_list_windows (workspace);
|
||||||
@ -335,81 +340,201 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
|
|||||||
meta_screen_queue_workarea_recalc (workspace->screen);
|
meta_screen_queue_workarea_recalc (workspace->screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
meta_workspace_get_work_area (MetaWorkspace *workspace,
|
ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||||
MetaRectangle *area)
|
|
||||||
{
|
{
|
||||||
if (workspace->work_area_invalid)
|
int left_strut = 0;
|
||||||
{
|
int right_strut = 0;
|
||||||
int left_strut = 0;
|
int top_strut = 0;
|
||||||
int right_strut = 0;
|
int bottom_strut = 0;
|
||||||
int top_strut = 0;
|
int all_left_strut = 0;
|
||||||
int bottom_strut = 0;
|
int all_right_strut = 0;
|
||||||
GList *tmp;
|
int all_top_strut = 0;
|
||||||
GList *windows;
|
int all_bottom_strut = 0;
|
||||||
|
int i;
|
||||||
|
GList *tmp;
|
||||||
|
GList *windows;
|
||||||
|
|
||||||
|
if (!workspace->work_areas_invalid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
windows = meta_workspace_list_windows (workspace);
|
||||||
|
|
||||||
|
g_free (workspace->work_areas);
|
||||||
|
workspace->work_areas = g_new (MetaRectangle,
|
||||||
|
workspace->screen->n_xinerama_infos);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < workspace->screen->n_xinerama_infos)
|
||||||
|
{
|
||||||
|
left_strut = 0;
|
||||||
|
right_strut = 0;
|
||||||
|
top_strut = 0;
|
||||||
|
bottom_strut = 0;
|
||||||
|
|
||||||
windows = meta_workspace_list_windows (workspace);
|
|
||||||
tmp = windows;
|
tmp = windows;
|
||||||
while (tmp != NULL)
|
while (tmp != NULL)
|
||||||
{
|
{
|
||||||
MetaWindow *w = tmp->data;
|
MetaWindow *w = tmp->data;
|
||||||
|
|
||||||
if (w->has_struts)
|
if (w->has_struts &&
|
||||||
|
(meta_screen_window_intersects_xinerama (w->screen, w, i)))
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Merging win %s with %d %d %d %d with %d %d %d %d\n",
|
"Merging win %s with %d %d %d %d "
|
||||||
|
"with %d %d %d %d\n",
|
||||||
w->desc,
|
w->desc,
|
||||||
w->left_strut, w->right_strut, w->top_strut, w->bottom_strut,
|
w->left_strut, w->right_strut,
|
||||||
left_strut, right_strut, top_strut, bottom_strut);
|
w->top_strut, w->bottom_strut,
|
||||||
left_strut = MAX (left_strut, w->left_strut);
|
left_strut, right_strut,
|
||||||
|
top_strut, bottom_strut);
|
||||||
|
|
||||||
|
left_strut = MAX (left_strut,
|
||||||
|
w->left_strut -
|
||||||
|
workspace->screen->xinerama_infos[i].x_origin);
|
||||||
|
all_left_strut = MAX (all_left_strut, w->left_strut);
|
||||||
|
|
||||||
right_strut = MAX (right_strut, w->right_strut);
|
right_strut = MAX (right_strut, w->right_strut);
|
||||||
top_strut = MAX (top_strut, w->top_strut);
|
all_right_strut = MAX (all_right_strut, w->right_strut);
|
||||||
|
|
||||||
|
top_strut = MAX (top_strut,
|
||||||
|
w->top_strut -
|
||||||
|
workspace->screen->xinerama_infos[i].y_origin);
|
||||||
|
all_top_strut = MAX (all_top_strut, w->top_strut);
|
||||||
|
|
||||||
bottom_strut = MAX (bottom_strut, w->bottom_strut);
|
bottom_strut = MAX (bottom_strut, w->bottom_strut);
|
||||||
|
all_bottom_strut = MAX (all_bottom_strut, w->bottom_strut);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free (windows);
|
|
||||||
|
|
||||||
/* Some paranoid robustness */
|
/* Some paranoid robustness */
|
||||||
#define MIN_SANE_AREA 100
|
#define MIN_SANE_AREA 100
|
||||||
|
|
||||||
if ((left_strut + right_strut) > (workspace->screen->width - MIN_SANE_AREA))
|
if ((left_strut + right_strut) >
|
||||||
|
(workspace->screen->xinerama_infos[i].width - MIN_SANE_AREA))
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Making left/right struts %d %d sane\n",
|
"Making left/right struts %d %d sane xinerama %d\n",
|
||||||
left_strut, right_strut);
|
left_strut, right_strut, i);
|
||||||
left_strut = (workspace->screen->width - MIN_SANE_AREA) / 2;
|
left_strut = (workspace->screen->xinerama_infos[i].width -
|
||||||
|
MIN_SANE_AREA) / 2;
|
||||||
right_strut = left_strut;
|
right_strut = left_strut;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((top_strut + bottom_strut) > (workspace->screen->height - MIN_SANE_AREA))
|
if ((top_strut + bottom_strut) >
|
||||||
|
(workspace->screen->xinerama_infos[i].height - MIN_SANE_AREA))
|
||||||
{
|
{
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Making top/bottom struts %d %d sane\n",
|
"Making top/bottom struts %d %d sane xinerama %d\n",
|
||||||
top_strut, bottom_strut);
|
top_strut, bottom_strut, i);
|
||||||
top_strut = (workspace->screen->height - MIN_SANE_AREA) / 2;
|
top_strut = (workspace->screen->xinerama_infos[i].height -
|
||||||
|
MIN_SANE_AREA) / 2;
|
||||||
bottom_strut = top_strut;
|
bottom_strut = top_strut;
|
||||||
}
|
}
|
||||||
|
|
||||||
workspace->work_area.x = left_strut;
|
/* FIXME even if we take struts to apply only to xineramas
|
||||||
workspace->work_area.y = top_strut;
|
* that the strut-specifying window overlaps, is it right
|
||||||
workspace->work_area.width = workspace->screen->width - left_strut - right_strut;
|
* to make the struts *relative to* the xinerama?
|
||||||
workspace->work_area.height = workspace->screen->height - top_strut - bottom_strut;
|
*/
|
||||||
|
workspace->work_areas[i].x =
|
||||||
workspace->work_area_invalid = FALSE;
|
left_strut + workspace->screen->xinerama_infos[i].x_origin;
|
||||||
|
workspace->work_areas[i].y = top_strut +
|
||||||
|
workspace->screen->xinerama_infos[i].y_origin;
|
||||||
|
workspace->work_areas[i].width =
|
||||||
|
workspace->screen->xinerama_infos[i].width -
|
||||||
|
left_strut - right_strut;
|
||||||
|
workspace->work_areas[i].height =
|
||||||
|
workspace->screen->xinerama_infos[i].height -
|
||||||
|
top_strut - bottom_strut;
|
||||||
|
|
||||||
meta_topic (META_DEBUG_WORKAREA,
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
"Computed work area for workspace %d: %d,%d %d x %d\n",
|
"Computed [unused] work area for workspace %d "
|
||||||
|
"xinerama %d: %d,%d %d x %d\n",
|
||||||
meta_workspace_index (workspace),
|
meta_workspace_index (workspace),
|
||||||
workspace->work_area.x,
|
i,
|
||||||
workspace->work_area.y,
|
workspace->work_areas[i].x,
|
||||||
workspace->work_area.width,
|
workspace->work_areas[i].y,
|
||||||
workspace->work_area.height);
|
workspace->work_areas[i].width,
|
||||||
|
workspace->work_areas[i].height);
|
||||||
|
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
*area = workspace->work_area;
|
g_list_free (windows);
|
||||||
|
|
||||||
|
if ((all_left_strut + all_right_strut) >
|
||||||
|
(workspace->screen->width - MIN_SANE_AREA))
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
|
"Making screen-wide left/right struts %d %d sane\n",
|
||||||
|
all_left_strut, all_right_strut);
|
||||||
|
all_left_strut = (workspace->screen->width - MIN_SANE_AREA) / 2;
|
||||||
|
all_right_strut = all_left_strut;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((all_top_strut + all_bottom_strut) >
|
||||||
|
(workspace->screen->height - MIN_SANE_AREA))
|
||||||
|
{
|
||||||
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
|
"Making top/bottom struts %d %d sane\n",
|
||||||
|
all_top_strut, all_bottom_strut);
|
||||||
|
all_top_strut = (workspace->screen->height - MIN_SANE_AREA) / 2;
|
||||||
|
all_bottom_strut = all_top_strut;
|
||||||
|
}
|
||||||
|
|
||||||
|
workspace->all_work_areas.x = all_left_strut;
|
||||||
|
workspace->all_work_areas.y = all_top_strut;
|
||||||
|
workspace->all_work_areas.width =
|
||||||
|
workspace->screen->width - all_left_strut - all_right_strut;
|
||||||
|
workspace->all_work_areas.height =
|
||||||
|
workspace->screen->height - all_top_strut - all_bottom_strut;
|
||||||
|
|
||||||
|
/* FIXME Here we disable all the per-xinerama work done earlier,
|
||||||
|
* because we don't have a spec for how it should work yet.
|
||||||
|
* If we do rely on which windows overlap what, work areas
|
||||||
|
* will need to be invalidated when we change a strut-setting
|
||||||
|
* window's size/position in move_resize_internal
|
||||||
|
*/
|
||||||
|
i = 0;
|
||||||
|
while (i < workspace->screen->n_xinerama_infos)
|
||||||
|
{
|
||||||
|
workspace->work_areas[i] = workspace->all_work_areas;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
workspace->work_areas_invalid = FALSE;
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_WORKAREA,
|
||||||
|
"Computed work area for workspace %d: %d,%d %d x %d\n",
|
||||||
|
meta_workspace_index (workspace),
|
||||||
|
workspace->all_work_areas.x,
|
||||||
|
workspace->all_work_areas.y,
|
||||||
|
workspace->all_work_areas.width,
|
||||||
|
workspace->all_work_areas.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_workspace_get_work_area_for_xinerama (MetaWorkspace *workspace,
|
||||||
|
int which_xinerama,
|
||||||
|
MetaRectangle *area)
|
||||||
|
{
|
||||||
|
g_assert (which_xinerama >= 0);
|
||||||
|
|
||||||
|
ensure_work_areas_validated (workspace);
|
||||||
|
g_assert (which_xinerama < workspace->screen->n_xinerama_infos);
|
||||||
|
|
||||||
|
*area = workspace->work_areas[which_xinerama];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
|
||||||
|
MetaRectangle *area)
|
||||||
|
{
|
||||||
|
ensure_work_areas_validated (workspace);
|
||||||
|
|
||||||
|
*area = workspace->all_work_areas;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_VERBOSE_MODE
|
#ifdef WITH_VERBOSE_MODE
|
||||||
|
@ -41,8 +41,10 @@ struct _MetaWorkspace
|
|||||||
|
|
||||||
GList *windows;
|
GList *windows;
|
||||||
|
|
||||||
MetaRectangle work_area;
|
MetaRectangle all_work_areas;
|
||||||
guint work_area_invalid : 1;
|
|
||||||
|
MetaRectangle *work_areas;
|
||||||
|
guint work_areas_invalid : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
MetaWorkspace* meta_workspace_new (MetaScreen *screen);
|
MetaWorkspace* meta_workspace_new (MetaScreen *screen);
|
||||||
@ -61,8 +63,16 @@ int meta_workspace_index (MetaWorkspace *workspace);
|
|||||||
GList* meta_workspace_list_windows (MetaWorkspace *workspace);
|
GList* meta_workspace_list_windows (MetaWorkspace *workspace);
|
||||||
|
|
||||||
void meta_workspace_invalidate_work_area (MetaWorkspace *workspace);
|
void meta_workspace_invalidate_work_area (MetaWorkspace *workspace);
|
||||||
void meta_workspace_get_work_area (MetaWorkspace *workspace,
|
|
||||||
MetaRectangle *area);
|
|
||||||
|
void meta_workspace_get_work_area_for_xinerama (MetaWorkspace *workspace,
|
||||||
|
int which_xinerama,
|
||||||
|
MetaRectangle *area);
|
||||||
|
void meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
|
||||||
|
MetaRectangle *area);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace *workspace,
|
MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace *workspace,
|
||||||
|
Loading…
Reference in New Issue
Block a user