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>
* src/themes/Esco/metacity-theme-1.xml: Increase the border size

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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;