예제 #1
0
static void
shell_window_tracker_on_n_workspaces_changed (MetaScreen    *screen,
                                           GParamSpec    *pspec,
                                           gpointer       user_data)
{
  ShellWindowTracker *self = SHELL_WINDOW_TRACKER (user_data);
  GList *workspaces, *iter;

  workspaces = meta_screen_get_workspaces (screen);

  for (iter = workspaces; iter; iter = iter->next)
    {
      MetaWorkspace *workspace = iter->data;

      /* This pair of disconnect/connect is idempotent if we were
       * already connected, while ensuring we get connected for
       * new workspaces.
       */
      g_signal_handlers_disconnect_by_func (workspace,
                                            shell_window_tracker_on_window_added,
                                            self);
      g_signal_handlers_disconnect_by_func (workspace,
                                            shell_window_tracker_on_window_removed,
                                            self);

      g_signal_connect (workspace, "window-added",
                        G_CALLBACK (shell_window_tracker_on_window_added), self);
      g_signal_connect (workspace, "window-removed",
                        G_CALLBACK (shell_window_tracker_on_window_removed), self);
    }
}
예제 #2
0
static void meta_switcher_dispose(GObject *object)
{
    MetaSwitcher *switcher = META_SWITCHER(object);
    MetaSwitcherPrivate* priv = switcher->priv;

    if (priv->disposed) return;
    priv->disposed = TRUE;

    MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
    ClutterActor* stage = meta_get_stage_for_screen(screen);
    clutter_actor_remove_child(stage, priv->top);

    if (priv->modaled) {
        meta_plugin_end_modal(priv->plugin, clutter_get_current_event_time());
        meta_enable_unredirect_for_screen(screen);

        if (priv->selected_id < 0 && priv->previous_focused)
            clutter_stage_set_key_focus(CLUTTER_STAGE(stage), priv->previous_focused);
    }

    if (CLUTTER_IS_ACTOR(priv->top)) {
        g_clear_pointer(&priv->top, clutter_actor_destroy);
    } else priv->top = NULL;

    if (priv->autoclose_id) {
        g_source_remove(priv->autoclose_id);
        priv->autoclose_id = 0;
    }

    GList* ws_list = meta_screen_get_workspaces(screen);
    g_list_foreach(ws_list, (GFunc)unhook_ws_event, switcher);

    G_OBJECT_CLASS(meta_switcher_parent_class)->dispose(object);
}
예제 #3
0
static void meta_switcher_present_list(MetaSwitcher* self)
{
    MetaSwitcherPrivate* priv = self->priv;
    MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
    MetaDisplay* display = meta_screen_get_display(screen);

    // windows on all workspaces
    GList* ls = meta_display_get_tab_list(display, META_TAB_LIST_NORMAL, NULL);
    if (!ls) return;

    GList* ws_list = meta_screen_get_workspaces(screen);
    g_list_foreach(ws_list, (GFunc)hook_ws_event, self);

    if (!priv->apps) {
        priv->apps = g_ptr_array_new();
        GList* orig = ls;
        while (ls) {
            g_ptr_array_add(priv->apps, ls->data);
            ls = ls->next;
        }
        g_list_free(orig);
    }

    clutter_actor_set_height(priv->top, APP_ACTOR_HEIGHT + 20);

    gint x = 0, y = 0;
    for (int i = 0; i < priv->apps->len; i++) {
        _add_app(self, g_ptr_array_index(priv->apps, i), &x, &y);
    }

    clutter_actor_set_margin_left(g_hash_table_lookup(priv->icons, g_ptr_array_index(priv->apps, 0)), 10);
    clutter_actor_set_margin_right(g_hash_table_lookup(priv->icons, g_ptr_array_index(priv->apps, priv->apps->len-1)), 10);

    gint screen_width = 0, screen_height = 0;
    meta_screen_get_size(screen, &screen_width, &screen_height);
    /* TODO: @sonald set top width when bigger than screen width */
    if (clutter_actor_get_width(priv->top) > screen_width)
        clutter_actor_set_width(priv->top, screen_width);

    gfloat w = clutter_actor_get_width(priv->top), h = clutter_actor_get_height(priv->top),
           tx = (screen_width - w) / 2, ty = (screen_height - h) / 2;
#if DEBUG
    g_message("%s, line %d, %f %f", __func__, __LINE__, w, tx);
#endif
    clutter_actor_set_position(priv->top, tx, ty);

    ClutterContent* canvas = clutter_canvas_new();
    clutter_canvas_set_size(CLUTTER_CANVAS(canvas), w, h);
    clutter_actor_set_content(priv->top, canvas);
    g_object_unref(canvas);
    g_signal_connect(canvas, "draw", G_CALLBACK(on_switcher_background_draw), self);

    clutter_content_invalidate(canvas);

    priv->selected_id = 0;
}
예제 #4
0
static void
load_initial_windows (ShellWindowTracker *monitor)
{
  GList *workspaces, *iter;
  MetaScreen *screen = shell_global_get_screen (shell_global_get ());
  workspaces = meta_screen_get_workspaces (screen);

  for (iter = workspaces; iter; iter = iter->next)
    {
      MetaWorkspace *workspace = iter->data;
      GList *windows = meta_workspace_list_windows (workspace);
      GList *window_iter;

      for (window_iter = windows; window_iter; window_iter = window_iter->next)
        {
          MetaWindow *window = window_iter->data;
          track_window (monitor, window);
        }

      g_list_free (windows);
    }
}