implement

2002-06-06  Havoc Pennington  <hp@pobox.com>

	* 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. ;-)
This commit is contained in:
Havoc Pennington 2002-06-07 03:18:46 +00:00 committed by Havoc Pennington
parent 47f0557175
commit a7c8cea1b5
7 changed files with 157 additions and 76 deletions

View File

@ -1,3 +1,20 @@
2002-06-06 Havoc Pennington <hp@pobox.com>
* 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 <jcape@ignore-your.tv> 2002-06-06 James M. Cape <jcape@ignore-your.tv>
* src/themes/Esco/metacity-theme-1.xml: Increase the border size * src/themes/Esco/metacity-theme-1.xml: Increase the border size

View File

@ -332,6 +332,8 @@ meta_display_open (const char *name)
display->leader_window = None; display->leader_window = None;
display->no_focus_window = None; display->no_focus_window = None;
display->xinerama_cache_invalidated = TRUE;
screens = NULL; screens = NULL;
#ifdef HAVE_GTK_MULTIHEAD #ifdef HAVE_GTK_MULTIHEAD
@ -876,6 +878,7 @@ event_callback (XEvent *event,
filter_out_event = FALSE; filter_out_event = FALSE;
display->current_time = event_get_time (display, event); display->current_time = event_get_time (display, event);
display->xinerama_cache_invalidated = TRUE;
modified = event_get_modified_window (display, event); modified = event_get_modified_window (display, event);

View File

@ -210,6 +210,9 @@ struct _MetaDisplay
unsigned int ignored_modifier_mask; unsigned int ignored_modifier_mask;
unsigned int num_lock_mask; unsigned int num_lock_mask;
unsigned int scroll_lock_mask; unsigned int scroll_lock_mask;
/* Xinerama cache */
unsigned int xinerama_cache_invalidated : 1;
}; };
gboolean meta_display_open (const char *name); gboolean meta_display_open (const char *name);

View File

@ -246,6 +246,7 @@ meta_window_place (MetaWindow *window,
int *new_y) int *new_y)
{ {
GList *windows; GList *windows;
const MetaXineramaScreenInfo *xi;
/* frame member variables should NEVER be used in here, only /* frame member variables should NEVER be used in here, only
* MetaFrameGeometry. But remember fgeom == NULL * MetaFrameGeometry. But remember fgeom == NULL
@ -360,9 +361,8 @@ meta_window_place (MetaWindow *window,
{ {
/* Center on screen */ /* Center on screen */
int w, h; int w, h;
const MetaXineramaScreenInfo *xi;
/* I think whole screen will look nicer than workarea */ /* Warning, this function is a round trip! */
xi = meta_screen_get_current_xinerama (window->screen); xi = meta_screen_get_current_xinerama (window->screen);
w = xi->width; w = xi->width;
@ -405,9 +405,12 @@ meta_window_place (MetaWindow *window,
} }
} }
/* Warning, this is a round trip! */
xi = meta_screen_get_current_xinerama (window->screen);
/* "Origin" placement algorithm */ /* "Origin" placement algorithm */
x = 0; x = xi->x_origin;
y = 0; y = xi->y_origin;
/* Cascade */ /* Cascade */
find_next_cascade (window, fgeom, windows, x, y, &x, &y); find_next_cascade (window, fgeom, windows, x, y, &x, &y);

View File

