Remove tabpopup and friends

These are unused in gnome-shell, and add complexity. Remove them.
This commit is contained in:
Jasper St. Pierre 2013-04-23 12:52:25 -04:00
parent 0054e637cc
commit 9c362f7fe4
12 changed files with 5 additions and 2368 deletions

View File

@ -94,8 +94,6 @@ libmutter_la_SOURCES = \
core/display.c \
core/display-private.h \
meta/display.h \
ui/draw-workspace.c \
ui/draw-workspace.h \
core/edge-resistance.c \
core/edge-resistance.h \
core/edid-parse.c \
@ -163,8 +161,6 @@ libmutter_la_SOURCES = \
ui/metaaccellabel.h \
ui/resizepopup.c \
ui/resizepopup.h \
ui/tabpopup.c \
ui/tabpopup.h \
ui/theme-parser.c \
ui/theme.c \
meta/theme.h \

View File

@ -4176,20 +4176,6 @@ meta_display_end_grab_op (MetaDisplay *display,
meta_window_raise (display->grab_window);
}
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) ||
display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING)
{
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
meta_screen_tab_popup_destroy (display->grab_screen);
else
meta_screen_workspace_popup_destroy (display->grab_screen);
/* If the ungrab here causes an EnterNotify, ignore it for
* sloppy focus
*/
display->ungrab_should_not_cause_focus_window = display->grab_xwindow;
}
/* If this was a move or resize clear out the edge cache */
if (meta_grab_op_is_resizing (display->grab_op) ||
meta_grab_op_is_moving (display->grab_op))

View File

