Unbreak tab popup a bit.

2001-08-28  Havoc Pennington  <hp@pobox.com>

        Unbreak tab popup a bit.

	* src/stack.c (meta_stack_get_tab_list): add workspace argument
	(meta_stack_get_tab_next): add workspace argument

	* src/window.c: implement recording of the last user-initiated
	window position, so we can magically handle moving panels around
	really nicely.

	* src/wm-tester/main.c (set_up_icon_windows): fix to use new GTK
	API
This commit is contained in:
Havoc Pennington 2001-08-29 03:37:03 +00:00 committed by Havoc Pennington
parent 4d2f018ddb
commit db0a7e2978
10 changed files with 211 additions and 85 deletions

View File

@ -1,3 +1,17 @@
2001-08-28 Havoc Pennington <hp@pobox.com>
Unbreak tab popup a bit.
* src/stack.c (meta_stack_get_tab_list): add workspace argument
(meta_stack_get_tab_next): add workspace argument
* src/window.c: implement recording of the last user-initiated
window position, so we can magically handle moving panels around
really nicely.
* src/wm-tester/main.c (set_up_icon_windows): fix to use new GTK
API
2001-08-24 Havoc Pennington <hp@pobox.com>
* src/window.c (constrain_position): force fullscreen windows to

View File

@ -91,8 +91,7 @@ meta_core_user_move (Display *xdisplay,
if (window == NULL || window->frame == NULL)
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
window->user_has_moved = TRUE;
meta_window_move (window, x, y);
meta_window_move (window, TRUE, x, y);
}
void
@ -111,8 +110,7 @@ meta_core_user_resize (Display *xdisplay,
if (window == NULL || window->frame == NULL)
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
window->user_has_resized = TRUE;
meta_window_resize_with_gravity (window, width, height, gravity);
meta_window_resize_with_gravity (window, TRUE, width, height, gravity);
}
void

View File