@ -236,6 +236,8 @@ meta_screen_new (MetaDisplay *display,
screen->xinerama_infos = NULL; screen->xinerama_infos = NULL;
screen->n_xinerama_infos = 0; screen->n_xinerama_infos = 0;
screen->last_xinerama_index = 0;
#ifdef HAVE_XINERAMA #ifdef HAVE_XINERAMA
if (XineramaQueryExtension (display->xdisplay, if (XineramaQueryExtension (display->xdisplay,
&xinerama_event_base, &xinerama_event_base,
@ -266,6 +268,14 @@ meta_screen_new (MetaDisplay *display,
screen->xinerama_infos[i].width = infos[i].width; screen->xinerama_infos[i].width = infos[i].width;
screen->xinerama_infos[i].height = infos[i].height; 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; ++i;
} }
} }
@ -810,7 +820,9 @@ meta_screen_get_xinerama_for_window (MetaScreen *screen,
best_xinerama = 0; best_xinerama = 0;
xinerama_score = 0; xinerama_score = 0;
for (i = 0; i < screen->n_xinerama_infos; i++) { i = 0;
while (i < screen->n_xinerama_infos)
{
MetaRectangle dest, screen_info; MetaRectangle dest, screen_info;
screen_info.x = screen->xinerama_infos[i].x_origin; screen_info.x = screen->xinerama_infos[i].x_origin;
@ -826,6 +838,8 @@ meta_screen_get_xinerama_for_window (MetaScreen *screen,
best_xinerama = i; best_xinerama = i;
} }
} }
++i;
} }
return &screen->xinerama_infos[best_xinerama]; return &screen->xinerama_infos[best_xinerama];
@ -834,9 +848,54 @@ meta_screen_get_xinerama_for_window (MetaScreen *screen,
const MetaXineramaScreenInfo* const MetaXineramaScreenInfo*
meta_screen_get_current_xinerama (MetaScreen *screen) meta_screen_get_current_xinerama (MetaScreen *screen)
{ {
/* FIXME how do we decide which is current? */ if (screen->n_xinerama_infos == 1)
return 0;
return &screen->xinerama_infos[0]; /* Sadly, we have to do it this way. Yuck.
*/
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 #define _NET_WM_ORIENTATION_HORZ 0

View File

@ -63,6 +63,9 @@ struct _MetaScreen
MetaXineramaScreenInfo *xinerama_infos; MetaXineramaScreenInfo *xinerama_infos;
int n_xinerama_infos; int n_xinerama_infos;
/* Cache the current Xinerama */
int last_xinerama_index;
guint work_area_idle; guint work_area_idle;
int rows_of_workspaces; int rows_of_workspaces;

View File

@ -1862,50 +1862,11 @@ meta_window_move_resize_internal (MetaWindow *window,
*/ */
int client_move_x; int client_move_x;
int client_move_y; int client_move_y;
const MetaXineramaScreenInfo *xinerama;
is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0; is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0;
do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0; do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0;
is_user_action = (flags & META_USER_MOVE_RESIZE) != 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. */ /* We don't need it in the idle queue anymore. */
meta_window_unqueue_move_resize (window); meta_window_unqueue_move_resize (window);
@ -4999,10 +4960,21 @@ constrain_size (MetaWindow *window,
meta_window_get_work_area (window, &work_area); meta_window_get_work_area (window, &work_area);
/* Get the allowed size ranges, considering maximized, etc. */ /* Get the allowed size ranges, considering maximized, etc. */
if (window->fullscreen || if (window->fullscreen)
window->type == META_WINDOW_DESKTOP || {
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) window->type == META_WINDOW_DOCK)
{ {
fullw = window->screen->width; fullw = window->screen->width;
fullh = window->screen->height; fullh = window->screen->height;
} }
@ -5137,16 +5109,28 @@ constrain_position (MetaWindow *window,
} }
else if (window->fullscreen) else if (window->fullscreen)
{ {
x = 0; const MetaXineramaScreenInfo *xinerama;
y = 0;
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) /* If the window's geometry gridding (e.g. for a terminal)
* prevents fullscreen, center the window within * prevents fullscreen, center the window within
* the screen area. * 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) else if (window->maximized)
{ {
@ -5670,11 +5654,20 @@ meta_window_get_work_area (MetaWindow *window,
{ {
MetaRectangle space_area; MetaRectangle space_area;
GList *tmp; GList *tmp;
const MetaXineramaScreenInfo *xinerama;
int left_strut = 0; int left_strut;
int right_strut = 0; int right_strut;
int top_strut = 0; int top_strut;
int bottom_strut = 0; int bottom_strut;
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); tmp = meta_window_get_workspaces (window);