gboolean _wnck_workspace_set_geometry (WnckWorkspace *space, int w, int h) { if (space->priv->width != w || space->priv->height != h) { space->priv->width = w; space->priv->height = h; space->priv->is_virtual = w > wnck_screen_get_width (space->priv->screen) || h > wnck_screen_get_height (space->priv->screen); return TRUE; /* change was made */ } else return FALSE; }
WnckWorkspace* _wnck_workspace_create (int number, WnckScreen *screen) { WnckWorkspace *space; space = g_object_new (WNCK_TYPE_WORKSPACE, NULL); space->priv->number = number; space->priv->name = NULL; space->priv->screen = screen; _wnck_workspace_update_name (space, NULL); /* Just set reasonable defaults */ space->priv->width = wnck_screen_get_width (screen); space->priv->height = wnck_screen_get_height (screen); space->priv->is_virtual = FALSE; space->priv->viewport_x = 0; space->priv->viewport_y = 0; return space; }
/** * return the geometry of the screen to the LUA script */ int c_get_screen_geometry(lua_State *lua) { int top = lua_gettop(lua); if (top != 0) { luaL_error(lua, "get_screen_geometry: %s", no_indata_expected_error); return 0; } int width = -1, height = -1; WnckWindow *window = get_current_window(); if (window) { WnckScreen *screen; screen = wnck_window_get_screen(window); width = wnck_screen_get_width(screen); height = wnck_screen_get_height(screen); } lua_pushnumber(lua, width); lua_pushnumber(lua, height); return 2; }
static void refill_submenu_viewport (WnckActionMenu *menu) { GtkWidget *submenu; GList *children; GList *l; WnckScreen *screen; WnckWorkspace *workspace; int window_x, window_y; int viewport_x, viewport_y; int viewport_width, viewport_height; int screen_width, screen_height; int x, y; int number; submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu->priv->workspace_item)); /* Remove existing items */ children = gtk_container_get_children (GTK_CONTAINER (submenu)); for (l = children; l; l = l->next) gtk_container_remove (GTK_CONTAINER (submenu), l->data); g_list_free (children); screen = wnck_window_get_screen (menu->priv->window); workspace = wnck_screen_get_workspace (screen, 0); wnck_window_get_geometry (menu->priv->window, &window_x, &window_y, NULL, NULL); viewport_x = wnck_workspace_get_viewport_x (workspace); viewport_y = wnck_workspace_get_viewport_y (workspace); window_x += viewport_x; window_y += viewport_y; viewport_width = wnck_workspace_get_width (workspace); viewport_height = wnck_workspace_get_height (workspace); screen_width = wnck_screen_get_width (screen); screen_height = wnck_screen_get_height (screen); number = 1; for (y = 0; y < viewport_height; y += screen_height) { char *label; GtkWidget *item; for (x = 0; x < viewport_width; x += screen_width) { /* Keep this in sync with what is in get_workspace_name_with_accel() */ if (number == 10) label = g_strdup_printf (_("Workspace 1_0")); else label = g_strdup_printf (_("Workspace %s%d"), number < 10 ? "_" : "", number); number++; item = make_menu_item (MOVE_TO_WORKSPACE); g_object_set_data (G_OBJECT (item), "viewport_x", GINT_TO_POINTER (x)); g_object_set_data (G_OBJECT (item), "viewport_y", GINT_TO_POINTER (y)); if (window_x >= x && window_x < x + screen_width && window_y >= y && window_y < y + screen_height) gtk_widget_set_sensitive (item, FALSE); gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); set_item_text (item, label); set_item_stock (item, NULL); g_free (label); } } gtk_menu_reposition (GTK_MENU (submenu)); }
static gboolean update_menu_state (WnckActionMenu *menu) { WnckActionMenuPrivate *priv; WnckWindowActions actions; WnckScreen *screen; WnckWorkspace *workspace; gboolean viewport_mode; gboolean move_workspace_sensitive; priv = menu->priv; priv->idle_handler = 0; actions = wnck_window_get_actions (priv->window); screen = wnck_window_get_screen (priv->window); viewport_mode = wnck_screen_get_workspace_count (screen) == 1 && wnck_workspace_is_virtual (wnck_screen_get_workspace (screen, 0)); move_workspace_sensitive = viewport_mode || (actions & WNCK_WINDOW_ACTION_CHANGE_WORKSPACE) != 0; if (wnck_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 & WNCK_WINDOW_ACTION_UNMINIMIZE) != 0); } else { set_item_text (priv->minimize_item, _("Mi_nimize")); set_item_stock (priv->minimize_item, WNCK_STOCK_MINIMIZE); gtk_widget_set_sensitive (priv->minimize_item, (actions & WNCK_WINDOW_ACTION_MINIMIZE) != 0); } if (wnck_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 & WNCK_WINDOW_ACTION_UNMAXIMIZE) != 0); } else { set_item_text (priv->maximize_item, _("Ma_ximize")); set_item_stock (priv->maximize_item, WNCK_STOCK_MAXIMIZE); gtk_widget_set_sensitive (priv->maximize_item, (actions & WNCK_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), wnck_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 & WNCK_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 && wnck_window_is_sticky (priv->window)) || (!viewport_mode && wnck_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 & WNCK_WINDOW_ACTION_CLOSE) != 0); gtk_widget_set_sensitive (priv->move_item, (actions & WNCK_WINDOW_ACTION_MOVE) != 0); gtk_widget_set_sensitive (priv->resize_item, (actions & WNCK_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 = wnck_window_get_workspace (priv->window); if (viewport_mode && !wnck_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 = wnck_screen_get_workspace (screen, 0); wnck_window_get_geometry (priv->window, &window_x, &window_y, NULL, NULL); viewport_x = wnck_workspace_get_viewport_x (workspace); viewport_y = wnck_workspace_get_viewport_y (workspace); window_x += viewport_x; window_y += viewport_y; viewport_width = wnck_workspace_get_width (workspace); viewport_height = wnck_workspace_get_height (workspace); screen_width = wnck_screen_get_width (screen); screen_height = wnck_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 && !wnck_window_is_pinned (priv->window)) { if (wnck_workspace_get_neighbor (workspace, WNCK_MOTION_LEFT)) gtk_widget_show (priv->left_item); else gtk_widget_hide (priv->left_item); if (wnck_workspace_get_neighbor (workspace, WNCK_MOTION_RIGHT)) gtk_widget_show (priv->right_item); else gtk_widget_hide (priv->right_item); if (wnck_workspace_get_neighbor (workspace, WNCK_MOTION_UP)) gtk_widget_show (priv->up_item); else gtk_widget_hide (priv->up_item); if (wnck_workspace_get_neighbor (workspace, WNCK_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 = wnck_workspace_get_width (workspace); viewport_height = wnck_workspace_get_height (workspace); screen_width = wnck_screen_get_width (screen); screen_height = wnck_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 (wnck_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; }
static void item_activated_callback (GtkWidget *menu_item, gpointer data) { WnckActionMenu *menu; WnckWindow *window; WindowAction action = GPOINTER_TO_INT (data); WnckScreen *screen; gboolean viewport_mode; menu = get_action_menu (menu_item); if (menu == NULL) return; window = menu->priv->window; screen = wnck_window_get_screen (window); viewport_mode = wnck_screen_get_workspace_count (screen) == 1 && wnck_workspace_is_virtual (wnck_screen_get_workspace (screen, 0)); switch (action) { case CLOSE: /* In an activate callback, so gtk_get_current_event_time() suffices */ wnck_window_close (window, gtk_get_current_event_time ()); break; case MINIMIZE: if (wnck_window_is_minimized (window)) wnck_window_unminimize (window, gtk_get_current_event_time ()); else wnck_window_minimize (window); break; case MAXIMIZE: if (wnck_window_is_maximized (window)) wnck_window_unmaximize (window); else wnck_window_maximize (window); break; case ABOVE: if (wnck_window_is_above (window)) wnck_window_unmake_above (window); else wnck_window_make_above (window); break; case MOVE: wnck_window_keyboard_move (window); break; case RESIZE: wnck_window_keyboard_size (window); break; case PIN: if (!viewport_mode) wnck_window_pin (window); else wnck_window_stick (window); break; case UNPIN: if (!viewport_mode) wnck_window_unpin (window); else wnck_window_unstick (window); break; case LEFT: if (!viewport_mode) { WnckWorkspace *workspace; workspace = wnck_workspace_get_neighbor (wnck_window_get_workspace (window), WNCK_MOTION_LEFT); wnck_window_move_to_workspace (window, workspace); } else { int width, xw, yw, ww, hw; width = wnck_screen_get_width (screen); wnck_window_get_geometry (window, &xw, &yw, &ww, &hw); wnck_window_unstick (window); wnck_window_set_geometry (window, 0, WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y, xw - width, yw, ww, hw); } break; case RIGHT: if (!viewport_mode) { WnckWorkspace *workspace; workspace = wnck_workspace_get_neighbor (wnck_window_get_workspace (window), WNCK_MOTION_RIGHT); wnck_window_move_to_workspace (window, workspace); } else { int width, xw, yw, ww, hw; width = wnck_screen_get_width (screen); wnck_window_get_geometry (window, &xw, &yw, &ww, &hw); wnck_window_unstick (window); wnck_window_set_geometry (window, 0, WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y, xw + width, yw, ww, hw); } break; case UP: if (!viewport_mode) { WnckWorkspace *workspace; workspace = wnck_workspace_get_neighbor (wnck_window_get_workspace (window), WNCK_MOTION_UP); wnck_window_move_to_workspace (window, workspace); } else { int height, xw, yw, ww, hw; height = wnck_screen_get_height (screen); wnck_window_get_geometry (window, &xw, &yw, &ww, &hw); wnck_window_unstick (window); wnck_window_set_geometry (window, 0, WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y, xw, yw - height, ww, hw); } break; case DOWN: if (!viewport_mode) { WnckWorkspace *workspace; workspace = wnck_workspace_get_neighbor (wnck_window_get_workspace (window), WNCK_MOTION_DOWN); wnck_window_move_to_workspace (window, workspace); } else { int height, xw, yw, ww, hw; height = wnck_screen_get_height (screen); wnck_window_get_geometry (window, &xw, &yw, &ww, &hw); wnck_window_unstick (window); wnck_window_set_geometry (window, 0, WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y, xw, yw + height, ww, hw); } break; case MOVE_TO_WORKSPACE: if (!viewport_mode) { int workspace_index; WnckWorkspace *workspace; workspace_index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "workspace")); workspace = wnck_screen_get_workspace (screen, workspace_index); wnck_window_move_to_workspace (window, workspace); } else { WnckWorkspace *workspace; int new_viewport_x, new_viewport_y; int width, height; int xw, yw, ww, hw; int viewport_x, viewport_y; new_viewport_x = GPOINTER_TO_INT ( g_object_get_data (G_OBJECT (menu_item), "viewport_x")); new_viewport_y = GPOINTER_TO_INT ( g_object_get_data (G_OBJECT (menu_item), "viewport_y")); workspace = wnck_screen_get_workspace (screen, 0); width = wnck_screen_get_width (screen); height = wnck_screen_get_height (screen); wnck_window_get_geometry (window, &xw, &yw, &ww, &hw); viewport_x = wnck_workspace_get_viewport_x (workspace); viewport_y = wnck_workspace_get_viewport_y (workspace); wnck_window_unstick (window); wnck_window_set_geometry (window, 0, WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y, xw + new_viewport_x - viewport_x, yw + new_viewport_y - viewport_y, ww, hw); } break; default: g_assert_not_reached (); } }
/** * ww_calc_bounds * @screen: The screen for which to calculate the bounds * @struts: A list of %WnckWindow<!---->s that should be treated as * blocking elements on the desktop. Eg. panels and docks * @x: Return value for the left side of the bounding box * @y: Return value for the top of the box * @right: Return coordinate for the right side of the bounding box * @bottom: Return value for the bottom coordinate of the bounding box * * Calculate the maximal rect within a set of blocking windows. * For simplicity this method assumes that all struts are along the screen * edges and expand over the entire screen edge. Ie a standard panel setup. */ void ww_calc_bounds (WnckScreen *screen, GList *struts, int *left, int *top, int *right, int *bottom) { GList *next; WnckWindow *win; int wx, wy, ww, wh; /* current window geom */ int edge_l, edge_t, edge_b, edge_r; int screen_w, screen_h; edge_l = 0; edge_t = 0; edge_r = wnck_screen_get_width (screen); edge_b = wnck_screen_get_height (screen); screen_w = edge_r; screen_h = edge_b; for (next = struts; next; next = next->next) { win = WNCK_WINDOW (next->data); wnck_window_get_geometry (win, &wx, &wy, &ww, &wh); /* Left side strut */ if (is_high(ww, wh) && wx == 0) { edge_l = MAX(edge_l, ww); } /* Top struct */ else if (is_broad(ww, wh) && wy == 0) { edge_t = MAX (edge_t, wh); } /* Right side strut */ else if (is_high(ww, wh) && (wx+ww) == screen_w) { edge_r = MIN(edge_r, wx); } /* Bottom struct */ else if (is_broad(ww, wh) && (wy+wh) == screen_h) { edge_b = MIN (edge_b, wy); } else { g_warning ("Desktop layout contains floating element at " "(%d, %d)@%dx%d", wx, wy, ww, wh); } } g_debug ("Calculated desktop bounds (%d, %d), (%d, %d)", edge_l, edge_t, edge_r, edge_b); *left = edge_l; *top = edge_t; *right = edge_r; *bottom = edge_b; }