From db0a7e29789b04fde38b9ca3b4aa855a6d9526f3 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 29 Aug 2001 03:37:03 +0000 Subject: [PATCH] Unbreak tab popup a bit. 2001-08-28 Havoc Pennington 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 --- ChangeLog | 14 +++++ src/core.c | 6 +-- src/keybindings.c | 50 ++++++++++------- src/screen.c | 3 +- src/stack.c | 36 +++++++------ src/stack.h | 11 ++-- src/tabpopup.c | 18 ++++++- src/window.c | 124 +++++++++++++++++++++++++++++++++---------- src/window.h | 25 +++++++-- src/wm-tester/main.c | 9 ++-- 10 files changed, 211 insertions(+), 85 deletions(-) diff --git a/ChangeLog b/ChangeLog index 364e9fff9..a5068f70d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2001-08-28 Havoc Pennington + + 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 * src/window.c (constrain_position): force fullscreen windows to diff --git a/src/core.c b/src/core.c index 9e709074d..d4d034594 100644 --- a/src/core.c +++ b/src/core.c @@ -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 diff --git a/src/keybindings.c b/src/keybindings.c index 0002cfdb8..c61b683a1 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -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) { diff --git a/src/screen.c b/src/screen.c index b1795f0c4..462855382 100644 --- a/src/screen.c +++ b/src/screen.c @@ -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); diff --git a/src/stack.c b/src/stack.c index b0bd94d55..d030cf271 100644 --- a/src/stack.c +++ b/src/stack.c @@ -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 || diff --git a/src/stack.h b/src/stack.h index d126b644d..605bd0280 100644 --- a/src/stack.h +++ b/src/stack.h @@ -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, diff --git a/src/tabpopup.c b/src/tabpopup.c index 4e1291a50..8ac522a5d 100644 --- a/src/tabpopup.c +++ b/src/tabpopup.c @@ -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; } diff --git a/src/window.c b/src/window.c index 8ff44a7e3..b086946b3 100644 --- a/src/window.c +++ b/src/window.c @@ -33,6 +33,14 @@ #include +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 diff --git a/src/window.h b/src/window.h index 3913d2366..e13bca333 100644 --- a/src/window.h +++ b/src/window.h @@ -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 diff --git a/src/wm-tester/main.c b/src/wm-tester/main.c index f58742d64..bcf1f104b 100644 --- a/src/wm-tester/main.c +++ b/src/wm-tester/main.c @@ -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);