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); }
/** * 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 (); }
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; }
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"); } }
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"); }
IO_METHOD(IoClutter, currentEventTime) { return IoDate_newWithTime_(IOSTATE, clutter_get_current_event_time()); }
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); }
//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; }
/** * 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; }