static void matewnck_selector_insert_window (MatewnckSelector *selector, MatewnckWindow *window) { GtkWidget *item; MatewnckScreen *screen; MatewnckWorkspace *workspace; int workspace_n; int i; screen = matewnck_selector_get_screen (selector); workspace = matewnck_window_get_workspace (window); if (!workspace && !matewnck_window_is_pinned (window)) return; item = matewnck_selector_create_window (selector, window); if (!workspace || workspace == matewnck_screen_get_active_workspace (screen)) { /* window is pinned or in the current workspace * => insert before the separator */ GList *l, *children; i = 0; children = gtk_container_get_children (GTK_CONTAINER (selector->priv->menu)); for (l = children; l; l = l->next) { if (GTK_IS_SEPARATOR_MENU_ITEM (l->data)) break; i++; } g_list_free (children); gtk_menu_shell_insert (GTK_MENU_SHELL (selector->priv->menu), item, i); } else { workspace_n = matewnck_workspace_get_number (workspace); if (workspace_n == matewnck_screen_get_workspace_count (screen) - 1) /* window is in last workspace => just append */ gtk_menu_shell_append (GTK_MENU_SHELL (selector->priv->menu), item); else { /* insert just before the next workspace item */ GList *l, *children; i = 0; children = gtk_container_get_children (GTK_CONTAINER (selector->priv->menu)); for (l = children; l; l = l->next) { int j; j = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (l->data), "matewnck-selector-workspace-n")); if (j - 1 == workspace_n + 1) break; i++; } g_list_free (children); gtk_menu_shell_insert (GTK_MENU_SHELL (selector->priv->menu), item, i); } } }
static gboolean matewnck_selector_scroll_cb (MatewnckSelector *selector, GdkEventScroll *event, gpointer user_data) { MatewnckScreen *screen; MatewnckWorkspace *workspace; GList *windows_list; GList *l; MatewnckWindow *window; MatewnckWindow *previous_window; gboolean should_activate_next_window; screen = matewnck_selector_get_screen (selector); workspace = matewnck_screen_get_active_workspace (screen); windows_list = matewnck_screen_get_windows (screen); windows_list = g_list_sort (windows_list, matewnck_selector_windows_compare); /* Walk through the list of windows until we find the active one * (considering only those windows on the same workspace). * Then, depending on whether we're scrolling up or down, activate the next * window in the list (if it exists), or the previous one. */ previous_window = NULL; should_activate_next_window = FALSE; for (l = windows_list; l; l = l->next) { window = MATEWNCK_WINDOW (l->data); if (matewnck_window_is_skip_tasklist (window)) continue; if (workspace && !matewnck_window_is_pinned (window) && matewnck_window_get_workspace (window) != workspace) continue; if (should_activate_next_window) { matewnck_window_activate_transient (window, event->time); return TRUE; } if (matewnck_window_is_active (window)) { switch (event->direction) { case GDK_SCROLL_UP: if (previous_window != NULL) { matewnck_window_activate_transient (previous_window, event->time); return TRUE; } break; case GDK_SCROLL_DOWN: should_activate_next_window = TRUE; break; case GDK_SCROLL_LEFT: case GDK_SCROLL_RIGHT: /* We ignore LEFT and RIGHT scroll events. */ break; default: g_assert_not_reached (); } } previous_window = window; } return TRUE; }
static void matewnck_selector_on_show (GtkWidget *widget, MatewnckSelector *selector) { GtkWidget *separator; MatewnckScreen *screen; MatewnckWorkspace *workspace; int nb_workspace; int i; GList **windows_per_workspace; GList *windows; GList *l, *children; /* Remove existing items */ children = gtk_container_get_children (GTK_CONTAINER (selector->priv->menu)); for (l = children; l; l = l->next) gtk_container_remove (GTK_CONTAINER (selector->priv->menu), l->data); g_list_free (children); if (selector->priv->window_hash) g_hash_table_destroy (selector->priv->window_hash); selector->priv->window_hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); screen = matewnck_selector_get_screen (selector); nb_workspace = matewnck_screen_get_workspace_count (screen); windows_per_workspace = g_malloc0 (nb_workspace * sizeof (GList *)); /* Get windows ordered by workspaces */ windows = matewnck_screen_get_windows (screen); windows = g_list_sort (windows, matewnck_selector_windows_compare); for (l = windows; l; l = l->next) { workspace = matewnck_window_get_workspace (l->data); if (!workspace && matewnck_window_is_pinned (l->data)) workspace = matewnck_screen_get_active_workspace (screen); if (!workspace) continue; i = matewnck_workspace_get_number (workspace); windows_per_workspace[i] = g_list_prepend (windows_per_workspace[i], l->data); } /* Add windows from the current workspace */ workspace = matewnck_screen_get_active_workspace (screen); if (workspace) { i = matewnck_workspace_get_number (workspace); windows_per_workspace[i] = g_list_reverse (windows_per_workspace[i]); for (l = windows_per_workspace[i]; l; l = l->next) matewnck_selector_append_window (selector, l->data); g_list_free (windows_per_workspace[i]); windows_per_workspace[i] = NULL; } /* Add separator */ separator = gtk_separator_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (selector->priv->menu), separator); /* Add windows from other workspaces */ for (i = 0; i < nb_workspace; i++) { matewnck_selector_add_workspace (selector, screen, i); windows_per_workspace[i] = g_list_reverse (windows_per_workspace[i]); for (l = windows_per_workspace[i]; l; l = l->next) matewnck_selector_append_window (selector, l->data); g_list_free (windows_per_workspace[i]); windows_per_workspace[i] = NULL; } g_free (windows_per_workspace); selector->priv->no_windows_item = matewnck_selector_item_new (selector, _("No Windows Open"), NULL); gtk_widget_set_sensitive (selector->priv->no_windows_item, FALSE); gtk_menu_shell_append (GTK_MENU_SHELL (selector->priv->menu), selector->priv->no_windows_item); matewnck_selector_make_menu_consistent (selector); }
static gboolean update_menu_state (MatewnckActionMenu *menu) { MatewnckActionMenuPrivate *priv; MatewnckWindowActions actions; MatewnckScreen *screen; MatewnckWorkspace *workspace; gboolean viewport_mode; gboolean move_workspace_sensitive; priv = menu->priv; priv->idle_handler = 0; actions = matewnck_window_get_actions (priv->window); screen = matewnck_window_get_screen (priv->window); viewport_mode = matewnck_screen_get_workspace_count (screen) == 1 && matewnck_workspace_is_virtual (matewnck_screen_get_workspace (screen, 0)); move_workspace_sensitive = viewport_mode || (actions & MATEWNCK_WINDOW_ACTION_CHANGE_WORKSPACE) != 0; if (matewnck_window_is_minimized (priv->window)) { set_item_text (priv->minimize_item, _("Unmi_nimize")); set_item_stock (priv->minimize_item, NULL); gtk_widget_set_sensitive (priv->minimize_item, (actions & MATEWNCK_WINDOW_ACTION_UNMINIMIZE) != 0); } else { set_item_text (priv->minimize_item, _("Mi_nimize")); set_item_stock (priv->minimize_item, MATEWNCK_STOCK_MINIMIZE); gtk_widget_set_sensitive (priv->minimize_item, (actions & MATEWNCK_WINDOW_ACTION_MINIMIZE) != 0); } if (matewnck_window_is_maximized (priv->window)) { set_item_text (priv->maximize_item, _("Unma_ximize")); set_item_stock (priv->maximize_item, NULL); gtk_widget_set_sensitive (priv->maximize_item, (actions & MATEWNCK_WINDOW_ACTION_UNMAXIMIZE) != 0); } else { set_item_text (priv->maximize_item, _("Ma_ximize")); set_item_stock (priv->maximize_item, MATEWNCK_STOCK_MAXIMIZE); gtk_widget_set_sensitive (priv->maximize_item, (actions & MATEWNCK_WINDOW_ACTION_MAXIMIZE) != 0); } g_signal_handlers_block_by_func (G_OBJECT (priv->above_item), item_activated_callback, GINT_TO_POINTER (ABOVE)); gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (priv->above_item), matewnck_window_is_above (priv->window)); g_signal_handlers_unblock_by_func (G_OBJECT (priv->above_item), item_activated_callback, GINT_TO_POINTER (ABOVE)); gtk_widget_set_sensitive (priv->above_item, (actions & MATEWNCK_WINDOW_ACTION_ABOVE) != 0); g_signal_handlers_block_by_func (G_OBJECT (priv->pin_item), item_activated_callback, GINT_TO_POINTER (PIN)); g_signal_handlers_block_by_func (G_OBJECT (priv->unpin_item), item_activated_callback, GINT_TO_POINTER (UNPIN)); if ((viewport_mode && matewnck_window_is_sticky (priv->window)) || (!viewport_mode && matewnck_window_is_pinned (priv->window))) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (priv->pin_item), TRUE); else gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (priv->unpin_item), TRUE); g_signal_handlers_unblock_by_func (G_OBJECT (priv->pin_item), item_activated_callback, GINT_TO_POINTER (PIN)); g_signal_handlers_unblock_by_func (G_OBJECT (priv->unpin_item), item_activated_callback, GINT_TO_POINTER (UNPIN)); gtk_widget_set_sensitive (priv->pin_item, move_workspace_sensitive); gtk_widget_set_sensitive (priv->unpin_item, move_workspace_sensitive); gtk_widget_set_sensitive (priv->close_item, (actions & MATEWNCK_WINDOW_ACTION_CLOSE) != 0); gtk_widget_set_sensitive (priv->move_item, (actions & MATEWNCK_WINDOW_ACTION_MOVE) != 0); gtk_widget_set_sensitive (priv->resize_item, (actions & MATEWNCK_WINDOW_ACTION_RESIZE) != 0); gtk_widget_set_sensitive (priv->workspace_item, move_workspace_sensitive); gtk_widget_set_sensitive (priv->left_item, move_workspace_sensitive); gtk_widget_set_sensitive (priv->right_item, move_workspace_sensitive); gtk_widget_set_sensitive (priv->up_item, move_workspace_sensitive); gtk_widget_set_sensitive (priv->down_item, move_workspace_sensitive); workspace = matewnck_window_get_workspace (priv->window); if (viewport_mode && !matewnck_window_is_sticky (priv->window)) { int window_x, window_y; int viewport_x, viewport_y; int viewport_width, viewport_height; int screen_width, screen_height; if (!workspace) workspace = matewnck_screen_get_workspace (screen, 0); matewnck_window_get_geometry (priv->window, &window_x, &window_y, NULL, NULL); viewport_x = matewnck_workspace_get_viewport_x (workspace); viewport_y = matewnck_workspace_get_viewport_y (workspace); window_x += viewport_x; window_y += viewport_y; viewport_width = matewnck_workspace_get_width (workspace); viewport_height = matewnck_workspace_get_height (workspace); screen_width = matewnck_screen_get_width (screen); screen_height = matewnck_screen_get_height (screen); if (window_x >= screen_width) gtk_widget_show (priv->left_item); else gtk_widget_hide (priv->left_item); if (window_x < viewport_width - screen_width) gtk_widget_show (priv->right_item); else gtk_widget_hide (priv->right_item); if (window_y >= screen_height) gtk_widget_show (priv->up_item); else gtk_widget_hide (priv->up_item); if (window_y < viewport_height - screen_height) gtk_widget_show (priv->down_item); else gtk_widget_hide (priv->down_item); } else if (!viewport_mode && workspace && !matewnck_window_is_pinned (priv->window)) { if (matewnck_workspace_get_neighbor (workspace, MATEWNCK_MOTION_LEFT)) gtk_widget_show (priv->left_item); else gtk_widget_hide (priv->left_item); if (matewnck_workspace_get_neighbor (workspace, MATEWNCK_MOTION_RIGHT)) gtk_widget_show (priv->right_item); else gtk_widget_hide (priv->right_item); if (matewnck_workspace_get_neighbor (workspace, MATEWNCK_MOTION_UP)) gtk_widget_show (priv->up_item); else gtk_widget_hide (priv->up_item); if (matewnck_workspace_get_neighbor (workspace, MATEWNCK_MOTION_DOWN)) gtk_widget_show (priv->down_item); else gtk_widget_hide (priv->down_item); } else { gtk_widget_hide (priv->left_item); gtk_widget_hide (priv->right_item); gtk_widget_hide (priv->up_item); gtk_widget_hide (priv->down_item); } if (viewport_mode) { int viewport_width, viewport_height; int screen_width, screen_height; viewport_width = matewnck_workspace_get_width (workspace); viewport_height = matewnck_workspace_get_height (workspace); screen_width = matewnck_screen_get_width (screen); screen_height = matewnck_screen_get_height (screen); gtk_widget_show (priv->workspace_separator); gtk_widget_show (priv->pin_item); gtk_widget_show (priv->unpin_item); if (viewport_width >= 2 * screen_width || viewport_height >= 2 * screen_height) { gtk_widget_show (priv->workspace_item); refill_submenu_viewport (menu); } else { gtk_widget_hide (priv->workspace_item); gtk_menu_popdown (GTK_MENU (gtk_menu_item_get_submenu (GTK_MENU_ITEM (priv->workspace_item)))); } } else if (matewnck_screen_get_workspace_count (screen) > 1) { gtk_widget_show (priv->workspace_separator); gtk_widget_show (priv->pin_item); gtk_widget_show (priv->unpin_item); gtk_widget_show (priv->workspace_item); refill_submenu_workspace (menu); } else { gtk_widget_hide (priv->workspace_separator); gtk_widget_hide (priv->pin_item); gtk_widget_hide (priv->unpin_item); gtk_widget_hide (priv->workspace_item); gtk_menu_popdown (GTK_MENU (gtk_menu_item_get_submenu (GTK_MENU_ITEM (priv->workspace_item)))); } gtk_menu_reposition (GTK_MENU (menu)); return FALSE; }