Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
|
2009-11-24 14:07:40 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2011-03-05 15:49:24 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2011-03-15 22:34:51 +00:00
|
|
|
#include <glib/gi18n-lib.h>
|
|
|
|
|
2011-03-05 15:49:24 +00:00
|
|
|
#include <meta/display.h>
|
2018-01-03 07:55:38 +00:00
|
|
|
#include <meta/meta-workspace-manager.h>
|
|
|
|
#include <meta/meta-x11-display.h>
|
2011-03-05 15:49:24 +00:00
|
|
|
|
2009-10-15 23:28:29 +00:00
|
|
|
#include "shell-app-private.h"
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
#include "shell-enum-types.h"
|
2011-03-05 15:49:24 +00:00
|
|
|
#include "shell-global.h"
|
2011-08-10 16:58:40 +00:00
|
|
|
#include "shell-util.h"
|
apps: Ensure running apps override new .desktop file data
This patch fixes the "apps vanish from alt-TAB bug".
If a "package system" rips away and possibly replaces .desktop files
at some random time, we have historically used inotify to detect this
and reread state (in a racy way, but...). In GNOME 2, this was
generally not too problematic because the menu widget was totally
separate from the list of windows - and the data they operate on was
disjoint as well.
In GNOME 3 we unify these, and this creates architectural problems
because the windows are tied to the app.
What this patch tries to do is, when rereading the application state,
if we have a running application, we keep that app around instead of
making a new instance. This ensures we preserve any state such as the
set of open windows.
This requires moving the running state into ShellAppSystem. Adjust
callers as necessary, and while we're at it drop the unused "contexts"
stuff.
This is just a somewhat quick band-aid; a REAL fix would require us
having low-level control over application installation. As long as
we're on top of random broken tar+wget wrappers, it will be gross.
A slight future improvement to this patch would add an explicit
"merge" between the old and new data. I think probably we always keep
around the ShellApp corresponding to a given ID, but replace its
GMenuTreeEntry.
https://bugzilla.gnome.org/show_bug.cgi?id=657990
2011-09-03 14:32:06 +00:00
|
|
|
#include "shell-app-system-private.h"
|
2010-06-07 20:31:30 +00:00
|
|
|
#include "shell-window-tracker-private.h"
|
2011-03-05 15:49:24 +00:00
|
|
|
#include "st.h"
|
2013-05-09 19:00:40 +00:00
|
|
|
#include "gtkactionmuxer.h"
|
2014-09-16 10:05:52 +00:00
|
|
|
#include "org-gtk-application.h"
|
2019-10-24 12:39:25 +00:00
|
|
|
#include "switcheroo-control.h"
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
2013-11-07 17:34:57 +00:00
|
|
|
#ifdef HAVE_SYSTEMD
|
|
|
|
#include <systemd/sd-journal.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
/* This is mainly a memory usage optimization - the user is going to
|
|
|
|
* be running far fewer of the applications at one time than they have
|
|
|
|
* installed. But it also just helps keep the code more logically
|
|
|
|
* separated.
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
guint refcount;
|
|
|
|
|
|
|
|
/* Signal connection to dirty window sort list on workspace changes */
|
2019-11-21 22:00:53 +00:00
|
|
|
gulong workspace_switch_id;
|
2010-06-09 18:50:01 +00:00
|
|
|
|
|
|
|
GSList *windows;
|
|
|
|
|
2014-01-22 16:51:25 +00:00
|
|
|
guint interesting_windows;
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
/* Whether or not we need to resort the windows; this is done on demand */
|
2013-11-04 21:04:20 +00:00
|
|
|
guint window_sort_stale : 1;
|
2011-05-10 16:29:52 +00:00
|
|
|
|
|
|
|
/* See GApplication documentation */
|
2013-05-09 19:00:40 +00:00
|
|
|
GtkActionMuxer *muxer;
|
2013-04-03 18:15:17 +00:00
|
|
|
char *unique_bus_name;
|
|
|
|
GDBusConnection *session;
|
2014-09-16 10:05:52 +00:00
|
|
|
|
|
|
|
/* GDBus Proxy for getting application busy state */
|
|
|
|
ShellOrgGtkApplication *application_proxy;
|
|
|
|
GCancellable *cancellable;
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
} ShellAppRunningState;
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
/**
|
|
|
|
* SECTION:shell-app
|
|
|
|
* @short_description: Object representing an application
|
|
|
|
*
|
2013-02-09 03:52:25 +00:00
|
|
|
* This object wraps a #GDesktopAppInfo, providing methods and signals
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
* primarily useful for running applications.
|
|
|
|
*/
|
|
|
|
struct _ShellApp
|
|
|
|
{
|
|
|
|
GObject parent;
|
|
|
|
|
2010-10-06 21:31:22 +00:00
|
|
|
int started_on_workspace;
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
ShellAppState state;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
2013-02-09 03:52:25 +00:00
|
|
|
GDesktopAppInfo *info; /* If NULL, this app is backed by one or more
|
2011-08-11 10:34:09 +00:00
|
|
|
* MetaWindow. For purposes of app title
|
|
|
|
* etc., we use the first window added,
|
|
|
|
* because it's most likely to be what we
|
|
|
|
* want (e.g. it will be of TYPE_NORMAL from
|
|
|
|
* the way shell-window-tracker.c works).
|
|
|
|
*/
|
2020-06-30 14:53:50 +00:00
|
|
|
GIcon *fallback_icon;
|
2021-12-15 15:03:52 +00:00
|
|
|
MetaWindow *fallback_icon_window;
|
2010-03-12 20:57:01 +00:00
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
ShellAppRunningState *running_state;
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
|
|
|
|
char *window_id_string;
|
|
|
|
char *name_collation_key;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
};
|
|
|
|
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
enum {
|
|
|
|
PROP_0,
|
2011-05-10 16:29:52 +00:00
|
|
|
PROP_STATE,
|
2014-09-16 10:08:19 +00:00
|
|
|
PROP_BUSY,
|
2011-05-10 16:29:52 +00:00
|
|
|
PROP_ID,
|
|
|
|
PROP_DBUS_ID,
|
|
|
|
PROP_ACTION_GROUP,
|
2021-03-12 22:13:25 +00:00
|
|
|
PROP_ICON,
|
2016-07-06 17:56:47 +00:00
|
|
|
PROP_APP_INFO
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
};
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
enum {
|
|
|
|
WINDOWS_CHANGED,
|
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
|
|
|
static guint shell_app_signals[LAST_SIGNAL] = { 0 };
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
static void create_running_state (ShellApp *app);
|
|
|
|
static void unref_running_state (ShellAppRunningState *state);
|
2011-05-10 16:29:52 +00:00
|
|
|
|
|
|
|
G_DEFINE_TYPE (ShellApp, shell_app, G_TYPE_OBJECT)
|
2010-06-09 18:50:01 +00:00
|
|
|
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
static void
|
|
|
|
shell_app_get_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
ShellApp *app = SHELL_APP (gobject);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_STATE:
|
|
|
|
g_value_set_enum (value, app->state);
|
|
|
|
break;
|
2014-09-16 10:08:19 +00:00
|
|
|
case PROP_BUSY:
|
|
|
|
g_value_set_boolean (value, shell_app_get_busy (app));
|
|
|
|
break;
|
2011-05-10 16:29:52 +00:00
|
|
|
case PROP_ID:
|
|
|
|
g_value_set_string (value, shell_app_get_id (app));
|
|
|
|
break;
|
2021-03-12 22:13:25 +00:00
|
|
|
case PROP_ICON:
|
|
|
|
g_value_set_object (value, shell_app_get_icon (app));
|
|
|
|
break;
|
2011-05-10 16:29:52 +00:00
|
|
|
case PROP_ACTION_GROUP:
|
|
|
|
if (app->running_state)
|
2011-12-15 05:29:31 +00:00
|
|
|
g_value_set_object (value, app->running_state->muxer);
|
2011-05-10 16:29:52 +00:00
|
|
|
break;
|
2016-07-06 17:56:47 +00:00
|
|
|
case PROP_APP_INFO:
|
|
|
|
if (app->info)
|
|
|
|
g_value_set_object (value, app->info);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
shell_app_set_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
ShellApp *app = SHELL_APP (gobject);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_APP_INFO:
|
|
|
|
_shell_app_set_app_info (app, g_value_get_object (value));
|
|
|
|
break;
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
const char *
|
|
|
|
shell_app_get_id (ShellApp *app)
|
|
|
|
{
|
2013-02-09 03:52:25 +00:00
|
|
|
if (app->info)
|
|
|
|
return g_app_info_get_id (G_APP_INFO (app->info));
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
return app->window_id_string;
|
|
|
|
}
|
|
|
|
|
|
|
|
static MetaWindow *
|
|
|
|
window_backed_app_get_window (ShellApp *app)
|
|
|
|
{
|
2013-02-09 03:52:25 +00:00
|
|
|
g_assert (app->info == NULL);
|
2015-10-08 02:56:11 +00:00
|
|
|
if (app->running_state)
|
|
|
|
{
|
|
|
|
g_assert (app->running_state->windows);
|
|
|
|
return app->running_state->windows->data;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return NULL;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
2021-03-12 22:10:42 +00:00
|
|
|
static GIcon *
|
|
|
|
x11_window_create_fallback_gicon (MetaWindow *window)
|
|
|
|
{
|
|
|
|
StTextureCache *texture_cache;
|
|
|
|
cairo_surface_t *surface;
|
|
|
|
|
|
|
|
g_object_get (window, "icon", &surface, NULL);
|
|
|
|
|
|
|
|
texture_cache = st_texture_cache_get_default ();
|
|
|
|
return st_texture_cache_load_cairo_surface_to_gicon (texture_cache, surface);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
on_window_icon_changed (GObject *object,
|
|
|
|
const GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
MetaWindow *window = META_WINDOW (object);
|
|
|
|
ShellApp *app = user_data;
|
|
|
|
|
|
|
|
g_clear_object (&app->fallback_icon);
|
|
|
|
app->fallback_icon = x11_window_create_fallback_gicon (window);
|
|
|
|
|
2021-12-15 15:03:52 +00:00
|
|
|
if (!app->fallback_icon)
|
|
|
|
app->fallback_icon = g_themed_icon_new ("application-x-executable");
|
|
|
|
|
2021-03-12 22:10:42 +00:00
|
|
|
g_object_notify (G_OBJECT (app), "icon");
|
|
|
|
}
|
|
|
|
|
2020-06-30 14:53:50 +00:00
|
|
|
/**
|
|
|
|
* shell_app_get_icon:
|
|
|
|
*
|
|
|
|
* Look up the icon for this application
|
|
|
|
*
|
|
|
|
* Return value: (transfer none): A #GIcon
|
|
|
|
*/
|
|
|
|
GIcon *
|
|
|
|
shell_app_get_icon (ShellApp *app)
|
2011-08-11 09:56:00 +00:00
|
|
|
{
|
2015-10-08 02:56:11 +00:00
|
|
|
MetaWindow *window = NULL;
|
2011-08-23 16:03:56 +00:00
|
|
|
|
2020-06-30 14:53:50 +00:00
|
|
|
g_return_val_if_fail (SHELL_IS_APP (app), NULL);
|
|
|
|
|
|
|
|
if (app->info)
|
|
|
|
return g_app_info_get_icon (G_APP_INFO (app->info));
|
|
|
|
|
|
|
|
if (app->fallback_icon)
|
|
|
|
return app->fallback_icon;
|
|
|
|
|
2011-08-23 16:03:56 +00:00
|
|
|
/* During a state transition from running to not-running for
|
|
|
|
* window-backend apps, it's possible we get a request for the icon.
|
2020-06-30 14:48:16 +00:00
|
|
|
* Avoid asserting here and just return a fallback icon
|
2011-08-23 16:03:56 +00:00
|
|
|
*/
|
2015-10-08 02:56:11 +00:00
|
|
|
if (app->running_state != NULL)
|
|
|
|
window = window_backed_app_get_window (app);
|
|
|
|
|
2020-06-30 14:48:16 +00:00
|
|
|
if (window &&
|
|
|
|
meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_X11)
|
2020-06-30 14:53:50 +00:00
|
|
|
{
|
2021-12-15 15:03:52 +00:00
|
|
|
app->fallback_icon_window = window;
|
2021-03-12 22:10:42 +00:00
|
|
|
app->fallback_icon = x11_window_create_fallback_gicon (window);
|
2021-12-15 15:03:52 +00:00
|
|
|
g_signal_connect (G_OBJECT (window),
|
|
|
|
"notify::icon", G_CALLBACK (on_window_icon_changed), app);
|
2020-06-30 14:53:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
app->fallback_icon = g_themed_icon_new ("application-x-executable");
|
|
|
|
}
|
|
|
|
|
|
|
|
return app->fallback_icon;
|
2011-08-11 09:56:00 +00:00
|
|
|
}
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
/**
|
|
|
|
* shell_app_create_icon_texture:
|
|
|
|
*
|
2019-11-12 18:43:38 +00:00
|
|
|
* Look up the icon for this application, and create a #ClutterActor
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
* for it at the given size.
|
|
|
|
*
|
|
|
|
* Return value: (transfer none): A floating #ClutterActor
|
|
|
|
*/
|
|
|
|
ClutterActor *
|
|
|
|
shell_app_create_icon_texture (ShellApp *app,
|
2011-08-11 09:44:19 +00:00
|
|
|
int size)
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
{
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
ClutterActor *ret;
|
|
|
|
|
2014-11-29 00:25:04 +00:00
|
|
|
ret = st_icon_new ();
|
|
|
|
st_icon_set_icon_size (ST_ICON (ret), size);
|
2015-03-14 22:44:54 +00:00
|
|
|
st_icon_set_fallback_icon_name (ST_ICON (ret), "application-x-executable");
|
2014-11-29 00:25:04 +00:00
|
|
|
|
2021-03-12 22:10:42 +00:00
|
|
|
g_object_bind_property (app, "icon", ret, "gicon", G_BINDING_SYNC_CREATE);
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
|
2020-06-30 14:53:50 +00:00
|
|
|
if (shell_app_is_window_backed (app))
|
|
|
|
st_widget_add_style_class_name (ST_WIDGET (ret), "fallback-app-icon");
|
|
|
|
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
return ret;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
|
|
|
|
const char *
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
shell_app_get_name (ShellApp *app)
|
|
|
|
{
|
2013-02-09 03:52:25 +00:00
|
|
|
if (app->info)
|
|
|
|
return g_app_info_get_name (G_APP_INFO (app->info));
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
MetaWindow *window = window_backed_app_get_window (app);
|
2015-10-08 02:56:11 +00:00
|
|
|
const char *name = NULL;
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
|
2015-10-08 02:56:11 +00:00
|
|
|
if (window)
|
|
|
|
name = meta_window_get_wm_class (window);
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
if (!name)
|
2012-06-01 12:44:40 +00:00
|
|
|
name = C_("program", "Unknown");
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
return name;
|
|
|
|
}
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
const char *
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
shell_app_get_description (ShellApp *app)
|
|
|
|
{
|
2013-02-09 03:52:25 +00:00
|
|
|
if (app->info)
|
|
|
|
return g_app_info_get_description (G_APP_INFO (app->info));
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
else
|
|
|
|
return NULL;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
/**
|
|
|
|
* shell_app_is_window_backed:
|
|
|
|
*
|
|
|
|
* A window backed application is one which represents just an open
|
2020-08-19 09:26:11 +00:00
|
|
|
* window, i.e. there's no .desktop file association, so we don't know
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
* how to launch it again.
|
|
|
|
*/
|
2009-10-14 21:25:17 +00:00
|
|
|
gboolean
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
shell_app_is_window_backed (ShellApp *app)
|
2009-10-14 21:25:17 +00:00
|
|
|
{
|
2013-02-09 03:52:25 +00:00
|
|
|
return app->info == NULL;
|
2009-10-14 21:25:17 +00:00
|
|
|
}
|
|
|
|
|
2010-04-17 20:57:58 +00:00
|
|
|
typedef struct {
|
|
|
|
MetaWorkspace *workspace;
|
|
|
|
GSList **transients;
|
|
|
|
} CollectTransientsData;
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
collect_transients_on_workspace (MetaWindow *window,
|
|
|
|
gpointer datap)
|
|
|
|
{
|
|
|
|
CollectTransientsData *data = datap;
|
|
|
|
|
|
|
|
if (data->workspace && meta_window_get_workspace (window) != data->workspace)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
*data->transients = g_slist_prepend (*data->transients, window);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The basic idea here is that when we're targeting a window,
|
|
|
|
* if it has transients we want to pick the most recent one
|
|
|
|
* the user interacted with.
|
|
|
|
* This function makes raising GEdit with the file chooser
|
|
|
|
* open work correctly.
|
|
|
|
*/
|
|
|
|
static MetaWindow *
|
|
|
|
find_most_recent_transient_on_same_workspace (MetaDisplay *display,
|
|
|
|
MetaWindow *reference)
|
|
|
|
{
|
|
|
|
GSList *transients, *transients_sorted, *iter;
|
|
|
|
MetaWindow *result;
|
|
|
|
CollectTransientsData data;
|
|
|
|
|
|
|
|
transients = NULL;
|
|
|
|
data.workspace = meta_window_get_workspace (reference);
|
|
|
|
data.transients = &transients;
|
|
|
|
|
|
|
|
meta_window_foreach_transient (reference, collect_transients_on_workspace, &data);
|
|
|
|
|
|
|
|
transients_sorted = meta_display_sort_windows_by_stacking (display, transients);
|
|
|
|
/* Reverse this so we're top-to-bottom (yes, we should probably change the order
|
|
|
|
* returned from the sort_windows_by_stacking function)
|
|
|
|
*/
|
|
|
|
transients_sorted = g_slist_reverse (transients_sorted);
|
|
|
|
g_slist_free (transients);
|
|
|
|
transients = NULL;
|
|
|
|
|
|
|
|
result = NULL;
|
|
|
|
for (iter = transients_sorted; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
MetaWindow *window = iter->data;
|
|
|
|
MetaWindowType wintype = meta_window_get_window_type (window);
|
|
|
|
|
|
|
|
/* Don't want to focus UTILITY types, like the Gimp toolbars */
|
|
|
|
if (wintype == META_WINDOW_NORMAL ||
|
|
|
|
wintype == META_WINDOW_DIALOG)
|
|
|
|
{
|
|
|
|
result = window;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g_slist_free (transients_sorted);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-01-03 07:55:38 +00:00
|
|
|
static MetaWorkspace *
|
|
|
|
get_active_workspace (void)
|
|
|
|
{
|
|
|
|
ShellGlobal *global = shell_global_get ();
|
|
|
|
MetaDisplay *display = shell_global_get_display (global);
|
|
|
|
MetaWorkspaceManager *workspace_manager =
|
|
|
|
meta_display_get_workspace_manager (display);
|
|
|
|
|
|
|
|
return meta_workspace_manager_get_active_workspace (workspace_manager);
|
|
|
|
}
|
|
|
|
|
2010-04-17 20:57:58 +00:00
|
|
|
/**
|
|
|
|
* shell_app_activate_window:
|
|
|
|
* @app: a #ShellApp
|
2014-05-28 19:54:02 +00:00
|
|
|
* @window: (nullable): Window to be focused
|
2010-04-17 20:57:58 +00:00
|
|
|
* @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
|
|
|
|
shell_app_activate_window (ShellApp *app,
|
|
|
|
MetaWindow *window,
|
|
|
|
guint32 timestamp)
|
|
|
|
{
|
|
|
|
GSList *windows;
|
|
|
|
|
|
|
|
if (shell_app_get_state (app) != SHELL_APP_STATE_RUNNING)
|
|
|
|
return;
|
|
|
|
|
|
|
|
windows = shell_app_get_windows (app);
|
|
|
|
if (window == NULL && windows)
|
|
|
|
window = windows->data;
|
|
|
|
|
|
|
|
if (!g_slist_find (windows, window))
|
|
|
|
return;
|
|
|
|
else
|
|
|
|
{
|
2012-05-19 15:25:00 +00:00
|
|
|
GSList *windows_reversed, *iter;
|
2010-04-17 20:57:58 +00:00
|
|
|
ShellGlobal *global = shell_global_get ();
|
2018-01-03 07:55:38 +00:00
|
|
|
MetaDisplay *display = shell_global_get_display (global);
|
|
|
|
MetaWorkspace *active = get_active_workspace ();
|
2010-04-17 20:57:58 +00:00
|
|
|
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.
|
|
|
|
*/
|
2012-05-19 15:25:00 +00:00
|
|
|
windows_reversed = g_slist_copy (windows);
|
|
|
|
windows_reversed = g_slist_reverse (windows_reversed);
|
|
|
|
for (iter = windows_reversed; iter; iter = iter->next)
|
2010-04-17 20:57:58 +00:00
|
|
|
{
|
|
|
|
MetaWindow *other_window = iter->data;
|
|
|
|
|
2015-01-30 17:01:57 +00:00
|
|
|
if (other_window != window && meta_window_get_workspace (other_window) == workspace)
|
2010-04-17 20:57:58 +00:00
|
|
|
meta_window_raise (other_window);
|
|
|
|
}
|
2012-05-19 15:25:00 +00:00
|
|
|
g_slist_free (windows_reversed);
|
2010-04-17 20:57:58 +00:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
2011-04-27 15:12:08 +00:00
|
|
|
|
2010-04-17 20:57:58 +00:00
|
|
|
if (active != workspace)
|
|
|
|
meta_workspace_activate_with_focus (workspace, window, timestamp);
|
|
|
|
else
|
|
|
|
meta_window_activate (window, timestamp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-15 06:25:35 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
shell_app_update_window_actions (ShellApp *app, MetaWindow *window)
|
|
|
|
{
|
|
|
|
const char *object_path;
|
|
|
|
|
2012-01-17 20:13:47 +00:00
|
|
|
object_path = meta_window_get_gtk_window_object_path (window);
|
2011-12-15 06:25:35 +00:00
|
|
|
if (object_path != NULL)
|
|
|
|
{
|
|
|
|
GActionGroup *actions;
|
|
|
|
|
|
|
|
actions = g_object_get_data (G_OBJECT (window), "actions");
|
|
|
|
if (actions == NULL)
|
|
|
|
{
|
2013-04-03 18:15:17 +00:00
|
|
|
actions = G_ACTION_GROUP (g_dbus_action_group_get (app->running_state->session,
|
2012-01-17 20:13:47 +00:00
|
|
|
meta_window_get_gtk_unique_bus_name (window),
|
2011-12-15 06:25:35 +00:00
|
|
|
object_path));
|
|
|
|
g_object_set_data_full (G_OBJECT (window), "actions", actions, g_object_unref);
|
|
|
|
}
|
|
|
|
|
2014-02-13 21:32:48 +00:00
|
|
|
g_assert (app->running_state->muxer);
|
2013-05-09 19:00:40 +00:00
|
|
|
gtk_action_muxer_insert (app->running_state->muxer, "win", actions);
|
2011-12-15 06:25:35 +00:00
|
|
|
g_object_notify (G_OBJECT (app), "action-group");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
/**
|
|
|
|
* shell_app_activate:
|
|
|
|
* @app: a #ShellApp
|
2011-08-11 09:35:23 +00:00
|
|
|
*
|
|
|
|
* Like shell_app_activate_full(), but using the default workspace and
|
|
|
|
* event timestamp.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
shell_app_activate (ShellApp *app)
|
|
|
|
{
|
|
|
|
return shell_app_activate_full (app, -1, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* shell_app_activate_full:
|
|
|
|
* @app: a #ShellApp
|
2011-01-30 21:09:58 +00:00
|
|
|
* @workspace: launch on this workspace, or -1 for default. Ignored if
|
|
|
|
* activating an existing window
|
2011-08-11 09:35:23 +00:00
|
|
|
* @timestamp: Event timestamp
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
*
|
|
|
|
* Perform an appropriate default action for operating on this application,
|
|
|
|
* dependent on its current state. For example, if the application is not
|
2010-04-17 20:57:58 +00:00
|
|
|
* currently running, launch it. If it is running, activate the most
|
|
|
|
* recently used NORMAL window (or if that window has a transient, the most
|
|
|
|
* recently used transient for that window).
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
*/
|
|
|
|
void
|
2011-08-11 09:35:23 +00:00
|
|
|
shell_app_activate_full (ShellApp *app,
|
|
|
|
int workspace,
|
|
|
|
guint32 timestamp)
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
{
|
2011-08-12 03:19:39 +00:00
|
|
|
ShellGlobal *global;
|
|
|
|
|
|
|
|
global = shell_global_get ();
|
|
|
|
|
|
|
|
if (timestamp == 0)
|
|
|
|
timestamp = shell_global_get_current_time (global);
|
|
|
|
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
switch (app->state)
|
|
|
|
{
|
|
|
|
case SHELL_APP_STATE_STOPPED:
|
2011-03-15 22:34:51 +00:00
|
|
|
{
|
|
|
|
GError *error = NULL;
|
2020-04-29 09:20:40 +00:00
|
|
|
if (!shell_app_launch (app, timestamp, workspace, SHELL_APP_LAUNCH_GPU_APP_PREF, &error))
|
2011-03-15 22:34:51 +00:00
|
|
|
{
|
|
|
|
char *msg;
|
2014-01-17 21:30:49 +00:00
|
|
|
msg = g_strdup_printf (_("Failed to launch “%s”"), shell_app_get_name (app));
|
2011-08-12 03:19:39 +00:00
|
|
|
shell_global_notify_error (global,
|
2011-03-15 22:34:51 +00:00
|
|
|
msg,
|
|
|
|
error->message);
|
|
|
|
g_free (msg);
|
|
|
|
g_clear_error (&error);
|
|
|
|
}
|
|
|
|
}
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
break;
|
|
|
|
case SHELL_APP_STATE_STARTING:
|
|
|
|
break;
|
|
|
|
case SHELL_APP_STATE_RUNNING:
|
2011-08-11 09:35:23 +00:00
|
|
|
shell_app_activate_window (app, NULL, timestamp);
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
break;
|
2015-09-23 17:10:16 +00:00
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
|
|
|
break;
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* shell_app_open_new_window:
|
|
|
|
* @app: a #ShellApp
|
2011-01-30 21:09:58 +00:00
|
|
|
* @workspace: open on this workspace, or -1 for default
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
*
|
|
|
|
* Request that the application create a new window.
|
|
|
|
*/
|
|
|
|
void
|
2011-01-30 21:09:58 +00:00
|
|
|
shell_app_open_new_window (ShellApp *app,
|
|
|
|
int workspace)
|
2009-10-15 23:28:29 +00:00
|
|
|
{
|
2016-09-22 16:29:29 +00:00
|
|
|
GActionGroup *group = NULL;
|
|
|
|
const char * const *actions;
|
|
|
|
|
2013-02-09 03:52:25 +00:00
|
|
|
g_return_if_fail (app->info != NULL);
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
|
2016-09-22 16:29:29 +00:00
|
|
|
/* First check whether the application provides a "new-window" desktop
|
|
|
|
* action - it is a safe bet that it will open a new window, and activating
|
|
|
|
* it will trigger startup notification if necessary
|
|
|
|
*/
|
|
|
|
actions = g_desktop_app_info_list_actions (G_DESKTOP_APP_INFO (app->info));
|
|
|
|
|
|
|
|
if (g_strv_contains (actions, "new-window"))
|
|
|
|
{
|
|
|
|
shell_app_launch_action (app, "new-window", 0, workspace);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Next, check whether the app exports an explicit "new-window" action
|
|
|
|
* that we can activate on the bus - the muxer will add startup notification
|
|
|
|
* information to the platform data, so this should work just as well as
|
|
|
|
* desktop actions.
|
|
|
|
*/
|
|
|
|
group = app->running_state ? G_ACTION_GROUP (app->running_state->muxer)
|
|
|
|
: NULL;
|
|
|
|
|
|
|
|
if (group &&
|
|
|
|
g_action_group_has_action (group, "app.new-window") &&
|
|
|
|
g_action_group_get_action_parameter_type (group, "app.new-window") == NULL)
|
|
|
|
{
|
|
|
|
g_action_group_activate_action (group, "app.new-window", NULL);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Lastly, just always launch the application again, even if we know
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
* it was already running. For most applications this
|
|
|
|
* should have the effect of creating a new window, whether that's
|
|
|
|
* a second process (in the case of Calculator) or IPC to existing
|
|
|
|
* instance (Firefox). There are a few less-sensical cases such
|
2016-09-22 16:29:29 +00:00
|
|
|
* as say Pidgin.
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
*/
|
2020-04-29 09:20:40 +00:00
|
|
|
shell_app_launch (app, 0, workspace, SHELL_APP_LAUNCH_GPU_APP_PREF, NULL);
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
}
|
|
|
|
|
2014-01-19 17:05:16 +00:00
|
|
|
/**
|
|
|
|
* shell_app_can_open_new_window:
|
|
|
|
* @app: a #ShellApp
|
|
|
|
*
|
|
|
|
* Returns %TRUE if the app supports opening a new window through
|
|
|
|
* shell_app_open_new_window() (ie, if calling that function will
|
|
|
|
* result in actually opening a new window and not something else,
|
|
|
|
* like presenting the most recently active one)
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
shell_app_can_open_new_window (ShellApp *app)
|
|
|
|
{
|
|
|
|
ShellAppRunningState *state;
|
2018-10-04 17:11:05 +00:00
|
|
|
MetaWindow *window;
|
2019-08-06 11:19:59 +00:00
|
|
|
GDesktopAppInfo *desktop_info;
|
|
|
|
const char * const *desktop_actions;
|
2014-01-19 17:05:16 +00:00
|
|
|
|
2019-08-01 15:22:50 +00:00
|
|
|
/* Apps that are stopped can always open new windows, because
|
|
|
|
* activating them would open the first one; if they are starting,
|
|
|
|
* we cannot tell whether they can open additional windows until
|
|
|
|
* they are running */
|
|
|
|
if (app->state != SHELL_APP_STATE_RUNNING)
|
|
|
|
return app->state == SHELL_APP_STATE_STOPPED;
|
2014-01-19 17:05:16 +00:00
|
|
|
|
|
|
|
state = app->running_state;
|
|
|
|
|
|
|
|
/* If the app has an explicit new-window action, then it can
|
2016-09-22 16:29:29 +00:00
|
|
|
(or it should be able to) ...
|
2014-01-19 17:05:16 +00:00
|
|
|
*/
|
|
|
|
if (g_action_group_has_action (G_ACTION_GROUP (state->muxer), "app.new-window"))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* If the app doesn't have a desktop file, then nothing is possible */
|
|
|
|
if (!app->info)
|
|
|
|
return FALSE;
|
|
|
|
|
2019-08-06 11:19:59 +00:00
|
|
|
desktop_info = G_DESKTOP_APP_INFO (app->info);
|
|
|
|
|
2022-01-05 16:13:12 +00:00
|
|
|
/* If the app is explicitly telling us via its desktop file, then we know
|
|
|
|
* for sure
|
|
|
|
*/
|
|
|
|
if (g_desktop_app_info_has_key (desktop_info, "SingleMainWindow"))
|
|
|
|
return !g_desktop_app_info_get_boolean (desktop_info,
|
|
|
|
"SingleMainWindow");
|
|
|
|
|
|
|
|
/* GNOME-specific key, for backwards compatibility with apps that haven't
|
|
|
|
* started using the XDG "SingleMainWindow" key yet
|
|
|
|
*/
|
2019-08-06 11:19:59 +00:00
|
|
|
if (g_desktop_app_info_has_key (desktop_info, "X-GNOME-SingleWindow"))
|
|
|
|
return !g_desktop_app_info_get_boolean (desktop_info,
|
2014-01-19 17:05:16 +00:00
|
|
|
"X-GNOME-SingleWindow");
|
|
|
|
|
2019-08-06 11:19:59 +00:00
|
|
|
/* If it has a new-window desktop action, it should be able to */
|
|
|
|
desktop_actions = g_desktop_app_info_list_actions (desktop_info);
|
|
|
|
if (desktop_actions && g_strv_contains (desktop_actions, "new-window"))
|
|
|
|
return TRUE;
|
|
|
|
|
2014-01-19 17:05:16 +00:00
|
|
|
/* If this is a unique GtkApplication, and we don't have a new-window, then
|
|
|
|
probably we can't
|
|
|
|
|
|
|
|
We don't consider non-unique GtkApplications here to handle cases like
|
|
|
|
evince, which don't export a new-window action because each window is in
|
|
|
|
a different process. In any case, in a non-unique GtkApplication each
|
|
|
|
Activate() knows nothing about the other instances, so it will show a
|
|
|
|
new window.
|
|
|
|
*/
|
2018-10-04 17:11:05 +00:00
|
|
|
|
|
|
|
window = state->windows->data;
|
|
|
|
|
|
|
|
if (state->unique_bus_name != NULL &&
|
|
|
|
meta_window_get_gtk_application_object_path (window) != NULL)
|
2014-01-19 17:05:16 +00:00
|
|
|
{
|
2018-10-04 17:11:05 +00:00
|
|
|
if (meta_window_get_gtk_application_id (window) != NULL)
|
2014-01-19 17:05:16 +00:00
|
|
|
return FALSE;
|
|
|
|
else
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* In all other cases, we don't have a reliable source of information
|
|
|
|
or a decent heuristic, so we err on the compatibility side and say
|
|
|
|
yes.
|
|
|
|
*/
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
/**
|
|
|
|
* shell_app_get_state:
|
|
|
|
* @app: a #ShellApp
|
|
|
|
*
|
|
|
|
* Returns: State of the application
|
|
|
|
*/
|
|
|
|
ShellAppState
|
|
|
|
shell_app_get_state (ShellApp *app)
|
|
|
|
{
|
|
|
|
return app->state;
|
2009-10-15 23:28:29 +00:00
|
|
|
}
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
typedef struct {
|
|
|
|
ShellApp *app;
|
|
|
|
MetaWorkspace *active_workspace;
|
|
|
|
} CompareWindowsData;
|
|
|
|
|
|
|
|
static int
|
|
|
|
shell_app_compare_windows (gconstpointer a,
|
|
|
|
gconstpointer b,
|
|
|
|
gpointer datap)
|
|
|
|
{
|
|
|
|
MetaWindow *win_a = (gpointer)a;
|
|
|
|
MetaWindow *win_b = (gpointer)b;
|
|
|
|
CompareWindowsData *data = datap;
|
|
|
|
gboolean ws_a, ws_b;
|
|
|
|
gboolean vis_a, vis_b;
|
|
|
|
|
|
|
|
ws_a = meta_window_get_workspace (win_a) == data->active_workspace;
|
|
|
|
ws_b = meta_window_get_workspace (win_b) == data->active_workspace;
|
|
|
|
|
|
|
|
if (ws_a && !ws_b)
|
|
|
|
return -1;
|
|
|
|
else if (!ws_a && ws_b)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
vis_a = meta_window_showing_on_its_workspace (win_a);
|
|
|
|
vis_b = meta_window_showing_on_its_workspace (win_b);
|
|
|
|
|
|
|
|
if (vis_a && !vis_b)
|
|
|
|
return -1;
|
|
|
|
else if (!vis_a && vis_b)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return meta_window_get_user_time (win_b) - meta_window_get_user_time (win_a);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* shell_app_get_windows:
|
|
|
|
* @app:
|
|
|
|
*
|
2013-12-04 16:26:01 +00:00
|
|
|
* Get the windows which are associated with this application. The
|
|
|
|
* returned list will be sorted first by whether they're on the
|
|
|
|
* active workspace, then by whether they're visible, and finally
|
|
|
|
* by the time the user last interacted with them.
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
*
|
|
|
|
* Returns: (transfer none) (element-type MetaWindow): List of windows
|
|
|
|
*/
|
|
|
|
GSList *
|
|
|
|
shell_app_get_windows (ShellApp *app)
|
|
|
|
{
|
2010-06-09 18:50:01 +00:00
|
|
|
if (app->running_state == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (app->running_state->window_sort_stale)
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
{
|
|
|
|
CompareWindowsData data;
|
|
|
|
data.app = app;
|
2018-01-03 07:55:38 +00:00
|
|
|
data.active_workspace = get_active_workspace ();
|
2010-06-09 18:50:01 +00:00
|
|
|
app->running_state->windows = g_slist_sort_with_data (app->running_state->windows, shell_app_compare_windows, &data);
|
|
|
|
app->running_state->window_sort_stale = FALSE;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
return app->running_state->windows;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
2009-10-15 23:28:29 +00:00
|
|
|
guint
|
|
|
|
shell_app_get_n_windows (ShellApp *app)
|
|
|
|
{
|
2010-06-09 18:50:01 +00:00
|
|
|
if (app->running_state == NULL)
|
|
|
|
return 0;
|
|
|
|
return g_slist_length (app->running_state->windows);
|
2009-10-15 23:28:29 +00:00
|
|
|
}
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
gboolean
|
|
|
|
shell_app_is_on_workspace (ShellApp *app,
|
|
|
|
MetaWorkspace *workspace)
|
|
|
|
{
|
|
|
|
GSList *iter;
|
|
|
|
|
2010-10-06 21:31:22 +00:00
|
|
|
if (shell_app_get_state (app) == SHELL_APP_STATE_STARTING)
|
|
|
|
{
|
2010-12-17 20:01:19 +00:00
|
|
|
if (app->started_on_workspace == -1 ||
|
|
|
|
meta_workspace_index (workspace) == app->started_on_workspace)
|
2010-10-06 21:31:22 +00:00
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
if (app->running_state == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (iter = app->running_state->windows; iter; iter = iter->next)
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
{
|
|
|
|
if (meta_window_get_workspace (iter->data) == workspace)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2011-10-01 20:26:13 +00:00
|
|
|
static int
|
|
|
|
shell_app_get_last_user_time (ShellApp *app)
|
|
|
|
{
|
|
|
|
GSList *iter;
|
2015-09-23 17:11:05 +00:00
|
|
|
guint32 last_user_time;
|
2011-10-01 20:26:13 +00:00
|
|
|
|
|
|
|
last_user_time = 0;
|
|
|
|
|
|
|
|
if (app->running_state != NULL)
|
|
|
|
{
|
|
|
|
for (iter = app->running_state->windows; iter; iter = iter->next)
|
|
|
|
last_user_time = MAX (last_user_time, meta_window_get_user_time (iter->data));
|
|
|
|
}
|
|
|
|
|
2015-09-23 17:11:05 +00:00
|
|
|
return (int)last_user_time;
|
2011-10-01 20:26:13 +00:00
|
|
|
}
|
|
|
|
|
2016-05-10 19:15:36 +00:00
|
|
|
static gboolean
|
|
|
|
shell_app_is_minimized (ShellApp *app)
|
|
|
|
{
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
if (app->running_state == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (iter = app->running_state->windows; iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
if (meta_window_showing_on_its_workspace (iter->data))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
/**
|
|
|
|
* shell_app_compare:
|
|
|
|
* @app:
|
|
|
|
* @other: A #ShellApp
|
|
|
|
*
|
|
|
|
* Compare one #ShellApp instance to another, in the following way:
|
2010-05-11 15:55:33 +00:00
|
|
|
* - Running applications sort before not-running applications.
|
2016-05-10 19:15:36 +00:00
|
|
|
* - If one of them has non-minimized windows and the other does not,
|
|
|
|
* the one with visible windows is first.
|
|
|
|
* - Finally, the application which the user interacted with most recently
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
* compares earlier.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
shell_app_compare (ShellApp *app,
|
|
|
|
ShellApp *other)
|
|
|
|
{
|
2016-05-10 19:15:36 +00:00
|
|
|
gboolean min_app, min_other;
|
|
|
|
|
2010-05-11 15:55:33 +00:00
|
|
|
if (app->state != other->state)
|
|
|
|
{
|
|
|
|
if (app->state == SHELL_APP_STATE_RUNNING)
|
|
|
|
return -1;
|
|
|
|
return 1;
|
|
|
|
}
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
2016-05-10 19:15:36 +00:00
|
|
|
min_app = shell_app_is_minimized (app);
|
|
|
|
min_other = shell_app_is_minimized (other);
|
|
|
|
|
|
|
|
if (min_app != min_other)
|
|
|
|
{
|
|
|
|
if (min_other)
|
|
|
|
return -1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
if (app->state == SHELL_APP_STATE_RUNNING)
|
|
|
|
{
|
|
|
|
if (app->running_state->windows && !other->running_state->windows)
|
|
|
|
return -1;
|
|
|
|
else if (!app->running_state->windows && other->running_state->windows)
|
|
|
|
return 1;
|
2011-10-01 20:26:13 +00:00
|
|
|
|
|
|
|
return shell_app_get_last_user_time (other) - shell_app_get_last_user_time (app);
|
2010-06-09 18:50:01 +00:00
|
|
|
}
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
return 0;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ShellApp *
|
|
|
|
_shell_app_new_for_window (MetaWindow *window)
|
|
|
|
{
|
|
|
|
ShellApp *app;
|
|
|
|
|
|
|
|
app = g_object_new (SHELL_TYPE_APP, NULL);
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
|
2011-08-11 09:47:38 +00:00
|
|
|
app->window_id_string = g_strdup_printf ("window:%d", meta_window_get_stable_sequence (window));
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
_shell_app_add_window (app, window);
|
|
|
|
|
|
|
|
return app;
|
|
|
|
}
|
|
|
|
|
|
|
|
ShellApp *
|
2013-02-09 03:52:25 +00:00
|
|
|
_shell_app_new (GDesktopAppInfo *info)
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
{
|
|
|
|
ShellApp *app;
|
|
|
|
|
2016-07-06 17:56:47 +00:00
|
|
|
app = g_object_new (SHELL_TYPE_APP,
|
|
|
|
"app-info", info,
|
|
|
|
NULL);
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
|
|
|
return app;
|
|
|
|
}
|
|
|
|
|
2011-09-19 16:49:05 +00:00
|
|
|
void
|
2013-02-09 03:52:25 +00:00
|
|
|
_shell_app_set_app_info (ShellApp *app,
|
|
|
|
GDesktopAppInfo *info)
|
2011-09-19 16:49:05 +00:00
|
|
|
{
|
2016-07-06 17:56:47 +00:00
|
|
|
g_set_object (&app->info, info);
|
2013-02-09 03:52:25 +00:00
|
|
|
|
2016-07-06 17:56:47 +00:00
|
|
|
g_clear_pointer (&app->name_collation_key, g_free);
|
|
|
|
if (app->info)
|
|
|
|
app->name_collation_key = g_utf8_collate_key (shell_app_get_name (app), -1);
|
2011-09-19 16:49:05 +00:00
|
|
|
}
|
|
|
|
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
static void
|
|
|
|
shell_app_state_transition (ShellApp *app,
|
|
|
|
ShellAppState state)
|
|
|
|
{
|
|
|
|
if (app->state == state)
|
|
|
|
return;
|
|
|
|
g_return_if_fail (!(app->state == SHELL_APP_STATE_RUNNING &&
|
|
|
|
state == SHELL_APP_STATE_STARTING));
|
|
|
|
app->state = state;
|
2010-06-09 18:50:01 +00:00
|
|
|
|
apps: Ensure running apps override new .desktop file data
This patch fixes the "apps vanish from alt-TAB bug".
If a "package system" rips away and possibly replaces .desktop files
at some random time, we have historically used inotify to detect this
and reread state (in a racy way, but...). In GNOME 2, this was
generally not too problematic because the menu widget was totally
separate from the list of windows - and the data they operate on was
disjoint as well.
In GNOME 3 we unify these, and this creates architectural problems
because the windows are tied to the app.
What this patch tries to do is, when rereading the application state,
if we have a running application, we keep that app around instead of
making a new instance. This ensures we preserve any state such as the
set of open windows.
This requires moving the running state into ShellAppSystem. Adjust
callers as necessary, and while we're at it drop the unused "contexts"
stuff.
This is just a somewhat quick band-aid; a REAL fix would require us
having low-level control over application installation. As long as
we're on top of random broken tar+wget wrappers, it will be gross.
A slight future improvement to this patch would add an explicit
"merge" between the old and new data. I think probably we always keep
around the ShellApp corresponding to a given ID, but replace its
GMenuTreeEntry.
https://bugzilla.gnome.org/show_bug.cgi?id=657990
2011-09-03 14:32:06 +00:00
|
|
|
_shell_app_system_notify_app_state_changed (shell_app_system_get_default (), app);
|
2010-06-09 18:50:01 +00:00
|
|
|
|
|
|
|
g_object_notify (G_OBJECT (app), "state");
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
}
|
|
|
|
|
2009-10-16 14:50:33 +00:00
|
|
|
static void
|
|
|
|
shell_app_on_user_time_changed (MetaWindow *window,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
ShellApp *app)
|
|
|
|
{
|
2010-06-09 18:50:01 +00:00
|
|
|
g_assert (app->running_state != NULL);
|
|
|
|
|
2009-10-16 14:50:33 +00:00
|
|
|
/* Ideally we don't want to emit windows-changed if the sort order
|
|
|
|
* isn't actually changing. This check catches most of those.
|
|
|
|
*/
|
2010-06-09 18:50:01 +00:00
|
|
|
if (window != app->running_state->windows->data)
|
2009-10-16 14:50:33 +00:00
|
|
|
{
|
2010-06-09 18:50:01 +00:00
|
|
|
app->running_state->window_sort_stale = TRUE;
|
2009-10-16 14:50:33 +00:00
|
|
|
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 16:33:36 +00:00
|
|
|
static void
|
2014-01-31 12:46:12 +00:00
|
|
|
shell_app_sync_running_state (ShellApp *app)
|
2014-01-30 16:33:36 +00:00
|
|
|
{
|
|
|
|
g_return_if_fail (app->running_state != NULL);
|
|
|
|
|
2015-07-16 22:20:23 +00:00
|
|
|
if (app->state != SHELL_APP_STATE_STARTING)
|
|
|
|
{
|
|
|
|
if (app->running_state->interesting_windows == 0)
|
|
|
|
shell_app_state_transition (app, SHELL_APP_STATE_STOPPED);
|
|
|
|
else
|
|
|
|
shell_app_state_transition (app, SHELL_APP_STATE_RUNNING);
|
|
|
|
}
|
2014-01-30 16:33:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
shell_app_on_skip_taskbar_changed (MetaWindow *window,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
ShellApp *app)
|
|
|
|
{
|
|
|
|
g_assert (app->running_state != NULL);
|
|
|
|
|
2014-01-31 12:46:12 +00:00
|
|
|
/* we rely on MetaWindow:skip-taskbar only being notified
|
|
|
|
* when it actually changes; when that assumption breaks,
|
|
|
|
* we'll have to track the "interesting" windows themselves
|
|
|
|
*/
|
2014-01-30 16:33:36 +00:00
|
|
|
if (meta_window_is_skip_taskbar (window))
|
|
|
|
app->running_state->interesting_windows--;
|
|
|
|
else
|
|
|
|
app->running_state->interesting_windows++;
|
|
|
|
|
2014-01-31 12:46:12 +00:00
|
|
|
shell_app_sync_running_state (app);
|
2014-01-30 16:33:36 +00:00
|
|
|
}
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
static void
|
2018-01-03 07:55:38 +00:00
|
|
|
shell_app_on_ws_switch (MetaWorkspaceManager *workspace_manager,
|
|
|
|
int from,
|
|
|
|
int to,
|
|
|
|
MetaMotionDirection direction,
|
|
|
|
gpointer data)
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
{
|
2010-06-09 18:50:01 +00:00
|
|
|
ShellApp *app = SHELL_APP (data);
|
|
|
|
|
|
|
|
g_assert (app->running_state != NULL);
|
|
|
|
|
|
|
|
app->running_state->window_sort_stale = TRUE;
|
|
|
|
|
|
|
|
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
2014-09-16 10:08:19 +00:00
|
|
|
gboolean
|
|
|
|
shell_app_get_busy (ShellApp *app)
|
|
|
|
{
|
|
|
|
if (app->running_state != NULL &&
|
|
|
|
app->running_state->application_proxy != NULL &&
|
|
|
|
shell_org_gtk_application_get_busy (app->running_state->application_proxy))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2013-04-03 18:16:58 +00:00
|
|
|
static void
|
2014-09-16 10:05:52 +00:00
|
|
|
busy_changed_cb (GObject *object,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
2013-04-03 18:16:58 +00:00
|
|
|
{
|
|
|
|
ShellApp *app = user_data;
|
|
|
|
|
2014-09-16 10:05:52 +00:00
|
|
|
g_assert (SHELL_IS_APP (app));
|
2013-04-03 18:16:58 +00:00
|
|
|
|
2014-09-16 10:08:19 +00:00
|
|
|
g_object_notify (G_OBJECT (app), "busy");
|
2014-09-16 10:05:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
get_application_proxy (GObject *source,
|
|
|
|
GAsyncResult *result,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
ShellApp *app = user_data;
|
|
|
|
ShellOrgGtkApplication *proxy;
|
2020-12-13 17:57:44 +00:00
|
|
|
g_autoptr (GError) error = NULL;
|
2014-09-16 10:05:52 +00:00
|
|
|
|
|
|
|
g_assert (SHELL_IS_APP (app));
|
|
|
|
|
2020-12-13 17:57:44 +00:00
|
|
|
proxy = shell_org_gtk_application_proxy_new_finish (result, &error);
|
2014-09-16 10:05:52 +00:00
|
|
|
if (proxy != NULL)
|
|
|
|
{
|
|
|
|
app->running_state->application_proxy = proxy;
|
|
|
|
g_signal_connect (proxy,
|
|
|
|
"notify::busy",
|
|
|
|
G_CALLBACK (busy_changed_cb),
|
|
|
|
app);
|
|
|
|
if (shell_org_gtk_application_get_busy (proxy))
|
2014-09-16 10:08:19 +00:00
|
|
|
g_object_notify (G_OBJECT (app), "busy");
|
2014-09-16 10:05:52 +00:00
|
|
|
}
|
2013-04-03 18:16:58 +00:00
|
|
|
|
2020-12-13 17:57:44 +00:00
|
|
|
if (app->running_state != NULL &&
|
|
|
|
!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
2014-09-16 10:05:52 +00:00
|
|
|
g_clear_object (&app->running_state->cancellable);
|
|
|
|
|
|
|
|
g_object_unref (app);
|
2013-04-03 18:16:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
shell_app_ensure_busy_watch (ShellApp *app)
|
|
|
|
{
|
|
|
|
ShellAppRunningState *running_state = app->running_state;
|
|
|
|
MetaWindow *window;
|
|
|
|
const gchar *object_path;
|
|
|
|
|
2014-09-16 10:05:52 +00:00
|
|
|
if (running_state->application_proxy != NULL ||
|
|
|
|
running_state->cancellable != NULL)
|
2013-04-03 18:16:58 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (running_state->unique_bus_name == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
window = g_slist_nth_data (running_state->windows, 0);
|
|
|
|
object_path = meta_window_get_gtk_application_object_path (window);
|
|
|
|
|
|
|
|
if (object_path == NULL)
|
|
|
|
return;
|
|
|
|
|
2014-09-16 10:05:52 +00:00
|
|
|
running_state->cancellable = g_cancellable_new();
|
|
|
|
/* Take a reference to app to make sure it isn't finalized before
|
|
|
|
get_application_proxy runs */
|
|
|
|
shell_org_gtk_application_proxy_new (running_state->session,
|
|
|
|
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
|
|
|
running_state->unique_bus_name,
|
|
|
|
object_path,
|
|
|
|
running_state->cancellable,
|
|
|
|
get_application_proxy,
|
|
|
|
g_object_ref (app));
|
2013-04-03 18:16:58 +00:00
|
|
|
}
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
void
|
|
|
|
_shell_app_add_window (ShellApp *app,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
2010-06-09 18:50:01 +00:00
|
|
|
if (app->running_state && g_slist_find (app->running_state->windows, window))
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
return;
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
g_object_freeze_notify (G_OBJECT (app));
|
2010-05-11 15:55:33 +00:00
|
|
|
|
2010-10-06 21:30:30 +00:00
|
|
|
if (!app->running_state)
|
|
|
|
create_running_state (app);
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
app->running_state->window_sort_stale = TRUE;
|
|
|
|
app->running_state->windows = g_slist_prepend (app->running_state->windows, g_object_ref (window));
|
2019-04-16 22:59:58 +00:00
|
|
|
g_signal_connect_object (window, "notify::user-time", G_CALLBACK(shell_app_on_user_time_changed), app, 0);
|
|
|
|
g_signal_connect_object (window, "notify::skip-taskbar", G_CALLBACK(shell_app_on_skip_taskbar_changed), app, 0);
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
2018-10-04 17:20:40 +00:00
|
|
|
shell_app_update_app_actions (app, window);
|
2013-04-03 18:16:58 +00:00
|
|
|
shell_app_ensure_busy_watch (app);
|
2012-01-17 20:13:47 +00:00
|
|
|
|
2014-01-30 17:04:18 +00:00
|
|
|
if (!meta_window_is_skip_taskbar (window))
|
2014-01-22 16:51:25 +00:00
|
|
|
app->running_state->interesting_windows++;
|
2014-01-31 12:46:12 +00:00
|
|
|
shell_app_sync_running_state (app);
|
2010-11-07 19:51:25 +00:00
|
|
|
|
2021-10-30 11:21:17 +00:00
|
|
|
if (app->started_on_workspace >= 0 && !meta_window_is_on_all_workspaces (window))
|
2021-03-07 15:57:44 +00:00
|
|
|
meta_window_change_workspace_by_index (window, app->started_on_workspace, FALSE);
|
|
|
|
app->started_on_workspace = -1;
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
g_object_thaw_notify (G_OBJECT (app));
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_shell_app_remove_window (ShellApp *app,
|
|
|
|
MetaWindow *window)
|
|
|
|
{
|
2010-06-20 20:46:21 +00:00
|
|
|
g_assert (app->running_state != NULL);
|
2010-06-09 18:50:01 +00:00
|
|
|
|
|
|
|
if (!g_slist_find (app->running_state->windows, window))
|
2009-10-23 17:15:13 +00:00
|
|
|
return;
|
|
|
|
|
2021-12-15 15:03:52 +00:00
|
|
|
app->running_state->windows = g_slist_remove (app->running_state->windows, window);
|
|
|
|
|
2021-12-22 00:53:17 +00:00
|
|
|
if (!meta_window_is_skip_taskbar (window))
|
|
|
|
app->running_state->interesting_windows--;
|
|
|
|
shell_app_sync_running_state (app);
|
|
|
|
|
|
|
|
if (app->running_state->windows == NULL)
|
|
|
|
g_clear_pointer (&app->running_state, unref_running_state);
|
|
|
|
|
2009-10-20 21:43:51 +00:00
|
|
|
g_signal_handlers_disconnect_by_func (window, G_CALLBACK(shell_app_on_user_time_changed), app);
|
2014-01-30 16:33:36 +00:00
|
|
|
g_signal_handlers_disconnect_by_func (window, G_CALLBACK(shell_app_on_skip_taskbar_changed), app);
|
2021-12-15 15:03:52 +00:00
|
|
|
if (window == app->fallback_icon_window)
|
|
|
|
{
|
|
|
|
g_signal_handlers_disconnect_by_func (window, G_CALLBACK(on_window_icon_changed), app);
|
|
|
|
app->fallback_icon_window = NULL;
|
2009-10-20 21:43:51 +00:00
|
|
|
|
2021-12-15 15:03:52 +00:00
|
|
|
/* Select a new icon from a different window. */
|
|
|
|
g_clear_object (&app->fallback_icon);
|
|
|
|
g_object_notify (G_OBJECT (app), "icon");
|
|
|
|
}
|
2021-03-12 22:10:42 +00:00
|
|
|
|
2021-03-13 23:10:56 +00:00
|
|
|
g_object_unref (window);
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0);
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
}
|
|
|
|
|
2010-05-24 14:59:52 +00:00
|
|
|
/**
|
|
|
|
* shell_app_get_pids:
|
|
|
|
* @app: a #ShellApp
|
|
|
|
*
|
2019-06-15 09:29:53 +00:00
|
|
|
* Returns: (transfer container) (element-type int): An unordered list of process identifiers associated with this application.
|
2010-05-24 14:59:52 +00:00
|
|
|
*/
|
|
|
|
GSList *
|
|
|
|
shell_app_get_pids (ShellApp *app)
|
|
|
|
{
|
|
|
|
GSList *result;
|
|
|
|
GSList *iter;
|
|
|
|
|
|
|
|
result = NULL;
|
|
|
|
for (iter = shell_app_get_windows (app); iter; iter = iter->next)
|
|
|
|
{
|
|
|
|
MetaWindow *window = iter->data;
|
2020-04-08 14:23:11 +00:00
|
|
|
pid_t pid = meta_window_get_pid (window);
|
2020-04-06 18:31:46 +00:00
|
|
|
|
|
|
|
if (pid < 1)
|
|
|
|
continue;
|
|
|
|
|
2010-05-24 14:59:52 +00:00
|
|
|
/* Note in the (by far) common case, app will only have one pid, so
|
|
|
|
* we'll hit the first element, so don't worry about O(N^2) here.
|
|
|
|
*/
|
|
|
|
if (!g_slist_find (result, GINT_TO_POINTER (pid)))
|
|
|
|
result = g_slist_prepend (result, GINT_TO_POINTER (pid));
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
void
|
2018-08-22 22:00:36 +00:00
|
|
|
_shell_app_handle_startup_sequence (ShellApp *app,
|
|
|
|
MetaStartupSequence *sequence)
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
{
|
2018-08-22 22:00:36 +00:00
|
|
|
gboolean starting = !meta_startup_sequence_get_completed (sequence);
|
2010-10-06 21:30:30 +00:00
|
|
|
|
|
|
|
/* The Shell 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 && shell_app_get_state (app) == SHELL_APP_STATE_STOPPED)
|
|
|
|
{
|
2018-01-03 07:55:38 +00:00
|
|
|
MetaDisplay *display = shell_global_get_display (shell_global_get ());
|
2010-10-06 21:30:30 +00:00
|
|
|
|
|
|
|
shell_app_state_transition (app, SHELL_APP_STATE_STARTING);
|
2019-01-08 16:14:24 +00:00
|
|
|
meta_display_unset_input_focus (display,
|
|
|
|
meta_startup_sequence_get_timestamp (sequence));
|
2010-10-06 21:30:30 +00:00
|
|
|
}
|
|
|
|
|
2020-06-15 18:41:45 +00:00
|
|
|
if (starting)
|
|
|
|
app->started_on_workspace = meta_startup_sequence_get_workspace (sequence);
|
|
|
|
else if (app->running_state && app->running_state->windows)
|
|
|
|
shell_app_state_transition (app, SHELL_APP_STATE_RUNNING);
|
|
|
|
else /* application have > 1 .desktop file */
|
|
|
|
shell_app_state_transition (app, SHELL_APP_STATE_STOPPED);
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
2010-03-24 13:42:59 +00:00
|
|
|
/**
|
|
|
|
* shell_app_request_quit:
|
|
|
|
* @app: A #ShellApp
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
shell_app_request_quit (ShellApp *app)
|
|
|
|
{
|
2019-02-05 01:32:52 +00:00
|
|
|
GActionGroup *group = NULL;
|
2010-03-24 13:42:59 +00:00
|
|
|
GSList *iter;
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
if (shell_app_get_state (app) != SHELL_APP_STATE_RUNNING)
|
|
|
|
return FALSE;
|
|
|
|
|
2019-02-05 01:32:52 +00:00
|
|
|
/* First, check whether the app exports an explicit "quit" action
|
|
|
|
* that we can activate on the bus
|
|
|
|
*/
|
|
|
|
group = G_ACTION_GROUP (app->running_state->muxer);
|
|
|
|
|
|
|
|
if (g_action_group_has_action (group, "app.quit") &&
|
|
|
|
g_action_group_get_action_parameter_type (group, "app.quit") == NULL)
|
|
|
|
{
|
|
|
|
g_action_group_activate_action (group, "app.quit", NULL);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2010-03-24 13:42:59 +00:00
|
|
|
|
2019-02-05 01:32:52 +00:00
|
|
|
/* Otherwise, fall back to closing all the app's windows */
|
2010-06-09 18:50:01 +00:00
|
|
|
for (iter = app->running_state->windows; iter; iter = iter->next)
|
2010-03-24 13:42:59 +00:00
|
|
|
{
|
|
|
|
MetaWindow *win = iter->data;
|
|
|
|
|
2018-09-03 15:10:27 +00:00
|
|
|
if (!meta_window_can_close (win))
|
2010-03-24 13:42:59 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
meta_window_delete (win, shell_global_get_current_time (shell_global_get ()));
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
shell-app: remove child_setup from app launching
When the amount of free memory on the system is somewhat low, gnome-shell
will sometimes fail to launch apps, reporting the error:
fork(): Cannot allocate memory
fork() is failing here because while cloning the process virtual address
space, Linux worries that the thread being forked may end up COWing the
entire address space of the parent process (gnome-shell, which is
memory-hungry), and there is not enough free memory to permit that to
happen. This check is somewhat irrelevant because we are only forking
to immediately exec(), which will discard the whole virtual address
space anyway.
This issue can be avoided by using a new optimized gspawn codepath in
the latest glib development version, which uses posix_spawn() internally.
For the optimized codepath to be used, we must not pass a child_setup
function, so the the file descriptor management is reimplemented here
using new glib API to pass fds to the child process. The old API will
continue to be used on older glib versions.
We must also change the spawn flags for this code path to be hit.
I checked that gnome-shell's open file descriptors are all CLOEXEC
so using G_SPAWN_LEAVE_DESCRIPTORS_OPEN should be safe.
This will result in more resilient app launching when memory is low,
since the optimized spawn path avoids cloning the virtual address
space of the parent process (gnome-shell) and avoids the irrelevant
memory overcommit check.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/132
2018-06-06 13:07:17 +00:00
|
|
|
#if !defined(HAVE_GIO_DESKTOP_LAUNCH_URIS_WITH_FDS) && defined(HAVE_SYSTEMD)
|
2013-11-07 17:34:57 +00:00
|
|
|
/* This sets up the launched application to log to the journal
|
|
|
|
* using its own identifier, instead of just "gnome-session".
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
app_child_setup (gpointer user_data)
|
|
|
|
{
|
|
|
|
const char *appid = user_data;
|
|
|
|
int res;
|
|
|
|
int journalfd = sd_journal_stream_fd (appid, LOG_INFO, FALSE);
|
|
|
|
if (journalfd >= 0)
|
|
|
|
{
|
|
|
|
do
|
|
|
|
res = dup2 (journalfd, 1);
|
|
|
|
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
|
|
|
do
|
|
|
|
res = dup2 (journalfd, 2);
|
|
|
|
while (G_UNLIKELY (res == -1 && errno == EINTR));
|
|
|
|
(void) close (journalfd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-03-25 01:46:25 +00:00
|
|
|
static void
|
|
|
|
wait_pid (GDesktopAppInfo *appinfo,
|
|
|
|
GPid pid,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
g_child_watch_add (pid, (GChildWatchFunc) g_spawn_close_pid, NULL);
|
|
|
|
}
|
|
|
|
|
2019-10-24 12:39:25 +00:00
|
|
|
static void
|
|
|
|
apply_discrete_gpu_env (GAppLaunchContext *context,
|
|
|
|
ShellGlobal *global)
|
|
|
|
{
|
|
|
|
GDBusProxy *proxy;
|
|
|
|
GVariant* variant;
|
|
|
|
guint num_children, i;
|
|
|
|
|
2020-04-28 15:25:18 +00:00
|
|
|
proxy = shell_global_get_switcheroo_control (global);
|
2019-10-24 12:39:25 +00:00
|
|
|
if (!proxy)
|
|
|
|
{
|
|
|
|
g_warning ("Could not apply discrete GPU environment, switcheroo-control not available");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
variant = shell_net_hadess_switcheroo_control_get_gpus (SHELL_NET_HADESS_SWITCHEROO_CONTROL (proxy));
|
|
|
|
if (!variant)
|
|
|
|
{
|
|
|
|
g_warning ("Could not apply discrete GPU environment, no GPUs in list");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
num_children = g_variant_n_children (variant);
|
|
|
|
for (i = 0; i < num_children; i++)
|
|
|
|
{
|
2020-03-02 17:16:25 +00:00
|
|
|
g_autoptr(GVariant) gpu = NULL;
|
2019-10-24 12:39:25 +00:00
|
|
|
g_autoptr(GVariant) env = NULL;
|
|
|
|
g_autoptr(GVariant) default_variant = NULL;
|
|
|
|
g_autofree const char **env_s = NULL;
|
|
|
|
guint j;
|
|
|
|
|
|
|
|
gpu = g_variant_get_child_value (variant, i);
|
|
|
|
if (!gpu ||
|
|
|
|
!g_variant_is_of_type (gpu, G_VARIANT_TYPE ("a{s*}")))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Skip over the default GPU */
|
|
|
|
default_variant = g_variant_lookup_value (gpu, "Default", NULL);
|
|
|
|
if (!default_variant || g_variant_get_boolean (default_variant))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
env = g_variant_lookup_value (gpu, "Environment", NULL);
|
|
|
|
if (!env)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
env_s = g_variant_get_strv (env, NULL);
|
|
|
|
for (j = 0; env_s[j] != NULL; j = j + 2)
|
|
|
|
g_app_launch_context_setenv (context, env_s[j], env_s[j+1]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-29 09:19:28 +00:00
|
|
|
g_debug ("Could not find discrete GPU in switcheroo-control, not applying environment");
|
2019-10-24 12:39:25 +00:00
|
|
|
}
|
|
|
|
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
/**
|
|
|
|
* shell_app_launch:
|
|
|
|
* @timestamp: Event timestamp, or 0 for current event timestamp
|
|
|
|
* @workspace: Start on this workspace, or -1 for default
|
2020-04-29 09:20:40 +00:00
|
|
|
* @gpu_pref: the GPU to prefer launching on
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
* @error: A #GError
|
|
|
|
*/
|
|
|
|
gboolean
|
2020-04-29 09:20:40 +00:00
|
|
|
shell_app_launch (ShellApp *app,
|
|
|
|
guint timestamp,
|
|
|
|
int workspace,
|
|
|
|
ShellAppLaunchGpu gpu_pref,
|
|
|
|
GError **error)
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
{
|
2014-01-19 17:34:32 +00:00
|
|
|
ShellGlobal *global;
|
2014-01-19 17:46:36 +00:00
|
|
|
GAppLaunchContext *context;
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
gboolean ret;
|
shell-app: remove child_setup from app launching
When the amount of free memory on the system is somewhat low, gnome-shell
will sometimes fail to launch apps, reporting the error:
fork(): Cannot allocate memory
fork() is failing here because while cloning the process virtual address
space, Linux worries that the thread being forked may end up COWing the
entire address space of the parent process (gnome-shell, which is
memory-hungry), and there is not enough free memory to permit that to
happen. This check is somewhat irrelevant because we are only forking
to immediately exec(), which will discard the whole virtual address
space anyway.
This issue can be avoided by using a new optimized gspawn codepath in
the latest glib development version, which uses posix_spawn() internally.
For the optimized codepath to be used, we must not pass a child_setup
function, so the the file descriptor management is reimplemented here
using new glib API to pass fds to the child process. The old API will
continue to be used on older glib versions.
We must also change the spawn flags for this code path to be hit.
I checked that gnome-shell's open file descriptors are all CLOEXEC
so using G_SPAWN_LEAVE_DESCRIPTORS_OPEN should be safe.
This will result in more resilient app launching when memory is low,
since the optimized spawn path avoids cloning the virtual address
space of the parent process (gnome-shell) and avoids the irrelevant
memory overcommit check.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/132
2018-06-06 13:07:17 +00:00
|
|
|
GSpawnFlags flags;
|
2020-04-29 09:20:40 +00:00
|
|
|
gboolean discrete_gpu = FALSE;
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
|
2013-02-09 03:52:25 +00:00
|
|
|
if (app->info == NULL)
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
{
|
|
|
|
MetaWindow *window = window_backed_app_get_window (app);
|
2015-10-08 02:56:11 +00:00
|
|
|
/* We don't use an error return if there no longer any windows, because the
|
|
|
|
* user attempting to activate a stale window backed app isn't something
|
|
|
|
* we would expect the caller to meaningfully handle or display an error
|
|
|
|
* message to the user.
|
|
|
|
*/
|
|
|
|
if (window)
|
|
|
|
meta_window_activate (window, timestamp);
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2014-01-19 17:34:32 +00:00
|
|
|
global = shell_global_get ();
|
|
|
|
context = shell_global_create_app_launch_context (global, timestamp, workspace);
|
2020-04-29 09:20:40 +00:00
|
|
|
if (gpu_pref == SHELL_APP_LAUNCH_GPU_APP_PREF)
|
|
|
|
discrete_gpu = g_desktop_app_info_get_boolean (app->info, "PrefersNonDefaultGPU");
|
|
|
|
else
|
|
|
|
discrete_gpu = (gpu_pref == SHELL_APP_LAUNCH_GPU_DISCRETE);
|
|
|
|
|
2016-10-19 13:43:37 +00:00
|
|
|
if (discrete_gpu)
|
2019-10-24 12:39:25 +00:00
|
|
|
apply_discrete_gpu_env (context, global);
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
|
shell-app: remove child_setup from app launching
When the amount of free memory on the system is somewhat low, gnome-shell
will sometimes fail to launch apps, reporting the error:
fork(): Cannot allocate memory
fork() is failing here because while cloning the process virtual address
space, Linux worries that the thread being forked may end up COWing the
entire address space of the parent process (gnome-shell, which is
memory-hungry), and there is not enough free memory to permit that to
happen. This check is somewhat irrelevant because we are only forking
to immediately exec(), which will discard the whole virtual address
space anyway.
This issue can be avoided by using a new optimized gspawn codepath in
the latest glib development version, which uses posix_spawn() internally.
For the optimized codepath to be used, we must not pass a child_setup
function, so the the file descriptor management is reimplemented here
using new glib API to pass fds to the child process. The old API will
continue to be used on older glib versions.
We must also change the spawn flags for this code path to be hit.
I checked that gnome-shell's open file descriptors are all CLOEXEC
so using G_SPAWN_LEAVE_DESCRIPTORS_OPEN should be safe.
This will result in more resilient app launching when memory is low,
since the optimized spawn path avoids cloning the virtual address
space of the parent process (gnome-shell) and avoids the irrelevant
memory overcommit check.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/132
2018-06-06 13:07:17 +00:00
|
|
|
/* Set LEAVE_DESCRIPTORS_OPEN in order to use an optimized gspawn
|
|
|
|
* codepath. The shell's open file descriptors should be marked CLOEXEC
|
|
|
|
* so that they are automatically closed even with this flag set.
|
|
|
|
*/
|
|
|
|
flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD |
|
|
|
|
G_SPAWN_LEAVE_DESCRIPTORS_OPEN;
|
|
|
|
|
|
|
|
#ifdef HAVE_GIO_DESKTOP_LAUNCH_URIS_WITH_FDS
|
|
|
|
/* Optimized spawn path, avoiding a child_setup function */
|
|
|
|
{
|
|
|
|
int journalfd = -1;
|
|
|
|
|
|
|
|
#ifdef HAVE_SYSTEMD
|
|
|
|
journalfd = sd_journal_stream_fd (shell_app_get_id (app), LOG_INFO, FALSE);
|
|
|
|
#endif /* HAVE_SYSTEMD */
|
|
|
|
|
|
|
|
ret = g_desktop_app_info_launch_uris_as_manager_with_fds (app->info, NULL,
|
|
|
|
context,
|
|
|
|
flags,
|
|
|
|
NULL, NULL,
|
|
|
|
wait_pid, NULL,
|
|
|
|
-1,
|
|
|
|
journalfd,
|
|
|
|
journalfd,
|
|
|
|
error);
|
|
|
|
|
|
|
|
if (journalfd >= 0)
|
|
|
|
(void) close (journalfd);
|
|
|
|
}
|
|
|
|
#else /* !HAVE_GIO_DESKTOP_LAUNCH_URIS_WITH_FDS */
|
2013-02-09 03:52:25 +00:00
|
|
|
ret = g_desktop_app_info_launch_uris_as_manager (app->info, NULL,
|
2014-01-19 17:46:36 +00:00
|
|
|
context,
|
shell-app: remove child_setup from app launching
When the amount of free memory on the system is somewhat low, gnome-shell
will sometimes fail to launch apps, reporting the error:
fork(): Cannot allocate memory
fork() is failing here because while cloning the process virtual address
space, Linux worries that the thread being forked may end up COWing the
entire address space of the parent process (gnome-shell, which is
memory-hungry), and there is not enough free memory to permit that to
happen. This check is somewhat irrelevant because we are only forking
to immediately exec(), which will discard the whole virtual address
space anyway.
This issue can be avoided by using a new optimized gspawn codepath in
the latest glib development version, which uses posix_spawn() internally.
For the optimized codepath to be used, we must not pass a child_setup
function, so the the file descriptor management is reimplemented here
using new glib API to pass fds to the child process. The old API will
continue to be used on older glib versions.
We must also change the spawn flags for this code path to be hit.
I checked that gnome-shell's open file descriptors are all CLOEXEC
so using G_SPAWN_LEAVE_DESCRIPTORS_OPEN should be safe.
This will result in more resilient app launching when memory is low,
since the optimized spawn path avoids cloning the virtual address
space of the parent process (gnome-shell) and avoids the irrelevant
memory overcommit check.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/132
2018-06-06 13:07:17 +00:00
|
|
|
flags,
|
2013-11-07 17:34:57 +00:00
|
|
|
#ifdef HAVE_SYSTEMD
|
|
|
|
app_child_setup, (gpointer)shell_app_get_id (app),
|
|
|
|
#else
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
NULL, NULL,
|
2013-11-07 17:34:57 +00:00
|
|
|
#endif
|
2017-03-25 01:46:25 +00:00
|
|
|
wait_pid, NULL,
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
error);
|
shell-app: remove child_setup from app launching
When the amount of free memory on the system is somewhat low, gnome-shell
will sometimes fail to launch apps, reporting the error:
fork(): Cannot allocate memory
fork() is failing here because while cloning the process virtual address
space, Linux worries that the thread being forked may end up COWing the
entire address space of the parent process (gnome-shell, which is
memory-hungry), and there is not enough free memory to permit that to
happen. This check is somewhat irrelevant because we are only forking
to immediately exec(), which will discard the whole virtual address
space anyway.
This issue can be avoided by using a new optimized gspawn codepath in
the latest glib development version, which uses posix_spawn() internally.
For the optimized codepath to be used, we must not pass a child_setup
function, so the the file descriptor management is reimplemented here
using new glib API to pass fds to the child process. The old API will
continue to be used on older glib versions.
We must also change the spawn flags for this code path to be hit.
I checked that gnome-shell's open file descriptors are all CLOEXEC
so using G_SPAWN_LEAVE_DESCRIPTORS_OPEN should be safe.
This will result in more resilient app launching when memory is low,
since the optimized spawn path avoids cloning the virtual address
space of the parent process (gnome-shell) and avoids the irrelevant
memory overcommit check.
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/132
2018-06-06 13:07:17 +00:00
|
|
|
#endif /* HAVE_GIO_DESKTOP_LAUNCH_URIS_WITH_FDS */
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
g_object_unref (context);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-01-19 17:46:36 +00:00
|
|
|
/**
|
|
|
|
* shell_app_launch_action:
|
|
|
|
* @app: the #ShellApp
|
|
|
|
* @action_name: the name of the action to launch (as obtained by
|
|
|
|
* g_desktop_app_info_list_actions())
|
|
|
|
* @timestamp: Event timestamp, or 0 for current event timestamp
|
|
|
|
* @workspace: Start on this workspace, or -1 for default
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
shell_app_launch_action (ShellApp *app,
|
|
|
|
const char *action_name,
|
|
|
|
guint timestamp,
|
|
|
|
int workspace)
|
|
|
|
{
|
2014-01-19 17:34:32 +00:00
|
|
|
ShellGlobal *global;
|
2014-01-19 17:46:36 +00:00
|
|
|
GAppLaunchContext *context;
|
|
|
|
|
2014-01-19 17:34:32 +00:00
|
|
|
global = shell_global_get ();
|
|
|
|
context = shell_global_create_app_launch_context (global, timestamp, workspace);
|
2014-01-19 17:46:36 +00:00
|
|
|
|
|
|
|
g_desktop_app_info_launch_action (G_DESKTOP_APP_INFO (app->info),
|
|
|
|
action_name, context);
|
|
|
|
|
|
|
|
g_object_unref (context);
|
|
|
|
}
|
|
|
|
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
/**
|
|
|
|
* shell_app_get_app_info:
|
|
|
|
* @app: a #ShellApp
|
|
|
|
*
|
|
|
|
* Returns: (transfer none): The #GDesktopAppInfo for this app, or %NULL if backed by a window
|
|
|
|
*/
|
|
|
|
GDesktopAppInfo *
|
|
|
|
shell_app_get_app_info (ShellApp *app)
|
|
|
|
{
|
2013-02-09 03:52:25 +00:00
|
|
|
return app->info;
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
}
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
static void
|
|
|
|
create_running_state (ShellApp *app)
|
|
|
|
{
|
2018-01-03 07:55:38 +00:00
|
|
|
MetaDisplay *display = shell_global_get_display (shell_global_get ());
|
|
|
|
MetaWorkspaceManager *workspace_manager =
|
|
|
|
meta_display_get_workspace_manager (display);
|
2010-06-09 18:50:01 +00:00
|
|
|
|
|
|
|
g_assert (app->running_state == NULL);
|
|
|
|
|
2020-10-19 18:12:27 +00:00
|
|
|
app->running_state = g_new0 (ShellAppRunningState, 1);
|
2010-06-09 18:50:01 +00:00
|
|
|
app->running_state->refcount = 1;
|
|
|
|
app->running_state->workspace_switch_id =
|
2018-01-03 07:55:38 +00:00
|
|
|
g_signal_connect (workspace_manager, "workspace-switched",
|
|
|
|
G_CALLBACK (shell_app_on_ws_switch), app);
|
2012-01-17 20:13:47 +00:00
|
|
|
|
2013-04-03 18:15:17 +00:00
|
|
|
app->running_state->session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
|
|
|
g_assert (app->running_state->session != NULL);
|
2013-05-09 19:00:40 +00:00
|
|
|
app->running_state->muxer = gtk_action_muxer_new ();
|
2012-01-17 20:13:47 +00:00
|
|
|
}
|
|
|
|
|
2012-05-17 16:18:53 +00:00
|
|
|
void
|
2018-10-04 17:20:40 +00:00
|
|
|
shell_app_update_app_actions (ShellApp *app,
|
|
|
|
MetaWindow *window)
|
2012-01-17 20:13:47 +00:00
|
|
|
{
|
2012-05-17 16:18:53 +00:00
|
|
|
const gchar *unique_bus_name;
|
|
|
|
|
|
|
|
/* We assume that 'gtk-application-object-path' and
|
|
|
|
* 'gtk-app-menu-object-path' are the same for all windows which
|
2012-01-17 20:13:47 +00:00
|
|
|
* have it set.
|
|
|
|
*
|
|
|
|
* It could be possible, however, that the first window we see
|
|
|
|
* belonging to the app didn't have them set. For this reason, we
|
|
|
|
* take the values from the first window that has them set and ignore
|
|
|
|
* all the rest (until the app is stopped and restarted).
|
|
|
|
*/
|
|
|
|
|
2012-05-17 16:18:53 +00:00
|
|
|
unique_bus_name = meta_window_get_gtk_unique_bus_name (window);
|
|
|
|
|
2018-10-04 17:20:40 +00:00
|
|
|
if (g_strcmp0 (app->running_state->unique_bus_name, unique_bus_name) != 0)
|
2012-01-17 20:13:47 +00:00
|
|
|
{
|
|
|
|
const gchar *application_object_path;
|
|
|
|
GDBusActionGroup *actions;
|
|
|
|
|
|
|
|
application_object_path = meta_window_get_gtk_application_object_path (window);
|
|
|
|
|
2018-10-04 17:20:40 +00:00
|
|
|
if (application_object_path == NULL || unique_bus_name == NULL)
|
2012-01-17 20:13:47 +00:00
|
|
|
return;
|
|
|
|
|
2012-05-17 16:18:53 +00:00
|
|
|
g_clear_pointer (&app->running_state->unique_bus_name, g_free);
|
|
|
|
app->running_state->unique_bus_name = g_strdup (unique_bus_name);
|
2013-04-03 18:15:17 +00:00
|
|
|
actions = g_dbus_action_group_get (app->running_state->session, unique_bus_name, application_object_path);
|
2013-05-09 19:00:40 +00:00
|
|
|
gtk_action_muxer_insert (app->running_state->muxer, "app", G_ACTION_GROUP (actions));
|
2012-01-17 20:13:47 +00:00
|
|
|
g_object_unref (actions);
|
|
|
|
}
|
2010-06-09 18:50:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
unref_running_state (ShellAppRunningState *state)
|
|
|
|
{
|
2018-01-03 07:55:38 +00:00
|
|
|
MetaDisplay *display = shell_global_get_display (shell_global_get ());
|
|
|
|
MetaWorkspaceManager *workspace_manager =
|
|
|
|
meta_display_get_workspace_manager (display);
|
2010-06-09 18:50:01 +00:00
|
|
|
|
2011-05-10 16:29:52 +00:00
|
|
|
g_assert (state->refcount > 0);
|
|
|
|
|
2010-06-09 18:50:01 +00:00
|
|
|
state->refcount--;
|
|
|
|
if (state->refcount > 0)
|
|
|
|
return;
|
|
|
|
|
2019-11-21 22:00:53 +00:00
|
|
|
g_clear_signal_handler (&state->workspace_switch_id, workspace_manager);
|
2011-05-10 16:29:52 +00:00
|
|
|
|
2014-09-16 10:05:52 +00:00
|
|
|
g_clear_object (&state->application_proxy);
|
|
|
|
|
|
|
|
if (state->cancellable != NULL)
|
|
|
|
{
|
|
|
|
g_cancellable_cancel (state->cancellable);
|
|
|
|
g_clear_object (&state->cancellable);
|
|
|
|
}
|
2013-04-03 18:16:58 +00:00
|
|
|
|
2011-12-15 05:29:31 +00:00
|
|
|
g_clear_object (&state->muxer);
|
2013-04-03 18:15:17 +00:00
|
|
|
g_clear_object (&state->session);
|
2012-08-26 01:14:34 +00:00
|
|
|
g_clear_pointer (&state->unique_bus_name, g_free);
|
2011-05-10 16:29:52 +00:00
|
|
|
|
2020-10-19 18:12:27 +00:00
|
|
|
g_free (state);
|
2010-06-09 18:50:01 +00:00
|
|
|
}
|
|
|
|
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
/**
|
|
|
|
* shell_app_compare_by_name:
|
2011-11-02 16:24:49 +00:00
|
|
|
* @app: One app
|
|
|
|
* @other: The other app
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
*
|
|
|
|
* Order two applications by name.
|
|
|
|
*
|
2011-11-02 16:24:49 +00:00
|
|
|
* Returns: -1, 0, or 1; suitable for use as a comparison function
|
|
|
|
* for e.g. g_slist_sort()
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
*/
|
|
|
|
int
|
|
|
|
shell_app_compare_by_name (ShellApp *app, ShellApp *other)
|
|
|
|
{
|
|
|
|
return strcmp (app->name_collation_key, other->name_collation_key);
|
|
|
|
}
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
static void
|
|
|
|
shell_app_init (ShellApp *self)
|
|
|
|
{
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
self->state = SHELL_APP_STATE_STOPPED;
|
2020-06-15 18:41:45 +00:00
|
|
|
self->started_on_workspace = -1;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
shell_app_dispose (GObject *object)
|
|
|
|
{
|
|
|
|
ShellApp *app = SHELL_APP (object);
|
|
|
|
|
2013-02-09 03:52:25 +00:00
|
|
|
g_clear_object (&app->info);
|
2020-06-30 14:53:50 +00:00
|
|
|
g_clear_object (&app->fallback_icon);
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
2014-01-28 21:47:23 +00:00
|
|
|
while (app->running_state)
|
|
|
|
_shell_app_remove_window (app, app->running_state->windows->data);
|
|
|
|
|
2011-05-10 16:29:52 +00:00
|
|
|
/* We should have been transitioned when we removed all of our windows */
|
|
|
|
g_assert (app->state == SHELL_APP_STATE_STOPPED);
|
|
|
|
g_assert (app->running_state == NULL);
|
2010-03-10 23:22:06 +00:00
|
|
|
|
|
|
|
G_OBJECT_CLASS(shell_app_parent_class)->dispose (object);
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|
|
|
|
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
static void
|
|
|
|
shell_app_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
ShellApp *app = SHELL_APP (object);
|
|
|
|
|
|
|
|
g_free (app->window_id_string);
|
|
|
|
|
|
|
|
g_free (app->name_collation_key);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS(shell_app_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
static void
|
|
|
|
shell_app_class_init(ShellAppClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
gobject_class->get_property = shell_app_get_property;
|
2016-07-06 17:56:47 +00:00
|
|
|
gobject_class->set_property = shell_app_set_property;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
gobject_class->dispose = shell_app_dispose;
|
Kill off ShellAppInfo, move into ShellApp
This dramatically thins down and sanitizes the application code.
The ShellAppSystem changes in a number of ways:
* Preferences are special cased more explicitly; they aren't apps,
they're shortcuts for an app), and we don't have many of them, so
don't need e.g. the optimizations in ShellAppSystem for searching.
* get_app() changes to lookup_app() and returns null if an app isn't
found. The semantics where it tried to find the .desktop file
if we didn't know about it were just broken; I am pretty sure no
caller needs this, and if they do we'll fix them.
* ShellAppSystem maintains two indexes on apps (by desktop file id
and by GMenuTreeEntry), but is no longer in the business of
dealing with GMenuTree as far as hierarchy and categories go. That
is moved up into js/ui/appDisplay.js. Actually, it flattens both
apps and settings.
Also, ShellWindowTracker is now the sole reference-owner for
window-backed apps. We still do the weird "window:0x1234beef" id
for these apps, but a reference is not stored in ShellAppSystem.
The js/ui/appDisplay.js code is rewritten, and sucks a lot less.
Variable names are clearer:
_apps -> _appIcons
_filterApp -> _visibleApps
_filters -> _categoryBox
Similarly for function names. We no longer call (for every app) a
recursive lookup in GMenuTree to see if it's in a particular section
on every category switch; it's all cached.
NOTE - this intentionally reverts the incremental loading code from
commit 7813c5b93f6bcde8c4beae286e82bfc472b2b656. It's fast enough
here without that.
https://bugzilla.gnome.org/show_bug.cgi?id=648149
2011-04-21 17:35:01 +00:00
|
|
|
gobject_class->finalize = shell_app_finalize;
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
|
|
|
|
shell_app_signals[WINDOWS_CHANGED] = g_signal_new ("windows-changed",
|
|
|
|
SHELL_TYPE_APP,
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
2011-10-18 22:19:32 +00:00
|
|
|
NULL, NULL, NULL,
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
G_TYPE_NONE, 0);
|
Major ShellApp API cleanup, startup notification, window focus handling
This patch combines several high level changes which are conceptually
independent but in practice rather intertwined.
* Add a "state" property to ShellApp which reflects whether it's
stopped, starting, or started. This will allow us to later clean
up all the callers that are using ".get_windows().length > 0" as
a proxy for this property
* Replace shell_app_launch with shell_app_activate and shell_app_open_new_window
A lot of code was calling .launch, but it's signficantly clearer
if we call this ".open_new_window()", and later if we gain the ability
to call into an application's menu, we can implement this correctly rather
than trying to update all .launch callers.
* Because ShellApp now has a "starting" state, rebase panel.js on top of
this so that when we get a startup-notification sequence for an app
and transition it to starting, it becomes the focus app, and panel.js
cleanly just tracks the focus app, rather than bouncing between SN
sequences. This removes display of non-app startup sequences, which
I consider an acceptable action in light of the committed changes
to startup-notification and GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=614755
2010-04-03 18:07:44 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ShellApp:state:
|
|
|
|
*
|
|
|
|
* The high-level state of the application, effectively whether it's
|
|
|
|
* running or not, or transitioning between those states.
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
PROP_STATE,
|
|
|
|
g_param_spec_enum ("state",
|
|
|
|
"State",
|
|
|
|
"Application state",
|
|
|
|
SHELL_TYPE_APP_STATE,
|
|
|
|
SHELL_APP_STATE_STOPPED,
|
2019-07-25 17:34:19 +00:00
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
2014-09-16 10:08:19 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ShellApp:busy:
|
|
|
|
*
|
|
|
|
* Whether the application has marked itself as busy.
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
PROP_BUSY,
|
|
|
|
g_param_spec_boolean ("busy",
|
|
|
|
"Busy",
|
|
|
|
"Busy state",
|
|
|
|
FALSE,
|
2019-07-25 17:34:19 +00:00
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
2011-05-10 16:29:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ShellApp:id:
|
|
|
|
*
|
|
|
|
* The id of this application (a desktop filename, or a special string
|
|
|
|
* like window:0xabcd1234)
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
PROP_ID,
|
|
|
|
g_param_spec_string ("id",
|
|
|
|
"Application id",
|
|
|
|
"The desktop file id of this ShellApp",
|
|
|
|
NULL,
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
|
|
|
|
2021-03-12 22:13:25 +00:00
|
|
|
/**
|
|
|
|
* ShellApp:icon:
|
|
|
|
*
|
|
|
|
* The #GIcon representing this ShellApp
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
PROP_ICON,
|
|
|
|
g_param_spec_object ("icon",
|
|
|
|
"GIcon",
|
|
|
|
"The GIcon representing this app",
|
|
|
|
G_TYPE_ICON,
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
|
|
|
|
2011-05-10 16:29:52 +00:00
|
|
|
/**
|
|
|
|
* ShellApp:action-group:
|
|
|
|
*
|
|
|
|
* The #GDBusActionGroup associated with this ShellApp, if any. See the
|
|
|
|
* documentation of #GApplication and #GActionGroup for details.
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
PROP_ACTION_GROUP,
|
|
|
|
g_param_spec_object ("action-group",
|
|
|
|
"Application Action Group",
|
|
|
|
"The action group exported by the remote application",
|
2011-12-15 05:29:31 +00:00
|
|
|
G_TYPE_ACTION_GROUP,
|
2011-05-10 16:29:52 +00:00
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
2016-07-06 17:56:47 +00:00
|
|
|
/**
|
|
|
|
* ShellApp:app-info:
|
|
|
|
*
|
|
|
|
* The #GDesktopAppInfo associated with this ShellApp, if any.
|
|
|
|
*/
|
|
|
|
g_object_class_install_property (gobject_class,
|
|
|
|
PROP_APP_INFO,
|
|
|
|
g_param_spec_object ("app-info",
|
|
|
|
"DesktopAppInfo",
|
|
|
|
"The DesktopAppInfo associated with this app",
|
|
|
|
G_TYPE_DESKTOP_APP_INFO,
|
|
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
2011-05-10 16:29:52 +00:00
|
|
|
|
Create ShellApp, rebase things on it
Previously, we had ShellAppInfo, which contains fundamental
information about an application, and methods on ShellAppMonitor
to retrieve "live" information like the window list.
AppIcon ended up being used as the "App" class which was painful
for various reasons; among them that we need to handle window
list changes, and some consumers weren't ready for that.
Clean things up a bit by introducing a new ShellApp class in C,
which currently wraps a ShellAppInfo.
AppIcon then is more like the display actor for a ShellApp. Notably,
the ".windows" property moves out of it. The altTab code which
won't handle dynamic changes instead is changed to maintain a
cached version.
ShellAppMonitor gains some more methods related to ShellApp now.
In the future, we might consider changing ShellApp to be a GInterface,
which could be implemented by ShellDesktopFileApp, ShellWindowApp.
Then we could axe ShellAppInfo from the "public" API and it would
return to being an internal loss mitigation layer for GMenu.
https://bugzilla.gnome.org/show_bug.cgi?id=598227
2009-10-11 20:40:00 +00:00
|
|
|
}
|