@ -581,6 +581,7 @@ process_keyboard_move_grab (MetaDisplay *display,
case XK_Escape:
/* End move and restore to original position */
meta_window_move_resize (display->grab_window,
TRUE,
display->grab_initial_window_pos.x,
display->grab_initial_window_pos.y,
display->grab_initial_window_pos.width,
@ -592,7 +593,7 @@ process_keyboard_move_grab (MetaDisplay *display,
}
if (handled)
meta_window_move (window, x, y);
meta_window_move (window, TRUE, x, y);
return handled;
}
@ -832,6 +833,7 @@ handle_tab_forward (MetaDisplay *display,
if (display->focus_window != NULL)
{
window = meta_stack_get_tab_next (display->focus_window->screen->stack,
display->focus_window->screen->active_workspace,
display->focus_window,
FALSE);
}
@ -849,7 +851,8 @@ handle_tab_forward (MetaDisplay *display,
if (screen)
{
window = meta_stack_get_tab_next (screen->stack,
event_window,
screen->active_workspace,
NULL,
FALSE);
}
}
@ -890,6 +893,7 @@ handle_tab_backward (MetaDisplay *display,
if (display->focus_window != NULL)
{
window = meta_stack_get_tab_next (display->focus_window->screen->stack,
display->focus_window->screen->active_workspace,
display->focus_window,
TRUE);
}
@ -907,7 +911,8 @@ handle_tab_backward (MetaDisplay *display,
if (screen)
{
window = meta_stack_get_tab_next (screen->stack,
event_window,
screen->active_workspace,
NULL,
TRUE);
}
}
@ -940,29 +945,36 @@ handle_focus_previous (MetaDisplay *display,
gpointer data)
{
MetaWindow *window;
MetaScreen *screen;
meta_verbose ("Focus previous window\n");
screen = meta_display_screen_for_root (display,
event->xkey.root);
if (screen == NULL)
return;
window = display->prev_focus_window;
if (window &&
!meta_workspace_contains_window (screen->active_workspace,
window))
window = NULL;
if (window == NULL)
{
/* Pick first window in tab order */
MetaScreen *screen;
screen = meta_display_screen_for_root (display,
event->xkey.root);
/* We get the screen because event_window may be NULL,
* in which case we can't use event_window->screen
*/
if (screen)
{
window = meta_stack_get_tab_next (screen->stack,
event_window,
TRUE);
}
/* Pick first window in tab order */
window = meta_stack_get_tab_next (screen->stack,
screen->active_workspace,
NULL,
TRUE);
}
if (window &&
!meta_workspace_contains_window (screen->active_workspace,
window))
window = NULL;
if (window)
{

View File

@ -464,7 +464,8 @@ meta_screen_ensure_tab_popup (MetaScreen *screen)
if (screen->tab_popup)
return;
tab_list = meta_stack_get_tab_list (screen->stack);
tab_list = meta_stack_get_tab_list (screen->stack,
screen->active_workspace);
len = g_slist_length (tab_list);
entries = g_new (MetaTabEntry, len + 1);

View File

@ -862,12 +862,23 @@ find_tab_backward (MetaStack *stack,
/* This ignores the dock/desktop layers */
MetaWindow*
meta_stack_get_tab_next (MetaStack *stack,
MetaWindow *window,
gboolean backward)
meta_stack_get_tab_next (MetaStack *stack,
MetaWorkspace *workspace,
MetaWindow *window,
gboolean backward)
{
int i;
if (workspace && window)
{
/* This is a paranoia check, because races can happen where
* you get a key shortcut or something on a window just as you
* are moving workspaces to one the window isn't on
*/
if (!meta_workspace_contains_window (workspace, window))
return NULL;
}
if (stack->windows->len == 0)
return NULL;
@ -881,11 +892,7 @@ meta_stack_get_tab_next (MetaStack *stack,
w = g_array_index (stack->windows, Window, i);
if (w == window->xwindow)
{
MetaWorkspace *workspace;
workspace = window->screen->active_workspace;
{
if (backward)
return find_tab_backward (stack, workspace, i);
else
@ -900,14 +907,15 @@ meta_stack_get_tab_next (MetaStack *stack,
* window and we need to wrap around
*/
if (backward)
return find_tab_backward (stack, NULL,
return find_tab_backward (stack, workspace,
stack->windows->len);
else
return find_tab_forward (stack, NULL, -1);
return find_tab_forward (stack, workspace, -1);
}
GSList*
meta_stack_get_tab_list (MetaStack *stack)
meta_stack_get_tab_list (MetaStack *stack,
MetaWorkspace *workspace)
{
GSList *list;
int i;
@ -918,15 +926,9 @@ meta_stack_get_tab_list (MetaStack *stack)
while (i < stack->windows->len)
{
MetaWindow *window;
MetaWorkspace *workspace;
window = meta_display_lookup_x_window (stack->screen->display,
GET_XWINDOW (stack, i));
if (window)
workspace = window->screen->active_workspace;
else
workspace = NULL;
if (window && IN_TAB_CHAIN (window) &&
(workspace == NULL ||

View File

@ -93,10 +93,13 @@ MetaWindow* meta_stack_get_above (MetaStack *stack,
MetaWindow* meta_stack_get_below (MetaStack *stack,
MetaWindow *window);
MetaWindow* meta_stack_get_tab_next (MetaStack *stack,
MetaWindow *window,
gboolean backward);
GSList* meta_stack_get_tab_list (MetaStack *stack);
MetaWindow* meta_stack_get_tab_next (MetaStack *stack,
MetaWorkspace *workspace,
MetaWindow *window,
gboolean backward);
GSList* meta_stack_get_tab_list (MetaStack *stack,
MetaWorkspace *workspace);
/* -1 if a < b, etc. */
int meta_stack_windows_cmp (MetaStack *stack,
MetaWindow *window_a,

View File

@ -61,6 +61,7 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries)
GtkWidget *table;
GList *tmp;
GtkWidget *frame;
int max_label_width;
popup = g_new (MetaTabPopup, 1);
popup->window = gtk_window_new (GTK_WINDOW_POPUP);
@ -118,6 +119,7 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries)
3, 3);
max_label_width = 0;
top = 0;
bottom = 1;
tmp = popup->entries;
@ -130,6 +132,7 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries)
while (tmp && left < width)
{
GtkWidget *image;
GtkRequisition req;
TabEntry *te;
@ -148,6 +151,12 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries)
left, right, top, bottom,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
0, 0);
/* Efficiency rules! */
gtk_label_set_text (GTK_LABEL (popup->label),
te->title);
gtk_widget_size_request (popup->label, &req);
max_label_width = MAX (max_label_width, req.width);
tmp = tmp->next;
@ -158,7 +167,14 @@ meta_ui_tab_popup_new (const MetaTabEntry *entries)
++top;
++bottom;
}
/* remove all the temporary text */
gtk_label_set_text (GTK_LABEL (popup->label), "");
gtk_window_set_default_size (GTK_WINDOW (popup->window),
max_label_width + 20 /* random number */,
-1);
return popup;
}

View File

@ -33,6 +33,14 @@
#include <X11/Xatom.h>
typedef enum
{
META_IS_CONFIGURE_REQUEST = 1 << 0,
META_DO_GRAVITY_ADJUST = 1 << 1,
META_USER_RESIZE = 1 << 2,
META_USER_MOVE = 1 << 3
} MetaMoveResizeFlags;
static void constrain_size (MetaWindow *window,
MetaFrameGeometry *fgeom,
int width,
@ -83,14 +91,14 @@ static void adjust_for_gravity (MetaWindow *window,
int y,
int *xp,
int *yp);
static void meta_window_move_resize_internal (MetaWindow *window,
gboolean is_configure_request,
gboolean do_gravity_adjust,
int resize_gravity,
int root_x_nw,
int root_y_nw,
int w,
int h);
static void meta_window_move_resize_internal (MetaWindow *window,
MetaMoveResizeFlags flags,
int resize_gravity,
int root_x_nw,
int root_y_nw,
int w,
int h);
void meta_window_move_resize_now (MetaWindow *window);
@ -250,6 +258,7 @@ meta_window_new (MetaDisplay *display, Window xwindow,
/* And this is our unmaximized size */
window->saved_rect = window->rect;
window->user_rect = window->rect;
window->depth = attrs.depth;
window->xvisual = attrs.visual;
@ -485,7 +494,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
* passing TRUE for is_configure_request, ICCCM says
* initial map is handled same as configure request
*/
meta_window_move_resize_internal (window, TRUE, FALSE,
meta_window_move_resize_internal (window,
META_IS_CONFIGURE_REQUEST,
NorthWestGravity,
window->size_hints.x,
window->size_hints.y,
@ -604,7 +614,7 @@ meta_window_apply_session_info (MetaWindow *window,
x, y, w, h, window->desc);
meta_window_move_resize_internal (window,
FALSE, TRUE,
META_DO_GRAVITY_ADJUST,
NorthWestGravity,
x, y, w, h);
}
@ -1077,6 +1087,7 @@ meta_window_unmaximize (MetaWindow *window)
window->maximized = FALSE;
meta_window_move_resize (window,
TRUE,
window->saved_rect.x,
window->saved_rect.y,
window->saved_rect.width,
@ -1277,9 +1288,7 @@ adjust_for_gravity (MetaWindow *window,
static void
meta_window_move_resize_internal (MetaWindow *window,
gboolean is_configure_request,
/* only relevant if !is_configure_request */
gboolean do_gravity_adjust,
MetaMoveResizeFlags flags,
int resize_gravity,
int root_x_nw,
int root_y_nw,
@ -1299,16 +1308,27 @@ meta_window_move_resize_internal (MetaWindow *window,
int pos_dx;
int pos_dy;
int frame_size_dx;
int frame_size_dy;
int frame_size_dy;
gboolean is_configure_request;
gboolean do_gravity_adjust;
gboolean is_user_resize;
gboolean is_user_move;
is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0;
do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0;
is_user_resize = (flags & META_USER_RESIZE) != 0;
is_user_move = (flags & META_USER_MOVE) != 0;
{
int oldx, oldy;
meta_window_get_position (window, &oldx, &oldy);
meta_verbose ("Move/resize %s to %d,%d %dx%d%s from %d,%d %dx%d\n",
meta_verbose ("Move/resize %s to %d,%d %dx%d%s%s%s from %d,%d %dx%d\n",
window->desc, root_x_nw, root_y_nw, w, h,
is_configure_request ? " (configure request)" : "",
is_user_resize ? " (user resize)" : "",
is_user_move ? " (user move)" : "",
oldx, oldy, window->rect.width, window->rect.height);
}
}
if (window->frame)
meta_frame_calc_geometry (window->frame,
@ -1549,6 +1569,22 @@ meta_window_move_resize_internal (MetaWindow *window,
if (need_configure_notify)
send_configure_notify (window);
if (is_user_resize)
{
window->user_has_resized = TRUE;
window->user_rect.width = window->rect.width;
window->user_rect.height = window->rect.height;
}
if (is_user_move)
{
window->user_has_moved = TRUE;
meta_window_get_position (window,
&window->user_rect.x,
&window->user_rect.y);
}
/* Invariants leaving this function are:
* a) window->rect and frame->rect reflect the actual
* server-side size/pos of window->xwindow and frame->xwindow
@ -1558,6 +1594,7 @@ meta_window_move_resize_internal (MetaWindow *window,
void
meta_window_resize (MetaWindow *window,
gboolean user_op,
int w,
int h)
{
@ -1565,17 +1602,20 @@ meta_window_resize (MetaWindow *window,
meta_window_get_position (window, &x, &y);
meta_window_move_resize_internal (window, FALSE, FALSE,
meta_window_move_resize_internal (window,
user_op ? META_USER_RESIZE : 0,
NorthWestGravity,
x, y, w, h);
}
void
meta_window_move (MetaWindow *window,
gboolean user_op,
int root_x_nw,
int root_y_nw)
{
meta_window_move_resize_internal (window, FALSE, FALSE,
meta_window_move_resize_internal (window,
user_op ? META_USER_MOVE : 0,
NorthWestGravity,
root_x_nw, root_y_nw,
window->rect.width,
@ -1584,12 +1624,14 @@ meta_window_move (MetaWindow *window,
void
meta_window_move_resize (MetaWindow *window,
gboolean user_op,
int root_x_nw,
int root_y_nw,
int w,
int h)
{
meta_window_move_resize_internal (window, FALSE, FALSE,
meta_window_move_resize_internal (window,
user_op ? META_USER_MOVE | META_USER_RESIZE : 0,
NorthWestGravity,
root_x_nw, root_y_nw,
w, h);
@ -1597,6 +1639,7 @@ meta_window_move_resize (MetaWindow *window,
void
meta_window_resize_with_gravity (MetaWindow *window,
gboolean user_op,
int w,
int h,
int gravity)
@ -1605,7 +1648,8 @@ meta_window_resize_with_gravity (MetaWindow *window,
meta_window_get_position (window, &x, &y);
meta_window_move_resize_internal (window, FALSE, FALSE,
meta_window_move_resize_internal (window,
user_op ? META_USER_RESIZE : 0,
gravity,
x, y, w, h);
}
@ -1614,11 +1658,17 @@ void
meta_window_move_resize_now (MetaWindow *window)
{
int x, y;
/* If constraints have changed then we'll snap back to wherever
* the user had the window
*/
meta_window_get_user_position (window, &x, &y);
meta_window_get_position (window, &x, &y);
meta_window_move_resize (window, x, y,
window->rect.width, window->rect.height);
meta_window_move_resize (window, FALSE, x, y,
window->user_has_resized ?
window->user_rect.width : window->rect.width,
window->user_has_resized ?
window->user_rect.height : window->rect.height);
}
void
@ -1649,6 +1699,24 @@ meta_window_get_position (MetaWindow *window,
}
}
void
meta_window_get_user_position (MetaWindow *window,
int *x,
int *y)
{
if (window->user_has_moved)
{
if (x)
*x = window->user_rect.x;
if (y)
*y = window->user_rect.y;
}
else
{
meta_window_get_position (window, x, y);
}
}
void
meta_window_get_gravity_position (MetaWindow *window,
int *root_x,
@ -2060,7 +2128,7 @@ meta_window_configure_request (MetaWindow *window,
* move_resize_internal arguments.
*/
meta_window_move_resize_internal (window, TRUE, FALSE,
meta_window_move_resize_internal (window, META_IS_CONFIGURE_REQUEST,
only_resize ?
window->size_hints.win_gravity : NorthWestGravity,
window->size_hints.x,
@ -4600,7 +4668,6 @@ update_move (MetaWindow *window,
dx = x - window->display->grab_root_x;
dy = y - window->display->grab_root_y;
window->user_has_moved = TRUE;
new_x = window->display->grab_initial_window_pos.x + dx;
new_y = window->display->grab_initial_window_pos.y + dy;
@ -4611,7 +4678,7 @@ update_move (MetaWindow *window,
new_y = meta_window_find_nearest_horizontal_edge (window, new_y);
}
meta_window_move (window, new_x, new_y);
meta_window_move (window, TRUE, new_x, new_y);
}
static void
@ -4696,8 +4763,7 @@ update_resize (MetaWindow *window,
break;
}
window->user_has_resized = TRUE;
meta_window_resize_with_gravity (window, new_w, new_h, gravity);
meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
}
void

View File

@ -156,8 +156,7 @@ struct _MetaWindow
guint has_focus : 1;
/* Track whether the user has ever manually modified
* the window; if so, we remove some constraints
* that exist on program modifications.
* the window; if so, we can use the saved user size/pos
*/
guint user_has_resized : 1;
guint user_has_moved : 1;
@ -191,7 +190,7 @@ struct _MetaWindow
* is withdrawing the window.
*/
int unmaps_pending;
/* The size we set the window to last (i.e. what we believe
* to be its actual size on the server). The x, y are
* the actual server-side x,y so are relative to the frame
@ -205,6 +204,17 @@ struct _MetaWindow
* above.
*/
MetaRectangle saved_rect;
/* This is the geometry the window had after the last user-initiated
* move/resize operations. We use this whenever we are moving the
* implicitly (for example, if we move to avoid a panel, we
* can snap back to this position if the panel moves again)
*
* Position valid if user_has_moved, size valid if user_has_resized
*
* Position always in root coords, unlike window->rect
*/
MetaRectangle user_rect;
/* Requested geometry */
int border_width;
@ -235,17 +245,21 @@ void meta_window_unstick (MetaWindow *window);
/* args to move are window pos, not frame pos */
void meta_window_move (MetaWindow *window,
gboolean user_op,
int root_x_nw,
int root_y_nw);
void meta_window_resize (MetaWindow *window,
gboolean user_op,
int w,
int h);
void meta_window_move_resize (MetaWindow *window,
gboolean user_op,
int root_x_nw,
int root_y_nw,
int w,
int h);
void meta_window_resize_with_gravity (MetaWindow *window,
void meta_window_resize_with_gravity (MetaWindow *window,
gboolean user_op,
int w,
int h,
int gravity);
@ -259,6 +273,9 @@ void meta_window_queue_move_resize (MetaWindow *window);
void meta_window_get_position (MetaWindow *window,
int *x,
int *y);
void meta_window_get_user_position (MetaWindow *window,
int *x,
int *y);
/* gets position we need to set to stay in current position,
* assuming position will be gravity-compensated. i.e.
* this is the position a client would send in a configure

View File

@ -44,7 +44,7 @@ main (int argc, char **argv)
gboolean do_evil;
gboolean do_icon_windows;
gtk_init (&argc, &argv);
gtk_init (&argc, &argv);
do_evil = FALSE;
do_icon_windows = FALSE;
@ -185,8 +185,6 @@ set_up_icon_windows (void)
c = gtk_button_new_with_label ("Icon window");
gtk_container_add (GTK_CONTAINER (w), c);
gtk_widget_realize (w);
icons = NULL;
pix = gtk_widget_render_icon (w,
@ -213,9 +211,8 @@ set_up_icon_windows (void)
NULL);
icons = g_list_append (icons, pix);
}
if (!gdk_window_set_icon_list (w->window, icons))
g_warning ("_NET_WM_ICON not supported?");
gtk_window_set_icon_list (GTK_WINDOW (w), icons);
g_list_foreach (icons, (GFunc) g_object_unref, NULL);
g_list_free (icons);