@ -134,16 +134,6 @@ static gboolean process_keyboard_resize_grab (MetaDisplay *display,
XIDeviceEvent *event,
KeySym keysym);
static gboolean process_tab_grab (MetaDisplay *display,
MetaScreen *screen,
XIDeviceEvent *event,
KeySym keysym);
static gboolean process_workspace_switch_grab (MetaDisplay *display,
MetaScreen *screen,
XIDeviceEvent *event,
KeySym keysym);
static void grab_key_bindings (MetaDisplay *display);
static void ungrab_key_bindings (MetaDisplay *display);
@ -1672,48 +1662,6 @@ is_modifier (MetaDisplay *display,
* mod5 = 7
*/
static gboolean
is_specific_modifier (MetaDisplay *display,
unsigned int keycode,
unsigned int mask)
{
int i;
int end;
gboolean retval = FALSE;
int mod_index;
g_assert (display->modmap);
meta_topic (META_DEBUG_KEYBINDINGS,
"Checking whether code 0x%x is bound to modifier 0x%x\n",
keycode, mask);
mod_index = 0;
mask = mask >> 1;
while (mask != 0)
{
mod_index += 1;
mask = mask >> 1;
}
meta_topic (META_DEBUG_KEYBINDINGS,
"Modifier has index %d\n", mod_index);
end = (mod_index + 1) * display->modmap->max_keypermod;
i = mod_index * display->modmap->max_keypermod;
while (i < end)
{
if (keycode == display->modmap->modifiermap[i])
{
retval = TRUE;
break;
}
++i;
}
return retval;
}
static unsigned int
get_primary_modifier (MetaDisplay *display,
unsigned int entire_binding_mask)
@ -1741,24 +1689,6 @@ get_primary_modifier (MetaDisplay *display,
return 0;
}
static gboolean
keycode_is_primary_modifier (MetaDisplay *display,
unsigned int keycode,
unsigned int entire_binding_mask)
{
unsigned int primary_modifier;
meta_topic (META_DEBUG_KEYBINDINGS,
"Checking whether code 0x%x is the primary modifier of mask 0x%x\n",
keycode, entire_binding_mask);
primary_modifier = get_primary_modifier (display, entire_binding_mask);
if (primary_modifier != 0)
return is_specific_modifier (display, keycode, primary_modifier);
else
return FALSE;
}
static gboolean
primary_modifier_still_pressed (MetaDisplay *display,
unsigned int entire_binding_mask)
@ -1820,20 +1750,6 @@ invoke_handler (MetaDisplay *display,
NULL);
}
static void
invoke_handler_by_name (MetaDisplay *display,
MetaScreen *screen,
const char *handler_name,
MetaWindow *window,
XIDeviceEvent *event)
{
MetaKeyHandler *handler;
handler = HANDLER (handler_name);
if (handler)
invoke_handler (display, screen, handler, window, event, NULL);
}
static gboolean
process_event (MetaKeyBinding *bindings,
int n_bindings,
@ -2153,23 +2069,6 @@ meta_display_process_key_event (MetaDisplay *display,
window, event, keysym);
break;
case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
meta_topic (META_DEBUG_KEYBINDINGS,
"Processing event for keyboard tabbing/cycling\n");
keep_grab = process_tab_grab (display, screen, event, keysym);
break;
case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
meta_topic (META_DEBUG_KEYBINDINGS,
"Processing event for keyboard workspace switching\n");
keep_grab = process_workspace_switch_grab (display, screen, event, keysym);
break;
default:
break;
}
@ -2719,348 +2618,6 @@ process_keyboard_resize_grab (MetaDisplay *display,
return handled;
}
static gboolean
end_keyboard_grab (MetaDisplay *display,
unsigned int keycode)
{
#ifdef HAVE_XKB
if (display->xkb_base_event_type > 0)
{
unsigned int primary_modifier;
XkbStateRec state;
primary_modifier = get_primary_modifier (display, display->grab_mask);
XkbGetState (display->xdisplay, XkbUseCoreKbd, &state);
if (!(primary_modifier & state.mods))
return TRUE;
}
else
#endif
{
if (keycode_is_primary_modifier (display, keycode, display->grab_mask))
return TRUE;
}
return FALSE;
}
static gboolean
process_tab_grab (MetaDisplay *display,
MetaScreen *screen,
XIDeviceEvent *event,
KeySym keysym)
{
MetaKeyBinding *binding;
MetaKeyBindingAction action;
gboolean popup_not_showing;
gboolean backward;
gboolean key_used;
MetaWindow *prev_window;
if (screen != display->grab_screen)
return FALSE;
binding = display_get_keybinding (display,
keysym,
event->detail,
display->grab_mask);
if (binding)
action = meta_prefs_get_keybinding_action (binding->name);
else
action = META_KEYBINDING_ACTION_NONE;
/*
* If there is no tab_pop up object, i.e., there is some custom handler
* implementing Alt+Tab & Co., we call this custom handler; we do not
* mess about with the grab, as that is up to the handler to deal with.
*/
if (!screen->tab_popup)
{
if (event->evtype == XI_KeyRelease)
{
if (end_keyboard_grab (display, event->detail))
{
invoke_handler_by_name (display, screen, "tab-popup-select", NULL, event);
/* We return FALSE to end the grab; if the handler ended the grab itself
* that will be a noop. If the handler didn't end the grab, then it's a
* safety measure to prevent a stuck grab.
*/
return FALSE;
}
return TRUE;
}
switch (action)
{
case META_KEYBINDING_ACTION_CYCLE_PANELS:
case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_PANELS:
case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS:
case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD:
case META_KEYBINDING_ACTION_CYCLE_GROUP:
case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_GROUP:
case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
/* These are the tab-popup bindings. If a custom Alt-Tab implementation
* is in effect, we expect it to want to handle all of these as a group
*
* If there are some of them that the custom implementation didn't
* handle, we treat them as "unbound" for the duration - running the
* normal handlers could get us into trouble.
*/
if (binding->handler &&
binding->handler->func &&
binding->handler->func != binding->handler->default_func)
{
invoke_handler (display, screen, binding->handler, NULL, event, binding);
return TRUE;
}
break;
case META_KEYBINDING_ACTION_NONE:
{
/*
* If this is simply user pressing the Shift key, we do not want
* to cancel the grab.
*/
if (is_modifier (display, event->detail))
return TRUE;
}
default:
break;
}
/* Some unhandled key press */
invoke_handler_by_name (display, screen, "tab-popup-cancel", NULL, event);
return FALSE;
}
if (event->evtype == XI_KeyRelease &&
end_keyboard_grab (display, event->detail))
{
/* We're done, move to the new window. */
MetaWindow *target_window;
target_window = meta_screen_tab_popup_get_selected (screen);
meta_topic (META_DEBUG_KEYBINDINGS,
"Ending tab operation, primary modifier released\n");
if (target_window)
{
target_window->tab_unminimized = FALSE;
meta_topic (META_DEBUG_KEYBINDINGS,
"Activating target window\n");
meta_topic (META_DEBUG_FOCUS, "Activating %s due to tab popup "
"selection and turning mouse_mode off\n",
target_window->desc);
display->mouse_mode = FALSE;
meta_window_activate (target_window, event->time);
meta_topic (META_DEBUG_KEYBINDINGS,
"Ending grab early so we can focus the target window\n");
meta_display_end_grab_op (display, event->time);
return TRUE; /* we already ended the grab */
}
return FALSE; /* end grab */
}
/* don't care about other releases, but eat them, don't end grab */
if (event->evtype == XI_KeyRelease)
return TRUE;
/* don't end grab on modifier key presses */
if (is_modifier (display, event->detail))
return TRUE;
prev_window = meta_screen_tab_popup_get_selected (screen);
/* Cancel when alt-Escape is pressed during using alt-Tab, and vice
* versa.
*/
switch (action)
{
case META_KEYBINDING_ACTION_CYCLE_PANELS:
case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
/* CYCLE_* are traditionally Escape-based actions,
* and should cancel traditionally Tab-based ones.
*/
switch (display->grab_op)
{
case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
/* carry on */
break;
default:
return FALSE;
}
break;
case META_KEYBINDING_ACTION_SWITCH_PANELS:
case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS:
case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD:
/* SWITCH_* are traditionally Tab-based actions,
* and should cancel traditionally Escape-based ones.
*/
switch (display->grab_op)
{
case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
/* carry on */
break;
default:
/* Also, we must re-lower and re-minimize whatever window
* we'd previously raised and unminimized.
*/
meta_stack_set_positions (screen->stack,
screen->display->grab_old_window_stacking);
if (prev_window && prev_window->tab_unminimized)
{
meta_window_minimize (prev_window);
prev_window->tab_unminimized = FALSE;
}
return FALSE;
}
break;
case META_KEYBINDING_ACTION_CYCLE_GROUP:
case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_GROUP:
case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
switch (display->grab_op)
{
case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
/* carry on */
break;
default:
return FALSE;
}
break;
default:
break;
}
/* !! TO HERE !!
* alt-f6 during alt-{Tab,Escape} does not end the grab
* but does change the grab op (and redraws the window,
* of course).
* See _{SWITCH,CYCLE}_GROUP.@@@
*/
popup_not_showing = FALSE;
key_used = FALSE;
backward = FALSE;
switch (action)
{
case META_KEYBINDING_ACTION_CYCLE_PANELS:
case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
case META_KEYBINDING_ACTION_CYCLE_GROUP:
popup_not_showing = TRUE;
key_used = TRUE;
break;
case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
popup_not_showing = TRUE;
key_used = TRUE;
backward = TRUE;
break;
case META_KEYBINDING_ACTION_SWITCH_PANELS:
case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS:
case META_KEYBINDING_ACTION_SWITCH_GROUP:
key_used = TRUE;
break;
case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD:
case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
key_used = TRUE;
backward = TRUE;
break;
default:
break;
}
if (key_used)
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Key pressed, moving tab focus in popup\n");
if (event->mods.effective & ShiftMask)
backward = !backward;
if (backward)
meta_screen_tab_popup_backward (screen);
else
meta_screen_tab_popup_forward (screen);
if (popup_not_showing)
{
/* We can't actually change window focus, due to the grab.
* but raise the window.
*/
MetaWindow *target_window;
meta_stack_set_positions (screen->stack,
display->grab_old_window_stacking);
target_window = meta_screen_tab_popup_get_selected (screen);
if (prev_window && prev_window->tab_unminimized)
{
prev_window->tab_unminimized = FALSE;
meta_window_minimize (prev_window);
}
if (target_window)
{
meta_window_raise (target_window);
target_window->tab_unminimized = target_window->minimized;
meta_window_unminimize (target_window);
}
}
}
else
{
/* end grab */
meta_topic (META_DEBUG_KEYBINDINGS,
"Ending tabbing/cycling, uninteresting key pressed\n");
meta_topic (META_DEBUG_KEYBINDINGS,
"Syncing to old stack positions.\n");
meta_stack_set_positions (screen->stack,
screen->display->grab_old_window_stacking);
if (prev_window && prev_window->tab_unminimized)
{
meta_window_minimize (prev_window);
prev_window->tab_unminimized = FALSE;
}
}
return key_used;
}
static void
handle_switch_to_workspace (MetaDisplay *display,
MetaScreen *screen,
@ -3313,120 +2870,6 @@ handle_move_to_center (MetaDisplay *display,
window->rect.height);
}
static gboolean
process_workspace_switch_grab (MetaDisplay *display,
MetaScreen *screen,
XIDeviceEvent *event,
KeySym keysym)
{
MetaWorkspace *workspace;
if (screen != display->grab_screen || !screen->ws_popup)
return FALSE;
if (event->evtype == XI_KeyRelease &&
end_keyboard_grab (display, event->detail))
{
/* We're done, move to the new workspace. */
MetaWorkspace *target_workspace;
target_workspace = meta_screen_workspace_popup_get_selected (screen);
meta_topic (META_DEBUG_KEYBINDINGS,
"Ending workspace tab operation, primary modifier released\n");
if (target_workspace == screen->active_workspace)
{
meta_topic (META_DEBUG_KEYBINDINGS,
"Ending grab so we can focus on the target workspace\n");
meta_display_end_grab_op (display, event->time);
meta_topic (META_DEBUG_KEYBINDINGS,
"Focusing default window on target workspace\n");
meta_workspace_focus_default_window (target_workspace,
NULL,
event->time);
return TRUE; /* we already ended the grab */
}
/* Workspace switching should have already occurred on KeyPress */
meta_warning ("target_workspace != active_workspace. Some other event must have occurred.\n");
return FALSE; /* end grab */
}
/* don't care about other releases, but eat them, don't end grab */
if (event->evtype == XI_KeyRelease)
return TRUE;
/* don't end grab on modifier key presses */
if (is_modifier (display, event->detail))
return TRUE;
/* select the next workspace in the popup */
workspace = meta_screen_workspace_popup_get_selected (screen);
if (workspace)
{
MetaWorkspace *target_workspace;
MetaKeyBindingAction action;
action = meta_display_get_keybinding_action (display,
event->detail,
display->grab_mask);
switch (action)
{
case META_KEYBINDING_ACTION_WORKSPACE_UP:
target_workspace = meta_workspace_get_neighbor (workspace,
META_MOTION_UP);
break;
case META_KEYBINDING_ACTION_WORKSPACE_DOWN:
target_workspace = meta_workspace_get_neighbor (workspace,
META_MOTION_DOWN);
break;
case META_KEYBINDING_ACTION_WORKSPACE_LEFT:
target_workspace = meta_workspace_get_neighbor (workspace,
META_MOTION_LEFT);
break;
case META_KEYBINDING_ACTION_WORKSPACE_RIGHT:
target_workspace = meta_workspace_get_neighbor (workspace,
META_MOTION_RIGHT);
break;
default:
target_workspace = NULL;
break;
}
if (target_workspace)
{
meta_screen_workspace_popup_select (screen, target_workspace);
meta_topic (META_DEBUG_KEYBINDINGS,
"Tab key pressed, moving tab focus in popup\n");
meta_topic (META_DEBUG_KEYBINDINGS,
"Activating target workspace\n");
meta_workspace_activate (target_workspace, event->time);
return TRUE; /* we already ended the grab */
}
}
/* end grab */
meta_topic (META_DEBUG_KEYBINDINGS,
"Ending workspace tabbing & focusing default window; uninteresting key pressed\n");
workspace = meta_screen_workspace_popup_get_selected (screen);
meta_workspace_focus_default_window (workspace, NULL, event->time);
return FALSE;
}
static void
handle_show_desktop (MetaDisplay *display,
MetaScreen *screen,
@ -3523,60 +2966,19 @@ handle_activate_window_menu (MetaDisplay *display,
}
}
static MetaGrabOp
tab_op_from_tab_type (MetaTabList type)
{
switch (type)
{
case META_TAB_LIST_NORMAL:
return META_GRAB_OP_KEYBOARD_TABBING_NORMAL;
case META_TAB_LIST_DOCKS:
return META_GRAB_OP_KEYBOARD_TABBING_DOCK;
case META_TAB_LIST_GROUP:
return META_GRAB_OP_KEYBOARD_TABBING_GROUP;
case META_TAB_LIST_NORMAL_ALL:
break;
}
g_assert_not_reached ();
return 0;
}
static MetaGrabOp
cycle_op_from_tab_type (MetaTabList type)
{
switch (type)
{
case META_TAB_LIST_NORMAL:
return META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL;
case META_TAB_LIST_DOCKS:
return META_GRAB_OP_KEYBOARD_ESCAPING_DOCK;
case META_TAB_LIST_GROUP:
return META_GRAB_OP_KEYBOARD_ESCAPING_GROUP;
case META_TAB_LIST_NORMAL_ALL:
break;
}
g_assert_not_reached ();
return 0;
}
static void
do_choose_window (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *event_window,
XIDeviceEvent *event,
MetaKeyBinding *binding,
gboolean backward,
gboolean show_popup)
gboolean backward)
{
MetaTabList type = binding->handler->data;
MetaWindow *initial_selection;
meta_topic (META_DEBUG_KEYBINDINGS,
"Tab list = %u show_popup = %d\n", type, show_popup);
"Tab list = %u\n", type);
/* reverse direction if shift is down */
if (event->mods.effective & ShiftMask)
@ -3589,82 +2991,7 @@ do_choose_window (MetaDisplay *display,
NULL,
backward);
/* Note that focus_window may not be in the tab chain, but it's OK */
if (initial_selection == NULL)
initial_selection = meta_display_get_tab_current (display,
type, screen,
screen->active_workspace);
meta_topic (META_DEBUG_KEYBINDINGS,
"Initially selecting window %s\n",
initial_selection ? initial_selection->desc : "(none)");
if (initial_selection == NULL)
return;
if (binding->mask == 0)
{
/* If no modifiers, we can't do the "hold down modifier to keep
* moving" thing, so we just instaswitch by one window.
*/
meta_topic (META_DEBUG_FOCUS,
"Activating %s and turning off mouse_mode due to "
"switch/cycle windows with no modifiers\n",
initial_selection->desc);
display->mouse_mode = FALSE;
meta_window_activate (initial_selection, event->time);
return;
}
if (meta_prefs_get_no_tab_popup ())
{
/* FIXME? Shouldn't this be merged with the previous case? */
return;
}
if (!meta_display_begin_grab_op (display,
screen,
NULL,
show_popup ?
tab_op_from_tab_type (type) :
cycle_op_from_tab_type (type),
FALSE,
FALSE,
0,
binding->mask,
event->time,
0, 0))
return;
if (!primary_modifier_still_pressed (display, binding->mask))
{
/* This handles a race where modifier might be released before
* we establish the grab. must end grab prior to trying to focus
* a window.
*/
meta_topic (META_DEBUG_FOCUS,
"Ending grab, activating %s, and turning off "
"mouse_mode due to switch/cycle windows where "
"modifier was released prior to grab\n",
initial_selection->desc);
meta_display_end_grab_op (display, event->time);
display->mouse_mode = FALSE;
meta_window_activate (initial_selection, event->time);
return;
}
meta_screen_tab_popup_create (screen, type,
show_popup ? META_TAB_SHOW_ICON :
META_TAB_SHOW_INSTANTLY,
initial_selection);
if (!show_popup)
{
meta_window_raise (initial_selection);
initial_selection->tab_unminimized =
initial_selection->minimized;
meta_window_unminimize (initial_selection);
}
}
static void
@ -3677,8 +3004,7 @@ handle_switch (MetaDisplay *display,
{
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
do_choose_window (display, screen, event_window, event, binding,
backwards, TRUE);
do_choose_window (display, screen, event_window, event, binding, backwards);
}
static void
@ -3691,30 +3017,7 @@ handle_cycle (MetaDisplay *display,
{
gint backwards = (binding->handler->flags & META_KEY_BINDING_IS_REVERSED) != 0;
do_choose_window (display, screen, event_window, event, binding,
backwards, FALSE);
}
static void
handle_tab_popup_select (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *window,
XIDeviceEvent *event,
MetaKeyBinding *binding,
gpointer dummy)
{
/* Stub for custom handlers; no default implementation */
}
static void
handle_tab_popup_cancel (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *window,
XIDeviceEvent *event,
MetaKeyBinding *binding,
gpointer dummy)
{
/* Stub for custom handlers; no default implementation */
do_choose_window (display, screen, event_window, event, binding, backwards);
}
static void
@ -4112,9 +3415,6 @@ handle_workspace_switch (MetaDisplay *display,
}
meta_workspace_activate (next, event->time);
if (grabbed_before_release && !meta_prefs_get_no_tab_popup ())
meta_screen_workspace_popup_create (screen, next);
}
static void
@ -4380,26 +3680,6 @@ init_builtin_key_bindings (MetaDisplay *display)
META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
handle_cycle, META_TAB_LIST_DOCKS);
/* These two are special pseudo-bindings that are provided for allowing
* custom handlers, but will never be bound to a key. While a tab
* grab is in effect, they are invoked for releasing the primary modifier
* or pressing some unbound key, respectively.
*/
add_builtin_keybinding (display,
"tab-popup-select",
mutter_keybindings,
META_KEY_BINDING_NONE,
META_KEYBINDING_ACTION_TAB_POPUP_SELECT,
handle_tab_popup_select, 0);
add_builtin_keybinding (display,
"tab-popup-cancel",
mutter_keybindings,
META_KEY_BINDING_NONE,
META_KEYBINDING_ACTION_TAB_POPUP_CANCEL,
handle_tab_popup_cancel, 0);
/***********************************/
add_builtin_keybinding (display,

View File

@ -57,7 +57,6 @@
#define KEY_OVERLAY_KEY "overlay-key"
#define KEY_WORKSPACES_ONLY_ON_PRIMARY "workspaces-only-on-primary"
#define KEY_NO_TAB_POPUP "no-tab-popup"
/* These are the different schemas we are keeping
* a GSettings instance for */
@ -112,8 +111,6 @@ static char **workspace_names = NULL;
static gboolean workspaces_only_on_primary = FALSE;
static gboolean no_tab_popup = FALSE;
static char *iso_next_group_option = NULL;
static void handle_preference_update_enum (GSettings *settings,
@ -365,13 +362,6 @@ static MetaBoolPreference preferences_bool[] =
},
&workspaces_only_on_primary,
},
{
{ KEY_NO_TAB_POPUP,
SCHEMA_MUTTER,
META_PREF_NO_TAB_POPUP,
},
&no_tab_popup,
},
{
{ "auto-maximize",
SCHEMA_MUTTER,
@ -1813,9 +1803,6 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_WORKSPACES_ONLY_ON_PRIMARY:
return "WORKSPACES_ONLY_ON_PRIMARY";
case META_PREF_NO_TAB_POPUP:
return "NO_TAB_POPUP";
case META_PREF_DRAGGABLE_BORDER_WIDTH:
return "DRAGGABLE_BORDER_WIDTH";
@ -2320,25 +2307,6 @@ meta_prefs_get_workspaces_only_on_primary (void)
return workspaces_only_on_primary;
}
gboolean
meta_prefs_get_no_tab_popup (void)
{
return no_tab_popup;
}
void
meta_prefs_set_no_tab_popup (gboolean whether)
{
MetaBasePreference *pref;
if (find_pref (preferences_bool, sizeof(MetaBoolPreference),
KEY_NO_TAB_POPUP, &pref))
{
g_settings_set_boolean (SETTINGS (pref->schema), KEY_NO_TAB_POPUP, whether);
}
}
int
meta_prefs_get_draggable_border_width (void)
{

View File

@ -64,7 +64,6 @@ struct _MetaScreen
Visual *default_xvisual;
MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */
MetaUI *ui;
MetaTabPopup *tab_popup, *ws_popup;
guint tile_preview_timeout_id;
@ -150,26 +149,6 @@ void meta_screen_foreach_window (MetaScreen *scree
void meta_screen_update_cursor (MetaScreen *screen);
void meta_screen_tab_popup_create (MetaScreen *screen,
MetaTabList list_type,
MetaTabShowType show_type,
MetaWindow *initial_window);
void meta_screen_tab_popup_forward (MetaScreen *screen);
void meta_screen_tab_popup_backward (MetaScreen *screen);
MetaWindow* meta_screen_tab_popup_get_selected (MetaScreen *screen);
void meta_screen_tab_popup_destroy (MetaScreen *screen);
void meta_screen_workspace_popup_create (MetaScreen *screen,
MetaWorkspace *initial_selection);
void meta_screen_workspace_popup_select (MetaScreen *screen,
MetaWorkspace *workspace);
MetaWorkspace*meta_screen_workspace_popup_get_selected (MetaScreen *screen);
void meta_screen_workspace_popup_destroy (MetaScreen *screen);
void meta_screen_update_tile_preview (MetaScreen *screen,
gboolean delay);
void meta_screen_hide_tile_preview (MetaScreen *screen);
MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen,
MetaWindow *not_this_one);

View File

@ -760,9 +760,6 @@ meta_screen_new (MetaDisplay *display,
screen->ui = meta_ui_new (screen->display->xdisplay,
screen->xscreen);
screen->tab_popup = NULL;
screen->ws_popup = NULL;
screen->tile_preview_timeout_id = 0;
screen->stack = meta_stack_new (screen);
@ -1425,253 +1422,6 @@ meta_screen_update_cursor (MetaScreen *screen)
screen->current_cursor);
}
void
meta_screen_tab_popup_create (MetaScreen *screen,
MetaTabList list_type,
MetaTabShowType show_type,
MetaWindow *initial_selection)
{
MetaTabEntry *entries;
GList *tab_list;
GList *tmp;
int len;
int i;
if (screen->tab_popup)
return;
tab_list = meta_display_get_tab_list (screen->display,
list_type,
screen,
screen->active_workspace);
len = g_list_length (tab_list);
entries = g_new (MetaTabEntry, len + 1);
entries[len].key = NULL;
entries[len].title = NULL;
entries[len].icon = NULL;
i = 0;
tmp = tab_list;
while (i < len)
{
MetaWindow *window;
MetaRectangle r;
window = tmp->data;
entries[i].key = (MetaTabEntryKey) window;
entries[i].title = window->title;
entries[i].icon = g_object_ref (window->icon);
entries[i].blank = FALSE;
entries[i].hidden = !meta_window_showing_on_its_workspace (window);
entries[i].demands_attention = window->wm_state_demands_attention;
if (show_type == META_TAB_SHOW_INSTANTLY ||
!entries[i].hidden ||
!meta_window_get_icon_geometry (window, &r))
meta_window_get_frame_rect (window, &r);
entries[i].rect = r;
/* Find inside of highlight rectangle to be used when window is
* outlined for tabbing. This should be the size of the
* east/west frame, and the size of the south frame, on those
* sides. On the top it should be the size of the south frame
* edge.
*/
#define OUTLINE_WIDTH 5
/* Top side */
if (!entries[i].hidden &&
window->frame && window->frame->bottom_height > 0 &&
window->frame->child_y >= window->frame->bottom_height)
entries[i].inner_rect.y = window->frame->bottom_height;
else
entries[i].inner_rect.y = OUTLINE_WIDTH;
/* Bottom side */
if (!entries[i].hidden &&
window->frame && window->frame->bottom_height != 0)
entries[i].inner_rect.height = r.height
- entries[i].inner_rect.y - window->frame->bottom_height;
else
entries[i].inner_rect.height = r.height
- entries[i].inner_rect.y - OUTLINE_WIDTH;
/* Left side */
if (!entries[i].hidden && window->frame && window->frame->child_x != 0)
entries[i].inner_rect.x = window->frame->child_x;
else
entries[i].inner_rect.x = OUTLINE_WIDTH;
/* Right side */
if (!entries[i].hidden &&
window->frame && window->frame->right_width != 0)
entries[i].inner_rect.width = r.width
- entries[i].inner_rect.x - window->frame->right_width;
else
entries[i].inner_rect.width = r.width
- entries[i].inner_rect.x - OUTLINE_WIDTH;
++i;
tmp = tmp->next;
}
if (!meta_prefs_get_no_tab_popup ())
screen->tab_popup = meta_ui_tab_popup_new (entries,
screen->number,
len,
5, /* FIXME */
TRUE);
for (i = 0; i < len; i++)
g_object_unref (entries[i].icon);
g_free (entries);
g_list_free (tab_list);
meta_ui_tab_popup_select (screen->tab_popup,
(MetaTabEntryKey) initial_selection);
if (show_type != META_TAB_SHOW_INSTANTLY)
meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE);
}
void
meta_screen_tab_popup_forward (MetaScreen *screen)
{
g_return_if_fail (screen->tab_popup != NULL);
meta_ui_tab_popup_forward (screen->tab_popup);
}
void
meta_screen_tab_popup_backward (MetaScreen *screen)
{
g_return_if_fail (screen->tab_popup != NULL);
meta_ui_tab_popup_backward (screen->tab_popup);
}
MetaWindow *
meta_screen_tab_popup_get_selected (MetaScreen *screen)
{
g_return_val_if_fail (screen->tab_popup != NULL, NULL);
return (MetaWindow *) meta_ui_tab_popup_get_selected (screen->tab_popup);
}
void
meta_screen_tab_popup_destroy (MetaScreen *screen)
{
if (screen->tab_popup)
{
meta_ui_tab_popup_free (screen->tab_popup);
screen->tab_popup = NULL;
}
}
void
meta_screen_workspace_popup_create (MetaScreen *screen,
MetaWorkspace *initial_selection)
{
MetaTabEntry *entries;
int len;
int i;
MetaWorkspaceLayout layout;
int n_workspaces;
int current_workspace;
if (screen->ws_popup || meta_prefs_get_no_tab_popup ())
return;
current_workspace = meta_workspace_index (screen->active_workspace);
n_workspaces = meta_screen_get_n_workspaces (screen);
meta_screen_calc_workspace_layout (screen, n_workspaces,
current_workspace, &layout);
len = layout.grid_area;
entries = g_new (MetaTabEntry, len + 1);
entries[len].key = NULL;
entries[len].title = NULL;
entries[len].icon = NULL;
i = 0;
while (i < len)
{
if (layout.grid[i] >= 0)
{
MetaWorkspace *workspace;
workspace = meta_screen_get_workspace_by_index (screen,
layout.grid[i]);
entries[i].key = (MetaTabEntryKey) workspace;
entries[i].title = meta_workspace_get_name (workspace);
entries[i].icon = NULL;
entries[i].blank = FALSE;
g_assert (entries[i].title != NULL);
}
else
{
entries[i].key = NULL;
entries[i].title = NULL;
entries[i].icon = NULL;
entries[i].blank = TRUE;
}
entries[i].hidden = FALSE;
entries[i].demands_attention = FALSE;
++i;
}
screen->ws_popup = meta_ui_tab_popup_new (entries,
screen->number,
len,
layout.cols,
FALSE);
g_free (entries);
meta_screen_free_workspace_layout (&layout);
meta_ui_tab_popup_select (screen->ws_popup,
(MetaTabEntryKey) initial_selection);
meta_ui_tab_popup_set_showing (screen->ws_popup, TRUE);
}
void
meta_screen_workspace_popup_select (MetaScreen *screen,
MetaWorkspace *workspace)
{
g_return_if_fail (screen->ws_popup != NULL);
meta_ui_tab_popup_select (screen->ws_popup,
(MetaTabEntryKey) workspace);
}
MetaWorkspace *
meta_screen_workspace_popup_get_selected (MetaScreen *screen)
{
g_return_val_if_fail (screen->ws_popup != NULL, NULL);
return (MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->ws_popup);
}
void
meta_screen_workspace_popup_destroy (MetaScreen *screen)
{
if (screen->ws_popup)
{
meta_ui_tab_popup_free (screen->ws_popup);
screen->ws_popup = NULL;
}
}
static gboolean
meta_screen_update_tile_preview_timeout (gpointer data)
{

View File

@ -62,7 +62,6 @@
* @META_PREF_EDGE_TILING: edge tiling
* @META_PREF_FORCE_FULLSCREEN: force fullscreen
* @META_PREF_WORKSPACES_ONLY_ON_PRIMARY: workspaces only on primary
* @META_PREF_NO_TAB_POPUP: no tab popup
* @META_PREF_DRAGGABLE_BORDER_WIDTH: draggable border width
* @META_PREF_AUTO_MAXIMIZE: auto-maximize
*/
@ -100,7 +99,6 @@ typedef enum
META_PREF_EDGE_TILING,
META_PREF_FORCE_FULLSCREEN,
META_PREF_WORKSPACES_ONLY_ON_PRIMARY,
META_PREF_NO_TAB_POPUP,
META_PREF_DRAGGABLE_BORDER_WIDTH,
META_PREF_AUTO_MAXIMIZE
} MetaPreference;
@ -163,9 +161,6 @@ void meta_prefs_set_force_fullscreen (gboolean whether);
gboolean meta_prefs_get_workspaces_only_on_primary (void);
gboolean meta_prefs_get_no_tab_popup (void);
void meta_prefs_set_no_tab_popup (gboolean whether);
int meta_prefs_get_draggable_border_width (void);
gboolean meta_prefs_get_ignore_request_hide_titlebar (void);
@ -204,8 +199,6 @@ void meta_prefs_set_ignore_request_hide_titlebar (gboolean whether);
* @META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_CYCLE_PANELS: FILLME
* @META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD: FILLME
* @META_KEYBINDING_ACTION_TAB_POPUP_SELECT: FILLME
* @META_KEYBINDING_ACTION_TAB_POPUP_CANCEL: FILLME
* @META_KEYBINDING_ACTION_SHOW_DESKTOP: FILLME
* @META_KEYBINDING_ACTION_PANEL_MAIN_MENU: FILLME
* @META_KEYBINDING_ACTION_PANEL_RUN_DIALOG: FILLME
@ -301,8 +294,6 @@ typedef enum _MetaKeyBindingAction
META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD,
META_KEYBINDING_ACTION_CYCLE_PANELS,
META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
META_KEYBINDING_ACTION_TAB_POPUP_SELECT,
META_KEYBINDING_ACTION_TAB_POPUP_CANCEL,
META_KEYBINDING_ACTION_SHOW_DESKTOP,
META_KEYBINDING_ACTION_PANEL_MAIN_MENU,
META_KEYBINDING_ACTION_PANEL_RUN_DIALOG,

