예제 #1
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);
}
예제 #2
0
/**
 * shell_global_get_current_time:
 * @global: A #ShellGlobal
 *
 * Returns: the current X server time from the current Clutter, Gdk, or X
 * event. If called from outside an event handler, this may return
 * %Clutter.CURRENT_TIME (aka 0), or it may return a slightly
 * out-of-date timestamp.
 */
guint32
shell_global_get_current_time (ShellGlobal *global)
{
  guint32 time;
  MetaDisplay *display;

  /* meta_display_get_current_time() will return the correct time
     when handling an X or Gdk event, but will return CurrentTime
     from some Clutter event callbacks.

     clutter_get_current_event_time() will return the correct time
     from a Clutter event callback, but may return an out-of-date
     timestamp if called at other times.

     So we try meta_display_get_current_time() first, since we
     can recognize a "wrong" answer from that, and then fall back
     to clutter_get_current_event_time().
   */

  display = meta_screen_get_display (shell_global_get_screen (global));
  time = meta_display_get_current_time (display);
  if (time != CLUTTER_CURRENT_TIME)
      return time;

  return clutter_get_current_event_time ();
}
예제 #3
0
gboolean meta_switcher_show(MetaSwitcher* self)
{
    MetaSwitcherPrivate* priv = self->priv;
    int screen_width, screen_height;

    MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
    priv->workspace = meta_screen_get_active_workspace(screen);

    meta_screen_get_size(screen, &screen_width, &screen_height);

    meta_switcher_present_list(self);
    if (priv->apps == NULL || priv->apps->len == 0) goto _end;

    _capture_desktop(self);
    clutter_content_invalidate(clutter_actor_get_content(priv->top));

    ClutterActor* stage = meta_get_stage_for_screen(screen);
    clutter_actor_insert_child_above(stage, priv->top, NULL);
    clutter_actor_show(priv->top);

    if (!meta_plugin_begin_modal(priv->plugin, 0, clutter_get_current_event_time())) {
        if (!meta_plugin_begin_modal(priv->plugin, META_MODAL_POINTER_ALREADY_GRABBED,
                    clutter_get_current_event_time())) {
            g_warning("can not be modal");
            goto _end;
        }
    }

    meta_disable_unredirect_for_screen(screen);
    priv->modaled = TRUE;

    priv->previous_focused = clutter_stage_get_key_focus(CLUTTER_STAGE(stage));
    if (priv->previous_focused == stage) priv->previous_focused = NULL;
    clutter_stage_set_key_focus(CLUTTER_STAGE(stage), priv->top);
    clutter_actor_grab_key_focus(priv->top);

    return TRUE;

_end:
    clutter_actor_hide(priv->top);
    return FALSE;
}
예제 #4
0
static void
_button_clicked_cb (MpdFolderButton  *button,
                    MpdFolderTile    *self)
{
  char const  *uri;
  GError      *error = NULL;

  uri = mpd_folder_button_get_uri (button);
  gtk_show_uri (NULL, uri, clutter_get_current_event_time (), &error);
  if (error)
  {
    g_warning ("%s : %s", G_STRLOC, error->message);
    g_clear_error (&error);
  } else {
    g_signal_emit_by_name (self, "request-hide");
  }
}
예제 #5
0
void moses_overview_show(MosesOverview* self, gboolean all_windows)
{
    MosesOverviewPrivate* priv = self->priv;

    MetaRectangle geom;
    MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
    int focused_monitor = meta_screen_get_current_monitor(screen);
    meta_screen_get_monitor_geometry(screen, focused_monitor, &geom);

    // FIXME: overview is as big as the current monitor,
    // need to take care multiple monitors
    ClutterActor* stage = meta_get_stage_for_screen(screen);
    ClutterActor* top = CLUTTER_ACTOR(self);
    clutter_actor_set_size(top, geom.width, geom.height);
    clutter_actor_insert_child_above(stage, top, NULL);

    moses_overview_setup(self);
    priv->previous_focused = clutter_stage_get_key_focus(CLUTTER_STAGE(stage));

    if (!meta_plugin_begin_modal(priv->plugin, 0, clutter_get_current_event_time())) {
        g_warning("can not be modal");
        goto _end;
    }

    meta_disable_unredirect_for_screen(screen);

    clutter_actor_show(top);
    clutter_stage_set_key_focus(CLUTTER_STAGE(stage), top);
    clutter_actor_grab_key_focus(top);

    priv->modaled = TRUE;
    g_idle_add((GSourceFunc)on_idle, self);

    return;

_end:
    clutter_actor_destroy(CLUTTER_ACTOR(self));
}
static void
_open_clicked_cb (MxButton              *button,
                  MpdStorageDeviceTile  *self)
{
  GError *error = NULL;
  MpdStorageDeviceTilePrivate *priv = GET_PRIVATE (self);

  if (!priv->mount_point)
  {
    g_warning ("%s: Mount point uri not set", G_STRLOC);
    return;
  }

  gtk_show_uri (NULL, priv->mount_point,
                clutter_get_current_event_time (), &error);
  if (error)
  {
    g_warning ("%s : %s", G_STRLOC, error->message);
    g_clear_error (&error);
  }

  g_signal_emit_by_name (self, "request-hide");
}
예제 #7
0
파일: IoClutter.c 프로젝트: akimd/io
IO_METHOD(IoClutter, currentEventTime) {
    return IoDate_newWithTime_(IOSTATE, clutter_get_current_event_time());
}
예제 #8
0
static void moses_overview_dispose(GObject *object)
{
    MosesOverview *overview = MOSES_OVERVIEW(object);
    MosesOverviewPrivate* priv = overview->priv;

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

    g_clear_pointer(&priv->ov_head, g_object_unref);

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

    ClutterActor* to_focus = NULL;
    if (priv->selected_actor) {
        to_focus = clutter_clone_get_source(CLUTTER_CLONE(priv->selected_actor));
    }

    for (int i = 0; priv->clones && i < priv->clones->len; i++) {
        ClutterActor* clone = g_ptr_array_index(priv->clones, i);
        ClutterActor* orig = clutter_clone_get_source(CLUTTER_CLONE(clone));
        clutter_actor_show(orig); // FIXME: maybe some actors had not been shown.
        clutter_actor_destroy(clone);
    }

    for (int i = 0; priv->badges && i < priv->badges->len; i++) {
        clutter_actor_destroy(CLUTTER_ACTOR(g_ptr_array_index(priv->badges, i)));
    }

    if (priv->background_actor) {
        clutter_actor_show(clutter_clone_get_source(CLUTTER_CLONE(priv->background_actor)));
        g_clear_pointer(&priv->background_actor, clutter_actor_destroy);
    }

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

        if (priv->selected_workspace) {
            meta_workspace_activate(priv->selected_workspace, CLUTTER_CURRENT_TIME);
            MetaDisplay* display = meta_screen_get_display(screen);
            meta_compositor_switch_workspace(meta_display_get_compositor(display),
                    meta_screen_get_active_workspace(screen),
                    priv->selected_workspace, META_MOTION_DOWN);

        } else if (to_focus) {
            clutter_stage_set_key_focus(CLUTTER_STAGE(stage), to_focus);
            MetaWindowActor* actor = META_WINDOW_ACTOR(to_focus);
            MetaWindow* win = meta_window_actor_get_meta_window(actor);
            meta_window_raise(win);
            meta_window_focus(win, CLUTTER_CURRENT_TIME);

        } else if (priv->previous_focused) {
            if (!CLUTTER_IS_STAGE(priv->previous_focused)) {
                clutter_stage_set_key_focus(CLUTTER_STAGE(stage), priv->previous_focused);
            }
        }
    }

    G_OBJECT_CLASS(moses_overview_parent_class)->dispose(object);
}
예제 #9
0
//FIXME: actually key_release is activated even when key press (WTF). does it because I'm hold alt/super?
static gboolean on_key_release(ClutterActor *actor, ClutterEvent *event, MetaSwitcher* self)
{
    MetaSwitcherPrivate* priv = self->priv;
    MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
    MetaDisplay* display = meta_screen_get_display(screen);

    ClutterModifierType state = clutter_event_get_state(event);
    guint keysym = clutter_event_get_key_symbol(event);
    guint action = meta_display_get_keybinding_action(display, clutter_event_get_key_code(event), state);

    int id = priv->selected_id;
    if (action == META_KEYBINDING_ACTION_SWITCH_WINDOWS) {
        id = (id + 1) % priv->apps->len;
    } else if (action == META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD) {
        id = (priv->apps->len + id - 1) % priv->apps->len;
    } else if (action == META_KEYBINDING_ACTION_SWITCH_APPLICATIONS) {
        id = (id + 1) % priv->apps->len;
    } else if (action == META_KEYBINDING_ACTION_SWITCH_APPLICATIONS_BACKWARD) {
        id = (priv->apps->len + id - 1) % priv->apps->len;
    }
    _set_highlight(self, priv->selected_id, FALSE);
    _set_highlight(self, id, TRUE);
    g_debug("%s, key: 0x%x, action: %d, previd: %d, now: %d", __func__, keysym, action,
            priv->selected_id, id);
    priv->selected_id = id;

    switch(keysym) {
        //FIXME: do not hardcode keysyms, use action instead
        case CLUTTER_KEY_Super_L:
        case CLUTTER_KEY_Super_R:
        case CLUTTER_KEY_Alt_L:
        case CLUTTER_KEY_Alt_R:
        {
            if (priv->selected_id >= 0) {
                meta_window_activate(g_ptr_array_index(priv->apps, priv->selected_id), clutter_get_current_event_time());
            }
            g_object_unref(self);
        }
        default: break;
    }

    return FALSE;
}
/**
 * shell_app_info_launch_full:
 * @timestamp: Event timestamp, or 0 for current event timestamp
 * @uris: List of uris to pass to application
 * @workspace: Start on this workspace, or -1 for default
 * @startup_id: (out): Returned startup notification ID, or %NULL if none
 * @error: A #GError
 */
