gboolean cinnamon_app_is_on_workspace (CinnamonApp *app, MetaWorkspace *workspace) { GSList *iter; if (cinnamon_app_get_state (app) == CINNAMON_APP_STATE_STARTING) { if (app->started_on_workspace == -1 || meta_workspace_index (workspace) == app->started_on_workspace) return TRUE; else return FALSE; } if (app->running_state == NULL) return FALSE; for (iter = app->running_state->windows; iter; iter = iter->next) { if (meta_window_get_workspace (iter->data) == workspace) return TRUE; } return FALSE; }
void _cinnamon_app_handle_startup_sequence (CinnamonApp *app, SnStartupSequence *sequence) { gboolean starting = !sn_startup_sequence_get_completed (sequence); /* The Cinnamon design calls for on application launch, the app title * appears at top, and no X window is focused. So when we get * a startup-notification for this app, transition it to STARTING * if it's currently stopped, set it as our application focus, * but focus the no_focus window. */ if (starting && cinnamon_app_get_state (app) == CINNAMON_APP_STATE_STOPPED) { MetaScreen *screen = cinnamon_global_get_screen (cinnamon_global_get ()); MetaDisplay *display = meta_screen_get_display (screen); cinnamon_app_state_transition (app, CINNAMON_APP_STATE_STARTING); meta_display_focus_the_no_focus_window (display, screen, sn_startup_sequence_get_timestamp (sequence)); app->started_on_workspace = sn_startup_sequence_get_workspace (sequence); } if (!starting) { if (app->running_state && app->running_state->windows) cinnamon_app_state_transition (app, CINNAMON_APP_STATE_RUNNING); else /* application have > 1 .desktop file */ cinnamon_app_state_transition (app, CINNAMON_APP_STATE_STOPPED); } }
void _cinnamon_app_system_notify_app_state_changed (CinnamonAppSystem *self, CinnamonApp *app) { CinnamonAppState state = cinnamon_app_get_state (app); switch (state) { case CINNAMON_APP_STATE_RUNNING: g_hash_table_insert (self->priv->running_apps, g_object_ref (app), NULL); break; case CINNAMON_APP_STATE_STARTING: break; case CINNAMON_APP_STATE_STOPPED: g_hash_table_remove (self->priv->running_apps, app); break; } g_signal_emit (self, signals[APP_STATE_CHANGED], 0, app); }
/** * cinnamon_app_request_quit: * @app: A #CinnamonApp * * Initiate an asynchronous request to quit this application. * The application may interact with the user, and the user * might cancel the quit request from the application UI. * * This operation may not be supported for all applications. * * Returns: %TRUE if a quit request is supported for this application */ gboolean cinnamon_app_request_quit (CinnamonApp *app) { GSList *iter; if (cinnamon_app_get_state (app) != CINNAMON_APP_STATE_RUNNING) return FALSE; /* TODO - check for an XSMP connection; we could probably use that */ for (iter = app->running_state->windows; iter; iter = iter->next) { MetaWindow *win = iter->data; if (!cinnamon_window_tracker_is_window_interesting (win)) continue; meta_window_delete (win, cinnamon_global_get_current_time (cinnamon_global_get ())); } return TRUE; }
/** * cinnamon_app_activate_window: * @app: a #CinnamonApp * @window: (allow-none): Window to be focused * @timestamp: Event timestamp * * Bring all windows for the given app to the foreground, * but ensure that @window is on top. If @window is %NULL, * the window with the most recent user time for the app * will be used. * * This function has no effect if @app is not currently running. */ void cinnamon_app_activate_window (CinnamonApp *app, MetaWindow *window, guint32 timestamp) { GSList *windows; if (cinnamon_app_get_state (app) != CINNAMON_APP_STATE_RUNNING) return; windows = cinnamon_app_get_windows (app); if (window == NULL && windows) window = windows->data; if (!g_slist_find (windows, window)) return; else { GSList *iter; CinnamonGlobal *global = cinnamon_global_get (); MetaScreen *screen = cinnamon_global_get_screen (global); MetaDisplay *display = meta_screen_get_display (screen); MetaWorkspace *active = meta_screen_get_active_workspace (screen); MetaWorkspace *workspace = meta_window_get_workspace (window); guint32 last_user_timestamp = meta_display_get_last_user_time (display); MetaWindow *most_recent_transient; if (meta_display_xserver_time_is_before (display, timestamp, last_user_timestamp)) { meta_window_set_demands_attention (window); return; } /* Now raise all the other windows for the app that are on * the same workspace, in reverse order to preserve the stacking. */ for (iter = windows; iter; iter = iter->next) { MetaWindow *other_window = iter->data; if (other_window != window) meta_window_raise (other_window); } /* If we have a transient that the user's interacted with more recently than * the window, pick that. */ most_recent_transient = find_most_recent_transient_on_same_workspace (display, window); if (most_recent_transient && meta_display_xserver_time_is_before (display, meta_window_get_user_time (window), meta_window_get_user_time (most_recent_transient))) window = most_recent_transient; if (!cinnamon_window_tracker_is_window_interesting (window)) { /* We won't get notify::user-time signals for uninteresting windows, * which means that an app's last_user_time won't get updated. * Update it here instead. */ app->running_state->last_user_time = timestamp; } if (active != workspace) meta_workspace_activate_with_focus (workspace, window, timestamp); else meta_window_activate (window, timestamp); } }