View File

@ -1,224 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Draw a workspace */
/* This file should not be modified to depend on other files in
* libwnck or mutter, since it's used in both of them
*/
/*
* Copyright (C) 2002 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "draw-workspace.h"
#include "theme-private.h"
static void
get_window_rect (const WnckWindowDisplayInfo *win,
int screen_width,
int screen_height,
const GdkRectangle *workspace_rect,
GdkRectangle *rect)
{
double width_ratio, height_ratio;
int x, y, width, height;
width_ratio = (double) workspace_rect->width / (double) screen_width;
height_ratio = (double) workspace_rect->height / (double) screen_height;
x = win->x;
y = win->y;
width = win->width;
height = win->height;
x *= width_ratio;
y *= height_ratio;
width *= width_ratio;
height *= height_ratio;
x += workspace_rect->x;
y += workspace_rect->y;
if (width < 3)
width = 3;
if (height < 3)
height = 3;
rect->x = x;
rect->y = y;
rect->width = width;
rect->height = height;
}
static void
draw_window (GtkWidget *widget,
cairo_t *cr,
const WnckWindowDisplayInfo *win,
const GdkRectangle *winrect,
GtkStateFlags state)
{
GdkPixbuf *icon;
int icon_x, icon_y, icon_w, icon_h;
gboolean is_active;
GdkRGBA color;
GtkStyleContext *style;
is_active = win->is_active;
cairo_save (cr);
cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height);
cairo_clip (cr);
style = gtk_widget_get_style_context (widget);
if (is_active)
meta_gtk_style_get_light_color (style, state, &color);
else
gtk_style_context_get_background_color (style, state, &color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_rectangle (cr,
winrect->x + 1, winrect->y + 1,
MAX (0, winrect->width - 2), MAX (0, winrect->height - 2));
cairo_fill (cr);
icon = win->icon;
icon_w = icon_h = 0;
if (icon)
{
icon_w = gdk_pixbuf_get_width (icon);
icon_h = gdk_pixbuf_get_height (icon);
/* If the icon is too big, fall back to mini icon.
* We don't arbitrarily scale the icon, because it's
* just too slow on my Athlon 850.
*/
if (icon_w > (winrect->width - 2) ||
icon_h > (winrect->height - 2))
{
icon = win->mini_icon;
if (icon)
{
icon_w = gdk_pixbuf_get_width (icon);
icon_h = gdk_pixbuf_get_height (icon);
/* Give up. */
if (icon_w > (winrect->width - 2) ||
icon_h > (winrect->height - 2))
icon = NULL;
}
}
}
if (icon)
{
icon_x = winrect->x + (winrect->width - icon_w) / 2;
icon_y = winrect->y + (winrect->height - icon_h) / 2;
cairo_save (cr);
gdk_cairo_set_source_pixbuf (cr, icon, icon_x, icon_y);
cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h);
cairo_clip (cr);
cairo_paint (cr);
cairo_restore (cr);
}
gtk_style_context_get_color (style, state, &color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_set_line_width (cr, 1.0);
cairo_rectangle (cr,
winrect->x + 0.5, winrect->y + 0.5,
MAX (0, winrect->width - 1), MAX (0, winrect->height - 1));
cairo_stroke (cr);
cairo_restore (cr);
}
void
wnck_draw_workspace (GtkWidget *widget,
cairo_t *cr,
int x,
int y,
int width,
int height,
int screen_width,
int screen_height,
GdkPixbuf *workspace_background,
gboolean is_active,
const WnckWindowDisplayInfo *windows,
int n_windows)
{
int i;
GdkRectangle workspace_rect;
GtkStateFlags state;
GtkStyleContext *style;
workspace_rect.x = x;
workspace_rect.y = y;
workspace_rect.width = width;
workspace_rect.height = height;
if (is_active)
state = GTK_STATE_FLAG_SELECTED;
else if (workspace_background)
state = GTK_STATE_FLAG_PRELIGHT;
else
state = GTK_STATE_FLAG_NORMAL;
style = gtk_widget_get_style_context (widget);
cairo_save (cr);
if (workspace_background)
{
gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y);
cairo_paint (cr);
}
else
{
GdkRGBA color;
meta_gtk_style_get_dark_color (style,state, &color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_rectangle (cr, x, y, width, height);
cairo_fill (cr);
}
i = 0;
while (i < n_windows)
{
const WnckWindowDisplayInfo *win = &windows[i];
GdkRectangle winrect;
get_window_rect (win, screen_width,
screen_height, &workspace_rect, &winrect);
draw_window (widget,
cr,
win,
&winrect,
state);
++i;
}
cairo_restore (cr);
}