gboolean
shell_app_info_launch_full (ShellAppInfo *info,
                            guint         timestamp,
                            GList        *uris,
                            int           workspace,
                            char        **startup_id,
                            GError      **error)
{
  ShellApp *shell_app;
  GDesktopAppInfo *gapp;
  GdkAppLaunchContext *context;
  gboolean ret;
  ShellGlobal *global;
  MetaScreen *screen;

  if (startup_id)
    *startup_id = NULL;

  if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
    {
      /* We can't pass URIs into a window; shouldn't hit this
       * code path.  If we do, fix the caller to disallow it.
       */
      g_return_val_if_fail (uris == NULL, TRUE);

      meta_window_activate (info->window, timestamp);
      return TRUE;
    }
  else if (info->type == SHELL_APP_INFO_TYPE_ENTRY)
    {
      /* Can't use g_desktop_app_info_new, see bug 614879 */
      const char *filename = gmenu_tree_entry_get_desktop_file_path ((GMenuTreeEntry *)info->entry);
      gapp = g_desktop_app_info_new_from_filename (filename);
    }
  else
    {
      char *filename = shell_app_info_get_desktop_file_path (info);
      gapp = g_desktop_app_info_new_from_filename (filename);
      g_free (filename);
    }

  if (!gapp)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Not found");
      return FALSE;
    }

  global = shell_global_get ();
  screen = shell_global_get_screen (global);

  if (timestamp == 0)
    timestamp = clutter_get_current_event_time ();

  if (workspace < 0)
    workspace = meta_screen_get_active_workspace_index (screen);

  context = gdk_app_launch_context_new ();
  gdk_app_launch_context_set_timestamp (context, timestamp);
  gdk_app_launch_context_set_desktop (context, workspace);

  shell_app = shell_app_system_get_app (shell_app_system_get_default (),
                                        shell_app_info_get_id (info));

  /* In the case where we know an app, we handle reaping the child internally,
   * in the window tracker.
   */
  if (shell_app != NULL)
    ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris,
                                                     G_APP_LAUNCH_CONTEXT (context),
                                                     G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
                                                     NULL, NULL,
                                                     _gather_pid_callback, shell_app,
                                                     error);
  else
    ret = g_desktop_app_info_launch_uris_as_manager (gapp, uris,
                                                     G_APP_LAUNCH_CONTEXT (context),
                                                     G_SPAWN_SEARCH_PATH,
                                                     NULL, NULL,
                                                     NULL, NULL,
                                                     error);

  g_object_unref (G_OBJECT (gapp));

  return ret;
}
예제 #11
0
/**
 * shell_app_info_launch_full:
 * @timestamp: Event timestamp, or 0 for current event timestamp
 * @uris: List of uris to pass to application
 * @workspace: Start on this workspace, or -1 for default
 * @startup_id: (out): Returned startup notification ID, or %NULL if none
 * @error: A #GError
 */
