static GtkWidget * matewnck_selector_create_window (MatewnckSelector *selector, MatewnckWindow *window) { MatewnckWorkspace *workspace; GtkWidget *item; GtkWidget *image; char *name; name = _matewnck_window_get_name_for_display (window, FALSE, TRUE); item = matewnck_selector_item_new (selector, name, window); g_free (name); image = gtk_image_new (); matewnck_selector_set_window_icon (selector, image, window, TRUE); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), GTK_WIDGET (image)); gtk_widget_show (image); workspace = matewnck_screen_get_active_workspace (matewnck_selector_get_screen (selector)); g_signal_connect_swapped (item, "activate", G_CALLBACK (matewnck_selector_activate_window), window); if (!matewnck_window_is_skip_tasklist (window)) gtk_widget_show (item); g_object_set_data (G_OBJECT (item), "matewnck-selector-window", window); return item; }
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 applet_scroll(MatePanelApplet* applet, GdkEventScroll* event, PagerData* pager) { GdkScrollDirection absolute_direction; int index; int n_workspaces; int n_columns; int in_last_row; if (event->type != GDK_SCROLL) return FALSE; index = matewnck_workspace_get_number(matewnck_screen_get_active_workspace(pager->screen)); n_workspaces = matewnck_screen_get_workspace_count(pager->screen); n_columns = n_workspaces / pager->n_rows; if (n_workspaces % pager->n_rows != 0) n_columns++; in_last_row = n_workspaces % n_columns; absolute_direction = event->direction; if (gtk_widget_get_direction(GTK_WIDGET(applet)) == GTK_TEXT_DIR_RTL) { switch (event->direction) { case GDK_SCROLL_DOWN: case GDK_SCROLL_UP: break; case GDK_SCROLL_RIGHT: absolute_direction = GDK_SCROLL_LEFT; break; case GDK_SCROLL_LEFT: absolute_direction = GDK_SCROLL_RIGHT; break; } } switch (absolute_direction) { case GDK_SCROLL_DOWN: if (index + n_columns < n_workspaces) { index += n_columns; } else if ((index < n_workspaces - 1 && index + in_last_row != n_workspaces - 1) || (index == n_workspaces - 1 && in_last_row != 0)) { index = (index % n_columns) + 1; } break; case GDK_SCROLL_RIGHT: if (index < n_workspaces - 1) index++; break; case GDK_SCROLL_UP: if (index - n_columns >= 0) { index -= n_columns; } else if (index > 0) { index = ((pager->n_rows - 1) * n_columns) + (index % n_columns) - 1; } if (index >= n_workspaces) index -= n_columns; break; case GDK_SCROLL_LEFT: if (index > 0) index--; break; default: g_assert_not_reached(); break; } matewnck_workspace_activate(matewnck_screen_get_workspace(pager->screen, index), event->time); return TRUE; }