View File

@ -1,59 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Draw a workspace */
/* This file should not be modified to depend on other files in
* libwnck or metacity, since it's used in both of them
*/
/*
* Copyright (C) 2002 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WNCK_DRAW_WORKSPACE_H
#define WNCK_DRAW_WORKSPACE_H
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
typedef struct
{
GdkPixbuf *icon;
GdkPixbuf *mini_icon;
int x;
int y;
int width;
int height;
guint is_active : 1;
} WnckWindowDisplayInfo;
void wnck_draw_workspace (GtkWidget *widget,
cairo_t *cr,
int x,
int y,
int width,
int height,
int screen_width,
int screen_height,
GdkPixbuf *workspace_background,
gboolean is_active,
const WnckWindowDisplayInfo *windows,
int n_windows);
#endif

View File

@ -1,963 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Mutter popup window thing showing windows you can tab to */
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2002 Red Hat, Inc.
* Copyright (C) 2005 Elijah Newren
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <meta/util.h>
#include "core.h"
#include "tabpopup.h"
/* FIXME these two includes are 100% broken ...
*/
#include "workspace-private.h"
#include "frame.h"
#include "draw-workspace.h"
#include <gtk/gtk.h>
#include <math.h>
#define OUTSIDE_SELECT_RECT 2
#define INSIDE_SELECT_RECT 2
typedef struct _TabEntry TabEntry;
struct _TabEntry
{
MetaTabEntryKey key;
char *title;
GdkPixbuf *icon, *dimmed_icon;
GtkWidget *widget;
GdkRectangle rect;
GdkRectangle inner_rect;
guint blank : 1;
};
struct _MetaTabPopup
{
GtkWidget *window;
GtkWidget *label;
GList *current;
GList *entries;
TabEntry *current_selected_entry;
GtkWidget *outline_window;
gboolean outline;
};
static GtkWidget* selectable_image_new (GdkPixbuf *pixbuf);
static void select_image (GtkWidget *widget);
static void unselect_image (GtkWidget *widget);
static GtkWidget* selectable_workspace_new (MetaWorkspace *workspace);
static void select_workspace (GtkWidget *widget);
static void unselect_workspace (GtkWidget *widget);
static gboolean
outline_window_draw (GtkWidget *widget,
cairo_t *cr,
gpointer data)
{
MetaTabPopup *popup;
TabEntry *te;
popup = data;
if (!popup->outline || popup->current_selected_entry == NULL)
return FALSE;
te = popup->current_selected_entry;
cairo_set_line_width (cr, 1.0);
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
cairo_rectangle (cr,
0.5, 0.5,
te->rect.width - 1,
te->rect.height - 1);
cairo_stroke (cr);
cairo_rectangle (cr,
te->inner_rect.x - 0.5, te->inner_rect.y - 0.5,
te->inner_rect.width + 1,
te->inner_rect.height + 1);
cairo_stroke (cr);
return FALSE;
}
static GdkPixbuf*
dimm_icon (GdkPixbuf *pixbuf)
{
int x, y, pixel_stride, row_stride;
guchar *row, *pixels;
int w, h;
GdkPixbuf *dimmed_pixbuf;
if (gdk_pixbuf_get_has_alpha (pixbuf))
{
dimmed_pixbuf = gdk_pixbuf_copy (pixbuf);
}
else
{
dimmed_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
}
w = gdk_pixbuf_get_width (dimmed_pixbuf);
h = gdk_pixbuf_get_height (dimmed_pixbuf);
pixel_stride = 4;
row = gdk_pixbuf_get_pixels (dimmed_pixbuf);
row_stride = gdk_pixbuf_get_rowstride (dimmed_pixbuf);
for (y = 0; y < h; y++)
{
pixels = row;
for (x = 0; x < w; x++)
{
pixels[3] /= 2;
pixels += pixel_stride;
}
row += row_stride;
}
return dimmed_pixbuf;
}
static TabEntry*
tab_entry_new (const MetaTabEntry *entry,
gint screen_width,
gboolean outline)
{
TabEntry *te;
te = g_new (TabEntry, 1);
te->key = entry->key;
te->title = NULL;
if (entry->title)
{
gchar *str;
gchar *tmp;
gchar *formatter = "%s";
str = meta_g_utf8_strndup (entry->title, 4096);
if (entry->hidden)
{
formatter = "[%s]";
}
tmp = g_markup_printf_escaped (formatter, str);
g_free (str);
str = tmp;
if (entry->demands_attention)
{
/* Escape the whole line of text then markup the text and
* copy it back into the original buffer.
*/
tmp = g_strdup_printf ("<b>%s</b>", str);
g_free (str);
str = tmp;
}
te->title=g_strdup(str);
g_free (str);
}
te->widget = NULL;
te->icon = entry->icon;
te->blank = entry->blank;
te->dimmed_icon = NULL;
if (te->icon)
{
g_object_ref (G_OBJECT (te->icon));
if (entry->hidden)
te->dimmed_icon = dimm_icon (entry->icon);
}
if (outline)
{
te->rect.x = entry->rect.x;
te->rect.y = entry->rect.y;
te->rect.width = entry->rect.width;
te->rect.height = entry->rect.height;
te->inner_rect.x = entry->inner_rect.x;
te->inner_rect.y = entry->inner_rect.y;
te->inner_rect.width = entry->inner_rect.width;
te->inner_rect.height = entry->inner_rect.height;
}
return te;
}
MetaTabPopup*
meta_ui_tab_popup_new (const MetaTabEntry *entries,
int screen_number,
int entry_count,
int width,
gboolean outline)
{
MetaTabPopup *popup;
int i, left, top;
int height;
GtkWidget *grid;
GtkWidget *vbox;
GtkWidget *align;
GList *tmp;
GtkWidget *frame;
int max_label_width; /* the actual max width of the labels we create */
AtkObject *obj;
GdkScreen *screen;
int screen_width;
popup = g_new (MetaTabPopup, 1);
popup->outline_window = gtk_window_new (GTK_WINDOW_POPUP);
screen = gdk_display_get_screen (gdk_display_get_default (),
screen_number);
gtk_window_set_screen (GTK_WINDOW (popup->outline_window),
screen);
gtk_widget_set_app_paintable (popup->outline_window, TRUE);
gtk_widget_realize (popup->outline_window);
g_signal_connect (G_OBJECT (popup->outline_window), "draw",
G_CALLBACK (outline_window_draw), popup);
popup->window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_window_set_screen (GTK_WINDOW (popup->window),
screen);
gtk_window_set_position (GTK_WINDOW (popup->window),
GTK_WIN_POS_CENTER_ALWAYS);
/* enable resizing, to get never-shrink behavior */
gtk_window_set_resizable (GTK_WINDOW (popup->window),
TRUE);
popup->current = NULL;
popup->entries = NULL;
popup->current_selected_entry = NULL;
popup->outline = outline;
screen_width = gdk_screen_get_width (screen);
for (i = 0; i < entry_count; ++i)
{
TabEntry* new_entry = tab_entry_new (&entries[i], screen_width, outline);
popup->entries = g_list_prepend (popup->entries, new_entry);
}
popup->entries = g_list_reverse (popup->entries);
g_assert (width > 0);
height = i / width;
if (i % width)
height += 1;
grid = gtk_grid_new ();
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
gtk_container_set_border_width (GTK_CONTAINER (grid), 1);
gtk_container_add (GTK_CONTAINER (popup->window),
frame);
gtk_container_add (GTK_CONTAINER (frame),
vbox);
align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (align),
grid);
popup->label = gtk_label_new ("");
/* Set the accessible role of the label to a status bar so it
* will emit name changed events that can be used by screen
* readers.
*/
obj = gtk_widget_get_accessible (popup->label);
atk_object_set_role (obj, ATK_ROLE_STATUSBAR);
gtk_misc_set_padding (GTK_MISC (popup->label), 3, 3);
gtk_box_pack_end (GTK_BOX (vbox), popup->label, FALSE, FALSE, 0);
max_label_width = 0;
top = 0;
tmp = popup->entries;
while (tmp && top < height)
{
left = 0;
while (tmp && left < width)
{
GtkWidget *image;
GtkRequisition req;
TabEntry *te;
te = tmp->data;
if (te->blank)
{
/* just stick a widget here to avoid special cases */
image = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
}
else if (outline)
{
if (te->dimmed_icon)
{
image = selectable_image_new (te->dimmed_icon);
}
else
{
image = selectable_image_new (te->icon);
}
gtk_misc_set_padding (GTK_MISC (image),
INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1,
INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1);
gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.5);
}
else
{
image = selectable_workspace_new ((MetaWorkspace *) te->key);
}
te->widget = image;
gtk_grid_attach (GTK_GRID (grid),
te->widget,
left, top, 1, 1);
/* Efficiency rules! */
gtk_label_set_markup (GTK_LABEL (popup->label),
te->title);
gtk_widget_get_preferred_size (popup->label, &req, NULL);
max_label_width = MAX (max_label_width, req.width);
tmp = tmp->next;
++left;
}
++top;
}
/* remove all the temporary text */
gtk_label_set_text (GTK_LABEL (popup->label), "");
/* Make it so that we ellipsize if the text is too long */
gtk_label_set_ellipsize (GTK_LABEL (popup->label), PANGO_ELLIPSIZE_END);
/* Limit the window size to no bigger than screen_width/4 */
if (max_label_width>(screen_width/4))
{
max_label_width = screen_width/4;
}
max_label_width += 20; /* add random padding */
gtk_window_set_default_size (GTK_WINDOW (popup->window),
max_label_width,
-1);
return popup;
}
static void
free_tab_entry (gpointer data, gpointer user_data)
{
TabEntry *te;
te = data;
g_free (te->title);
if (te->icon)
g_object_unref (G_OBJECT (te->icon));
if (te->dimmed_icon)
g_object_unref (G_OBJECT (te->dimmed_icon));
g_free (te);
}
void
meta_ui_tab_popup_free (MetaTabPopup *popup)
{
meta_verbose ("Destroying tab popup window\n");
if (!popup)
{
meta_warning ("NULL passed to meta_ui_tab_popup_free\n");
return;
}
gtk_widget_destroy (popup->outline_window);
gtk_widget_destroy (popup->window);
g_list_foreach (popup->entries, free_tab_entry, NULL);
g_list_free (popup->entries);
g_free (popup);
}
void
meta_ui_tab_popup_set_showing (MetaTabPopup *popup,
gboolean showing)
{
if (showing)
{
gtk_widget_show_all (popup->window);
}
else
{
if (gtk_widget_get_visible (popup->window))
{
meta_verbose ("Hiding tab popup window\n");
gtk_widget_hide (popup->window);
meta_core_increment_event_serial (
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
}
}
}
static void
display_entry (MetaTabPopup *popup,
TabEntry *te)
{
GdkRectangle rect;
GdkWindow *window;
if (popup->current_selected_entry)
{
if (popup->outline)
unselect_image (popup->current_selected_entry->widget);
else
unselect_workspace (popup->current_selected_entry->widget);
}
gtk_label_set_markup (GTK_LABEL (popup->label), te->title);
if (popup->outline)
select_image (te->widget);
else
select_workspace (te->widget);
if (popup->outline)
{
cairo_region_t *region;
cairo_region_t *inner_region;
GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 };
window = gtk_widget_get_window (popup->outline_window);
/* Do stuff behind gtk's back */
gdk_window_hide (window);
meta_core_increment_event_serial (
GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
rect = te->rect;
rect.x = 0;
rect.y = 0;
gdk_window_move_resize (window,
te->rect.x, te->rect.y,
te->rect.width, te->rect.height);
gdk_window_set_background_rgba (window, &black);
region = cairo_region_create_rectangle (&rect);
inner_region = cairo_region_create_rectangle (&te->inner_rect);
cairo_region_subtract (region, inner_region);
cairo_region_destroy (inner_region);
gdk_window_shape_combine_region (window,
region,
0, 0);
cairo_region_destroy (region);
/* This should piss off gtk a bit, but we don't want to raise
* above the tab popup. So, instead of calling gtk_widget_show,
* we manually set the window as mapped and then manually map it
* with gdk functions.
*/
gtk_widget_set_mapped (popup->outline_window, TRUE);
gdk_window_show_unraised (window);
}
/* Must be before we handle an expose for the outline window */
popup->current_selected_entry = te;
}
void
meta_ui_tab_popup_forward (MetaTabPopup *popup)
{
if (popup->current != NULL)
popup->current = popup->current->next;
if (popup->current == NULL)
popup->current = popup->entries;
if (popup->current != NULL)
{
TabEntry *te;
te = popup->current->data;
display_entry (popup, te);
}
}
void
meta_ui_tab_popup_backward (MetaTabPopup *popup)
{
if (popup->current != NULL)
popup->current = popup->current->prev;
if (popup->current == NULL)
popup->current = g_list_last (popup->entries);
if (popup->current != NULL)
{
TabEntry *te;
te = popup->current->data;
display_entry (popup, te);
}
}
MetaTabEntryKey
meta_ui_tab_popup_get_selected (MetaTabPopup *popup)
{
if (popup->current)
{
TabEntry *te;
te = popup->current->data;
return te->key;
}
else
return (MetaTabEntryKey)None;
}
void
meta_ui_tab_popup_select (MetaTabPopup *popup,
MetaTabEntryKey key)
{
GList *tmp;
/* Note, "key" may not be in the list of entries; other code assumes
* it's OK to pass in a key that isn't.
*/
tmp = popup->entries;
while (tmp != NULL)
{
TabEntry *te;
te = tmp->data;
if (te->key == key)
{
popup->current = tmp;
display_entry (popup, te);
return;
}
tmp = tmp->next;
}
}
#define META_TYPE_SELECT_IMAGE (meta_select_image_get_type ())
#define META_SELECT_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SELECT_IMAGE, MetaSelectImage))
typedef struct _MetaSelectImage MetaSelectImage;
typedef struct _MetaSelectImageClass MetaSelectImageClass;
struct _MetaSelectImage
{
GtkImage parent_instance;
guint selected : 1;
};
struct _MetaSelectImageClass
{
GtkImageClass parent_class;
};
static GType meta_select_image_get_type (void) G_GNUC_CONST;
static GtkWidget*
selectable_image_new (GdkPixbuf *pixbuf)
{
GtkWidget *w;
w = g_object_new (meta_select_image_get_type (), NULL);
gtk_image_set_from_pixbuf (GTK_IMAGE (w), pixbuf);
return w;
}
static void
select_image (GtkWidget *widget)
{
META_SELECT_IMAGE (widget)->selected = TRUE;
gtk_widget_queue_draw (widget);
}
static void
unselect_image (GtkWidget *widget)
{
META_SELECT_IMAGE (widget)->selected = FALSE;
gtk_widget_queue_draw (widget);
}
static void meta_select_image_class_init (MetaSelectImageClass *klass);
static gboolean meta_select_image_draw (GtkWidget *widget,
cairo_t *cr);
static GtkImageClass *parent_class;
GType
meta_select_image_get_type (void)
{
static GType image_type = 0;
if (!image_type)
{
static const GTypeInfo image_info =
{
sizeof (MetaSelectImageClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) meta_select_image_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (MetaSelectImage),
16, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
image_type = g_type_register_static (GTK_TYPE_IMAGE, "MetaSelectImage", &image_info, 0);
}
return image_type;
}
static void
meta_select_image_class_init (MetaSelectImageClass *klass)
{
GtkWidgetClass *widget_class;
parent_class = g_type_class_peek (gtk_image_get_type ());
widget_class = GTK_WIDGET_CLASS (klass);
widget_class->draw = meta_select_image_draw;
}
static gboolean
meta_select_image_draw (GtkWidget *widget,
cairo_t *cr)
{
GtkAllocation allocation;
gtk_widget_get_allocation (widget, &allocation);
if (META_SELECT_IMAGE (widget)->selected)
{
GtkMisc *misc;
GtkRequisition requisition;
GtkStyleContext *context;
GdkRGBA color;
int x, y, w, h;
gint xpad, ypad;
gfloat xalign, yalign;
misc = GTK_MISC (widget);
gtk_widget_get_requisition (widget, &requisition);
gtk_misc_get_alignment (misc, &xalign, &yalign);
gtk_misc_get_padding (misc, &xpad, &ypad);
x = (allocation.width - (requisition.width - xpad * 2)) * xalign + 0.5;
y = (allocation.height - (requisition.height - ypad * 2)) * yalign + 0.5;
x -= INSIDE_SELECT_RECT + 1;
y -= INSIDE_SELECT_RECT + 1;
w = requisition.width - OUTSIDE_SELECT_RECT * 2 - 1;
h = requisition.height - OUTSIDE_SELECT_RECT * 2 - 1;
context = gtk_widget_get_style_context (widget);
gtk_style_context_set_state (context,
gtk_widget_get_state_flags (widget));
gtk_style_context_lookup_color (context, "color", &color);
cairo_set_line_width (cr, 2.0);
cairo_set_source_rgb (cr, color.red, color.green, color.blue);
cairo_rectangle (cr, x, y, w + 1, h + 1);
cairo_stroke (cr);
cairo_set_line_width (cr, 1.0);
}
return GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
}
#define META_TYPE_SELECT_WORKSPACE (meta_select_workspace_get_type ())
#define META_SELECT_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_SELECT_WORKSPACE, MetaSelectWorkspace))
typedef struct _MetaSelectWorkspace MetaSelectWorkspace;
typedef struct _MetaSelectWorkspaceClass MetaSelectWorkspaceClass;
struct _MetaSelectWorkspace
{
GtkDrawingArea parent_instance;
MetaWorkspace *workspace;
guint selected : 1;
};
struct _MetaSelectWorkspaceClass
{
GtkDrawingAreaClass parent_class;
};
static GType meta_select_workspace_get_type (void) G_GNUC_CONST;
#define SELECT_OUTLINE_WIDTH 2
#define MINI_WORKSPACE_WIDTH 48
static GtkWidget*
selectable_workspace_new (MetaWorkspace *workspace)
{
GtkWidget *widget;
double screen_aspect;
widget = g_object_new (meta_select_workspace_get_type (), NULL);
screen_aspect = (double) workspace->screen->rect.height /
(double) workspace->screen->rect.width;
/* account for select rect */
gtk_widget_set_size_request (widget,
MINI_WORKSPACE_WIDTH + SELECT_OUTLINE_WIDTH * 2,
MINI_WORKSPACE_WIDTH * screen_aspect + SELECT_OUTLINE_WIDTH * 2);
META_SELECT_WORKSPACE (widget)->workspace = workspace;
return widget;
}
static void
select_workspace (GtkWidget *widget)
{
META_SELECT_WORKSPACE(widget)->selected = TRUE;
gtk_widget_queue_draw (widget);
}
static void
unselect_workspace (GtkWidget *widget)
{
META_SELECT_WORKSPACE (widget)->selected = FALSE;
gtk_widget_queue_draw (widget);
}
static void meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass);
static gboolean meta_select_workspace_draw (GtkWidget *widget,
cairo_t *cr);
GType
meta_select_workspace_get_type (void)
{
static GType workspace_type = 0;
if (!workspace_type)
{
static const GTypeInfo workspace_info =
{
sizeof (MetaSelectWorkspaceClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) meta_select_workspace_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (MetaSelectWorkspace),
16, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
workspace_type = g_type_register_static (GTK_TYPE_DRAWING_AREA,
"MetaSelectWorkspace",
&workspace_info,
0);
}
return workspace_type;
}
static void
meta_select_workspace_class_init (MetaSelectWorkspaceClass *klass)
{
GtkWidgetClass *widget_class;
widget_class = GTK_WIDGET_CLASS (klass);
widget_class->draw = meta_select_workspace_draw;
}
/**
* meta_convert_meta_to_wnck:
* @window: the #MetaWindow
* @screen: the #MetaScreen the window is on
*
* Converts a #MetaWindow to a #WnckWindowDisplayInfo window
* that is used to build a thumbnail of a workspace.
**/
static WnckWindowDisplayInfo
meta_convert_meta_to_wnck (MetaWindow *window, MetaScreen *screen)
{
WnckWindowDisplayInfo wnck_window;
wnck_window.icon = window->icon;
wnck_window.mini_icon = window->mini_icon;
wnck_window.is_active = window->has_focus;
if (window->frame)
{
wnck_window.x = window->frame->rect.x;
wnck_window.y = window->frame->rect.y;
wnck_window.width = window->frame->rect.width;
wnck_window.height = window->frame->rect.height;
}
else
{
wnck_window.x = window->rect.x;
wnck_window.y = window->rect.y;
wnck_window.width = window->rect.width;
wnck_window.height = window->rect.height;
}
return wnck_window;
}
static gboolean
meta_select_workspace_draw (GtkWidget *widget,
cairo_t *cr)
{
MetaWorkspace *workspace;
WnckWindowDisplayInfo *windows;
GtkAllocation allocation;
int i, n_windows;
GList *tmp, *list;
workspace = META_SELECT_WORKSPACE (widget)->workspace;
list = meta_stack_list_windows (workspace->screen->stack, workspace);
n_windows = g_list_length (list);
windows = g_new (WnckWindowDisplayInfo, n_windows);
tmp = list;
i = 0;
while (tmp != NULL)
{
MetaWindow *window;
gboolean ignoreable_sticky;
window = tmp->data;
ignoreable_sticky = window->on_all_workspaces &&
workspace != workspace->screen->active_workspace;
if (window->skip_pager ||
!meta_window_showing_on_its_workspace (window) ||
window->unmaps_pending ||
ignoreable_sticky)
{
--n_windows;
}
else
{
windows[i] = meta_convert_meta_to_wnck (window, workspace->screen);
i++;
}
tmp = tmp->next;
}
g_list_free (list);
gtk_widget_get_allocation (widget, &allocation);
wnck_draw_workspace (widget,
cr,
SELECT_OUTLINE_WIDTH,
SELECT_OUTLINE_WIDTH,
allocation.width - SELECT_OUTLINE_WIDTH * 2,
allocation.height - SELECT_OUTLINE_WIDTH * 2,
workspace->screen->rect.width,
workspace->screen->rect.height,
NULL,
(workspace->screen->active_workspace == workspace),
windows,
n_windows);
g_free (windows);
if (META_SELECT_WORKSPACE (widget)->selected)
{
GtkStyleContext *context;
GdkRGBA color;
context = gtk_widget_get_style_context (widget);
gtk_style_context_set_state (context,
gtk_widget_get_state_flags (widget));
gtk_style_context_lookup_color (context, "color", &color);
cairo_set_line_width (cr, SELECT_OUTLINE_WIDTH);
cairo_set_source_rgb (cr, color.red, color.green, color.blue);
cairo_rectangle (cr,
SELECT_OUTLINE_WIDTH / 2.0, SELECT_OUTLINE_WIDTH / 2.0,
allocation.width - SELECT_OUTLINE_WIDTH,
allocation.height - SELECT_OUTLINE_WIDTH);
cairo_stroke (cr);
}
return TRUE;
}

View File

@ -1,65 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Mutter tab popup window */
/*
* Copyright (C) 2001 Havoc Pennington
* Copyright (C) 2005 Elijah Newren
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef META_TABPOPUP_H
#define META_TABPOPUP_H
/* Don't include gtk.h or gdk.h here */
#include <meta/common.h>
#include <meta/boxes.h>
#include <X11/Xlib.h>
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
typedef struct _MetaTabEntry MetaTabEntry;
typedef struct _MetaTabPopup MetaTabPopup;
typedef void *MetaTabEntryKey;
struct _MetaTabEntry
{
MetaTabEntryKey key;
const char *title;
GdkPixbuf *icon;
MetaRectangle rect;
MetaRectangle inner_rect;
guint blank : 1;
guint hidden : 1;
guint demands_attention : 1;
};
MetaTabPopup* meta_ui_tab_popup_new (const MetaTabEntry *entries,
int screen_number,
int entry_count,
int width,
gboolean outline);
void meta_ui_tab_popup_free (MetaTabPopup *popup);
void meta_ui_tab_popup_set_showing (MetaTabPopup *popup,
gboolean showing);
void meta_ui_tab_popup_forward (MetaTabPopup *popup);
void meta_ui_tab_popup_backward (MetaTabPopup *popup);
MetaTabEntryKey meta_ui_tab_popup_get_selected (MetaTabPopup *popup);
void meta_ui_tab_popup_select (MetaTabPopup *popup,
MetaTabEntryKey key);
#endif

View File

@ -178,6 +178,4 @@ int meta_ui_get_drag_threshold (MetaUI *ui);
MetaUIDirection meta_ui_get_direction (void);
#include "tabpopup.h"
#endif