gboolean
shell_app_info_launch_full (ShellAppInfo *info,
                            guint         timestamp,
                            GList        *uris,
                            int           workspace,
                            char        **startup_id,
                            GError      **error)
{
  GDesktopAppInfo *gapp;
  char *filename;
  GdkAppLaunchContext *context;
  gboolean ret;
  ShellGlobal *global;
  MetaScreen *screen;
  MetaDisplay *display;

  if (startup_id)
    *startup_id = NULL;

  if (info->type == SHELL_APP_INFO_TYPE_WINDOW)
    {
      /* We can't pass URIs into a window; shouldn't hit this
       * code path.  If we do, fix the caller to disallow it.
       */
      g_return_val_if_fail (uris == NULL, TRUE);

      meta_window_activate (info->window, timestamp);
      return TRUE;
    }
  else if (info->type == SHELL_APP_INFO_TYPE_ENTRY)
    {
      gapp = g_desktop_app_info_new (shell_app_info_get_id (info));
    }
  else
    {
      filename = shell_app_info_get_desktop_file_path (info);
      gapp = g_desktop_app_info_new_from_filename (filename);
      g_free (filename);
    }

  if (!gapp)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Not found");
      return FALSE;
    }

  global = shell_global_get ();
  screen = shell_global_get_screen (global);
  display = meta_screen_get_display (screen);

  if (timestamp == 0)
    timestamp = clutter_get_current_event_time ();

  if (workspace < 0)
    workspace = meta_screen_get_active_workspace_index (screen);

  context = gdk_app_launch_context_new ();
  gdk_app_launch_context_set_timestamp (context, timestamp);
  gdk_app_launch_context_set_desktop (context, workspace);

  ret = g_app_info_launch (G_APP_INFO (gapp), uris, (GAppLaunchContext*) context, error);

  g_object_unref (G_OBJECT (gapp));

  return ret;
}