示例#1
0
文件: layout.c 项目: jpinon/bonnye
static void get_workspace_geometry(int spaceid,
                                   int *x,
                                   int *y,
                                   int *width,
                                   int *height)
{
    workspace_t *workspace = workspace_get(spaceid);
    workspace_geometry_t *g = &workspace->geometry;
    WnckWorkspace *space = workspace->workspace;
    time_t now = time(NULL);

    if (now > g->last_update + CACHE_DURATION) {
        WnckWindow *window;
        GList      *l;
        GList *all_windows = wnck_screen_get_windows (wnck_workspace_get_screen (space));
        int left   = 0;
        int right  = 0;
        int top    = 0;
        int bottom = 0;
        for (l = all_windows; l; l = l->next) {
            window = WNCK_WINDOW (l->data);
            if (wnck_window_get_workspace(window) == space ||
                    wnck_window_is_pinned(window)) {
                int tl, tr, tt, tb;
                if (get_window_strut(window, &tl, &tr, &tt, &tb)) {
                    if (tl > left  ) left   = tl;
                    if (tr > right ) right  = tr;
                    if (tt > top   ) top    = tt;
                    if (tb > bottom) bottom = tb;
                }
            }
        }
        g->x      = wnck_workspace_get_viewport_x(space) + left;
        g->y      = wnck_workspace_get_viewport_y(space) + top;
        g->width  = wnck_workspace_get_width(space) - left - right;
        g->height = wnck_workspace_get_height(space) - top - bottom;
        g->last_update = now;
    }

    *x = g->x;
    *y = g->y;
    *width = g->width;
    *height = g->height;
}
示例#2
0
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));
}
示例#3
0
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;
}
示例#4
0
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 ();
    }
}
示例#5
0
static gboolean
on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
  SSWorkspace *workspace;
  int screen_width, screen_height;
  double width_ratio, height_ratio;
  int x, y, w, h;
  int viewport_x;
  GList *i;
  SSWindow *active_window;
  WnckWindow *wnck_window;
  int state;
  GdkRectangle r;

  workspace = (SSWorkspace *) data;
  screen_width  = workspace->screen->screen_width;
  screen_height = workspace->screen->screen_height;
  active_window = workspace->screen->active_window;

  x = widget->allocation.x;
  y = widget->allocation.y;
  w = widget->allocation.width;
  h = widget->allocation.height;

  state = (workspace == workspace->screen->active_workspace) ? GTK_STATE_SELECTED : GTK_STATE_NORMAL;
  gdk_draw_rectangle (widget->window,
    widget->style->dark_gc[state], TRUE,
    1, 1, w-2, h-2);
  gdk_draw_rectangle (widget->window,
    widget->style->base_gc[state], FALSE,
    0, 0, w-1, h-1);

  width_ratio  = (double) w / (double) screen_width;
  height_ratio = (double) h / (double) screen_height;

  viewport_x = 0;
  if (window_manager_uses_viewports) {
    viewport_x = wnck_workspace_get_viewport_x (workspace->wnck_workspace);
  }

  for (i = workspace->screen->wnck_windows_in_stacking_order; i; i = i->next) {
    wnck_window = (WnckWindow *) i->data;
    if (wnck_window_get_workspace (wnck_window) != workspace->wnck_workspace) {
      continue;
    }
    if (wnck_window_is_minimized (wnck_window)) {
      continue;
    }

    state = GTK_STATE_ACTIVE;
    if ((active_window != NULL) &&
      ((wnck_window_get_xid (wnck_window) == wnck_window_get_xid (active_window->wnck_window)))) {
      state = GTK_STATE_SELECTED;
    }
    wnck_window_get_geometry (wnck_window, &r.x, &r.y, &r.width, &r.height);
    if (window_manager_uses_viewports) {
      r.x += viewport_x - (workspace->viewport * workspace->screen->screen_width);
    }

    r.x = 0.5 + r.x * width_ratio;
    r.y = 0.5 + r.y * height_ratio;
    r.width  = 0.5 + r.width  * width_ratio;
    r.height = 0.5 + r.height * height_ratio;

    if (r.width < 3) {
      r.width = 3;
    }
    if (r.height < 3) {
      r.height = 3;
    }

    gdk_draw_rectangle (widget->window,
      widget->style->bg_gc[state], TRUE,
      r.x+1, r.y+1, r.width-2, r.height-2);
    gdk_draw_rectangle (widget->window,
      widget->style->fg_gc[state], FALSE,
      r.x,   r.y,   r.width-1, r.height-1);
  }

  on_expose_event_draw_text (widget, workspace);
  return FALSE;
}