Map windows to realms by calling realmsd pid lookup method
This commit is contained in:
parent
3f794cbe00
commit
2f4a1ed647
@ -56,4 +56,3 @@ var RealmManager = class {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -17,10 +17,11 @@ function _windowAppId(window) {
|
||||
function windowMenuDebugString(window) {
|
||||
const id = _windowAppId(window);
|
||||
const realm_name = windowRealmName(window);
|
||||
const realms = Shell.Realms.get_default();
|
||||
|
||||
if (!realm_name) {
|
||||
return id;
|
||||
} else if (window.is_on_foreign_workspace_context()) {
|
||||
} else if (realms.is_foreign_window(window)) {
|
||||
return `${id} [${realm_name}]`;
|
||||
} else {
|
||||
return `${id} (${realm_name})`;
|
||||
|
@ -123,7 +123,7 @@ realm_name_from_application_id (const char *id)
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
static char *
|
||||
current_realm_name (gboolean name_only)
|
||||
{
|
||||
gchar *link = NULL;
|
||||
@ -399,6 +399,10 @@ shell_app_system_lookup_app (ShellAppSystem *self,
|
||||
ShellApp *app;
|
||||
GDesktopAppInfo *info;
|
||||
|
||||
if (id == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
app = g_hash_table_lookup (priv->id_to_app, id);
|
||||
if (app)
|
||||
return app;
|
||||
|
@ -8,16 +8,14 @@ struct _ShellRealmItem {
|
||||
GObject parent;
|
||||
char *realm_name;
|
||||
char *description;
|
||||
char *namespace;
|
||||
guint64 namespace;
|
||||
MetaWorkspaceContext *context;
|
||||
guint8 status;
|
||||
ShellRealmItemStatus status;
|
||||
gboolean tagged;
|
||||
gboolean disposed;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ShellRealmItem, shell_realm_item, G_TYPE_OBJECT);
|
||||
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ITEM_REALM_NAME,
|
||||
@ -25,45 +23,45 @@ enum {
|
||||
PROP_ITEM_NAMESPACE
|
||||
};
|
||||
|
||||
#define REALM_STATUS_RUNNING 1
|
||||
#define REALM_STATUS_CURRENT 2
|
||||
#define REALM_STATUS_SYSTEM 4
|
||||
|
||||
static void
|
||||
shell_realm_item_init(ShellRealmItem *item)
|
||||
shell_realm_item_init (ShellRealmItem *item)
|
||||
{
|
||||
}
|
||||
|
||||
ShellRealmItem *
|
||||
shell_realm_item_new (const char *realm_name, const char *description, const char *namespace, guint8 status)
|
||||
shell_realm_item_new (const char *realm_name, const char *description, guint64 namespace, guint8 status)
|
||||
{
|
||||
ShellRealmItem *item = g_object_new (SHELL_TYPE_REALM_ITEM, NULL);
|
||||
item->realm_name = g_strdup (realm_name);
|
||||
item->description = g_strdup (description);
|
||||
item->namespace = g_strdup (namespace);
|
||||
item->namespace = namespace;
|
||||
item->status = status;
|
||||
item->context = NULL;
|
||||
item->tagged = FALSE;
|
||||
item->disposed = FALSE;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void
|
||||
shell_realm_item_acquire_context (ShellRealmItem *item)
|
||||
/**
|
||||
* shell_realm_item_get_context:
|
||||
* @item: A #ShellRealmItem instance
|
||||
*
|
||||
* Returns the #MetaWorkspaceContext associated with this realm if any.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #MetaWorkspaceContext instance or
|
||||
* %NULL if no context is associated with this realm.
|
||||
*/
|
||||
MetaWorkspaceContext *
|
||||
shell_realm_item_get_context (ShellRealmItem *item)
|
||||
{
|
||||
if (item->context || item->disposed || shell_realm_item_is_system (item)) {
|
||||
return;
|
||||
}
|
||||
return item->context;
|
||||
}
|
||||
|
||||
if (!item->namespace || !shell_realm_item_is_running (item)) {
|
||||
g_warning ("ShellRealmItem: Cannot acquire workspace context for realm '%s' because not running or no namespace", item->realm_name);
|
||||
return;
|
||||
}
|
||||
|
||||
MetaDisplay *display = shell_global_get_display (shell_global_get());
|
||||
MetaWorkspaceManager *workspace_manager = meta_display_get_workspace_manager (display);
|
||||
item->context = meta_workspace_manager_context_for_namespace (workspace_manager, item->namespace);
|
||||
void
|
||||
shell_realm_item_set_context (ShellRealmItem *item, MetaWorkspaceContext *context)
|
||||
{
|
||||
item->context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,15 +96,12 @@ shell_realm_item_get_description (ShellRealmItem *item)
|
||||
* shell_realm_item_get_namespace:
|
||||
* @item: A #ShellRealmItem instance
|
||||
*
|
||||
* Returns: The namespace field for this realm or an empty string if no namespace is set
|
||||
* Returns: The namespace field for this realm or 0 if no namespace is set
|
||||
*/
|
||||
const char *
|
||||
guint64
|
||||
shell_realm_item_get_namespace (ShellRealmItem *item)
|
||||
{
|
||||
if (item->namespace)
|
||||
return item->namespace;
|
||||
else
|
||||
return "";
|
||||
return item->namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,10 +114,6 @@ shell_realm_item_get_namespace (ShellRealmItem *item)
|
||||
guint
|
||||
shell_realm_item_get_context_id (ShellRealmItem *item)
|
||||
{
|
||||
if (shell_realm_item_is_running (item) && !item->context) {
|
||||
shell_realm_item_acquire_context (item);
|
||||
}
|
||||
|
||||
if (item->context) {
|
||||
return meta_workspace_context_id (item->context);
|
||||
} else {
|
||||
@ -140,10 +131,6 @@ shell_realm_item_get_context_id (ShellRealmItem *item)
|
||||
MetaWorkspace *
|
||||
shell_realm_item_get_active_workspace (ShellRealmItem *item)
|
||||
{
|
||||
if (shell_realm_item_is_running (item) && !item->context) {
|
||||
shell_realm_item_acquire_context (item);
|
||||
}
|
||||
|
||||
if (item->context) {
|
||||
return meta_workspace_context_get_active_workspace (item->context);
|
||||
} else {
|
||||
@ -151,23 +138,6 @@ shell_realm_item_get_active_workspace (ShellRealmItem *item)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_realm_item_activate_context:
|
||||
* @item: A #ShellRealmItem instance for a running realm
|
||||
*
|
||||
* If a #MetaWorkspaceContext is associated with this realm
|
||||
* set it as the active workspace context.
|
||||
*/
|
||||
void
|
||||
shell_realm_item_activate_context (ShellRealmItem *item)
|
||||
{
|
||||
shell_realm_item_acquire_context (item);
|
||||
|
||||
if (item->context) {
|
||||
meta_workspace_context_activate (item->context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_realm_item_set_current:
|
||||
* @item: A #ShellRealmItem instance for a running realm
|
||||
@ -178,7 +148,7 @@ shell_realm_item_activate_context (ShellRealmItem *item)
|
||||
*/
|
||||
void
|
||||
shell_realm_item_set_current (ShellRealmItem *item) {
|
||||
ShellRealmTracker *tracker = shell_realm_tracker_get_default();
|
||||
ShellRealmTracker *tracker = shell_realm_tracker_get_default ();
|
||||
if (item && item->realm_name) {
|
||||
shell_realm_tracker_call_set_current (tracker, item->realm_name);
|
||||
}
|
||||
@ -195,8 +165,6 @@ shell_realm_item_set_current (ShellRealmItem *item) {
|
||||
void
|
||||
shell_realm_item_move_window_to_context (ShellRealmItem *item, MetaWindow *window)
|
||||
{
|
||||
shell_realm_item_acquire_context (item);
|
||||
|
||||
if (item->context) {
|
||||
meta_workspace_context_move_window_to_context (item->context, window);
|
||||
} else {
|
||||
@ -204,20 +172,20 @@ shell_realm_item_move_window_to_context (ShellRealmItem *item, MetaWindow *windo
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_flag_set(guint8 status, guchar flag)
|
||||
gboolean
|
||||
shell_realm_is_flag_set(guint8 status, ShellRealmItemStatus flag)
|
||||
{
|
||||
return ((status & flag) != 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_status_flag (ShellRealmItem *item, guchar flag)
|
||||
has_status_flag (ShellRealmItem *item, ShellRealmItemStatus flag)
|
||||
{
|
||||
return is_flag_set (item->status, flag);
|
||||
return shell_realm_is_flag_set (item->status, flag);
|
||||
}
|
||||
|
||||
static void
|
||||
set_status_flag (ShellRealmItem *item, guint8 flag, gboolean value)
|
||||
set_status_flag (ShellRealmItem *item, ShellRealmItemStatus flag, gboolean value)
|
||||
{
|
||||
if (value) {
|
||||
item->status |= flag;
|
||||
@ -235,7 +203,7 @@ set_status_flag (ShellRealmItem *item, guint8 flag, gboolean value)
|
||||
gboolean
|
||||
shell_realm_item_is_current (ShellRealmItem *item)
|
||||
{
|
||||
return has_status_flag (item, REALM_STATUS_CURRENT);
|
||||
return has_status_flag (item, SHELL_REALM_ITEM_STATUS_CURRENT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,7 +215,7 @@ shell_realm_item_is_current (ShellRealmItem *item)
|
||||
gboolean
|
||||
shell_realm_item_is_running (ShellRealmItem *item)
|
||||
{
|
||||
return has_status_flag (item, REALM_STATUS_RUNNING);
|
||||
return has_status_flag (item, SHELL_REALM_ITEM_STATUS_RUNNING);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,27 +227,22 @@ shell_realm_item_is_running (ShellRealmItem *item)
|
||||
gboolean
|
||||
shell_realm_item_is_system (ShellRealmItem *item)
|
||||
{
|
||||
return has_status_flag (item, REALM_STATUS_SYSTEM);
|
||||
return has_status_flag (item, SHELL_REALM_ITEM_STATUS_SYSTEM);
|
||||
}
|
||||
|
||||
|
||||
void shell_realm_item_set_current_flag (ShellRealmItem *item, gboolean value)
|
||||
{
|
||||
set_status_flag (item, REALM_STATUS_CURRENT, value);
|
||||
set_status_flag (item, SHELL_REALM_ITEM_STATUS_CURRENT, value);
|
||||
}
|
||||
|
||||
void shell_realm_item_set_running_flag (ShellRealmItem *item, gboolean value)
|
||||
{
|
||||
set_status_flag (item, REALM_STATUS_RUNNING, value);
|
||||
|
||||
if (!value && item->context) {
|
||||
meta_workspace_context_remove (item->context);
|
||||
item->context = NULL;
|
||||
}
|
||||
set_status_flag (item, SHELL_REALM_ITEM_STATUS_RUNNING, value);
|
||||
}
|
||||
|
||||
|
||||
void shell_realm_item_update (ShellRealmItem *item, const char *realm_name, const char *namespace, guint8 status)
|
||||
void shell_realm_item_update (ShellRealmItem *item, const char *realm_name, guint64 namespace, guint8 status)
|
||||
{
|
||||
if (g_strcmp0 (item->realm_name, realm_name)) {
|
||||
g_message ("ShellRealmItem: Realm name changed from %s to %s", item->realm_name, realm_name);
|
||||
@ -287,23 +250,8 @@ void shell_realm_item_update (ShellRealmItem *item, const char *realm_name, cons
|
||||
item->realm_name = g_strdup (realm_name);
|
||||
}
|
||||
|
||||
if (g_strcmp0 (item->namespace, namespace)) {
|
||||
g_free(item->namespace);
|
||||
item->namespace = g_strdup (namespace);
|
||||
}
|
||||
|
||||
if (item->status != status) {
|
||||
gboolean was_running = has_status_flag (item, REALM_STATUS_RUNNING);
|
||||
gboolean is_running = is_flag_set (status, REALM_STATUS_RUNNING);
|
||||
gboolean stopped = was_running && !is_running;
|
||||
|
||||
item->status = status;
|
||||
|
||||
if (stopped) {
|
||||
meta_workspace_context_remove (item->context);
|
||||
item->context = NULL;
|
||||
}
|
||||
}
|
||||
item->namespace = namespace;
|
||||
item->status = status;
|
||||
}
|
||||
|
||||
void
|
||||
@ -332,7 +280,7 @@ static void shell_realm_item_get_property (GObject *gobject,
|
||||
g_value_set_string (value, shell_realm_item_get_description (item));
|
||||
break;
|
||||
case PROP_ITEM_NAMESPACE:
|
||||
g_value_set_string (value, shell_realm_item_get_namespace (item));
|
||||
g_value_set_uint64 (value, shell_realm_item_get_namespace (item));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
@ -347,7 +295,6 @@ static void shell_realm_item_dispose (GObject *object)
|
||||
meta_workspace_context_remove (item->context);
|
||||
item->context = NULL;
|
||||
}
|
||||
item->disposed = TRUE;
|
||||
G_OBJECT_CLASS(shell_realm_item_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@ -357,7 +304,6 @@ shell_realm_item_finalize (GObject *object)
|
||||
ShellRealmItem *item = SHELL_REALM_ITEM (object);
|
||||
g_free (item->realm_name);
|
||||
g_free (item->description);
|
||||
g_free (item->namespace);
|
||||
|
||||
G_OBJECT_CLASS(shell_realm_item_parent_class)->finalize (object);
|
||||
}
|
||||
@ -373,10 +319,10 @@ shell_realm_item_class_init (ShellRealmItemClass *klass)
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ITEM_NAMESPACE,
|
||||
g_param_spec_string ("namespace",
|
||||
g_param_spec_uint64 ("namespace",
|
||||
"Context Namespace",
|
||||
"PID namespace of context",
|
||||
NULL,
|
||||
0, UINT64_MAX, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ITEM_REALM_NAME,
|
||||
@ -393,4 +339,4 @@ shell_realm_item_class_init (ShellRealmItemClass *klass)
|
||||
"Optional description of realm",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
}
|
||||
|
@ -7,26 +7,36 @@
|
||||
#define SHELL_TYPE_REALM_ITEM (shell_realm_item_get_type())
|
||||
G_DECLARE_FINAL_TYPE (ShellRealmItem, shell_realm_item, SHELL, REALM_ITEM, GObject)
|
||||
|
||||
ShellRealmItem *shell_realm_item_new (const char *realm_name, const char *description, const char *namespace, guint8 status);
|
||||
typedef enum {
|
||||
SHELL_REALM_ITEM_STATUS_RUNNING = 1 << 0,
|
||||
SHELL_REALM_ITEM_STATUS_CURRENT = 1 << 1,
|
||||
SHELL_REALM_ITEM_STATUS_SYSTEM = 1 << 2,
|
||||
} ShellRealmItemStatus;
|
||||
|
||||
gboolean shell_realm_is_flag_set (guint8 status, ShellRealmItemStatus flag);
|
||||
|
||||
ShellRealmItem *shell_realm_item_new (const char *realm_name, const char *description, guint64 namespace, guint8 status);
|
||||
|
||||
const char *shell_realm_item_get_realm_name (ShellRealmItem *item);
|
||||
const char *shell_realm_item_get_description (ShellRealmItem *item);
|
||||
const char *shell_realm_item_get_namespace (ShellRealmItem *item);
|
||||
guint64 shell_realm_item_get_namespace (ShellRealmItem *item);
|
||||
guint shell_realm_item_get_context_id (ShellRealmItem *item);
|
||||
MetaWorkspaceContext *shell_realm_item_get_context (ShellRealmItem *item);
|
||||
void shell_realm_item_set_context (ShellRealmItem *item, MetaWorkspaceContext *context);
|
||||
|
||||
MetaWorkspace *shell_realm_item_get_active_workspace (ShellRealmItem *item);
|
||||
|
||||
void shell_realm_item_update (ShellRealmItem *item, const char *realm_name, const char *namespace, guint8 status);
|
||||
void shell_realm_item_update (ShellRealmItem *item, const char *realm_name, guint64 namespace, guint8 status);
|
||||
|
||||
|
||||
void shell_realm_item_set_current_flag (ShellRealmItem *item, gboolean value);
|
||||
void shell_realm_item_set_running_flag (ShellRealmItem *item, gboolean value);
|
||||
|
||||
void shell_realm_item_activate_context (ShellRealmItem *item);
|
||||
void shell_realm_item_set_current (ShellRealmItem *item);
|
||||
void shell_realm_item_move_window_to_context (ShellRealmItem *item, MetaWindow *window);
|
||||
gboolean shell_realm_item_is_current(ShellRealmItem *item);
|
||||
gboolean shell_realm_item_is_running(ShellRealmItem *item);
|
||||
gboolean shell_realm_item_is_system(ShellRealmItem *item);
|
||||
gboolean shell_realm_item_is_current (ShellRealmItem *item);
|
||||
gboolean shell_realm_item_is_running (ShellRealmItem *item);
|
||||
gboolean shell_realm_item_is_system (ShellRealmItem *item);
|
||||
|
||||
void shell_realm_item_set_tagged (ShellRealmItem *item, gboolean is_tagged);
|
||||
gboolean shell_realm_item_is_tagged (ShellRealmItem *item);
|
||||
|
@ -7,6 +7,12 @@
|
||||
#define REALMS_OBJECT_PATH "/com/subgraph/realms"
|
||||
#define REALMS_MANAGER_INTERFACE "com.subgraph.realms.Manager"
|
||||
|
||||
enum {
|
||||
REALM_PID_LOOKUP_UNKNOWN = 1,
|
||||
REALM_PID_LOOKUP_REALM = 2,
|
||||
REALM_PID_LOOKUP_CITADEL = 3,
|
||||
};
|
||||
|
||||
struct _ShellRealmTracker {
|
||||
GObject parent;
|
||||
GDBusConnection *dbus;
|
||||
@ -43,12 +49,12 @@ on_realm_bus_signal(GDBusConnection *connection,
|
||||
|
||||
const gchar *realm_name = NULL;
|
||||
const gchar *description = NULL;
|
||||
const gchar *namespace = NULL;
|
||||
guint64 namespace;
|
||||
guint8 status = 0;
|
||||
|
||||
if (g_str_equal (signal_name, "RealmStarted")) {
|
||||
|
||||
g_variant_get (parameters, "(&s&sy)", &realm_name, &namespace, &status);
|
||||
g_variant_get (parameters, "(&sty)", &realm_name, &namespace, &status);
|
||||
shell_realms_on_realm_started (realms, realm_name, namespace, status);
|
||||
|
||||
} else if (g_str_equal (signal_name, "RealmStopped")) {
|
||||
@ -76,6 +82,50 @@ on_realm_bus_signal(GDBusConnection *connection,
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
bus_signal_subscribe (ShellRealmTracker *self, const gchar *signal_name)
|
||||
{
|
||||
g_assert(self->dbus);
|
||||
|
||||
return g_dbus_connection_signal_subscribe (self->dbus,
|
||||
REALMS_BUS_NAME,
|
||||
REALMS_MANAGER_INTERFACE,
|
||||
signal_name,
|
||||
REALMS_OBJECT_PATH,
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
on_realm_bus_signal,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
subscribe_bus_signals (ShellRealmTracker *self)
|
||||
{
|
||||
if (self->dbus) {
|
||||
int idx = 0;
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe (self, "RealmStarted");
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe (self, "RealmStopped");
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe (self, "RealmCurrent");
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe (self, "RealmNew");
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe (self, "RealmRemoved");
|
||||
g_assert(idx == NUM_BUS_SIGNAL_IDS);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unsubscribe_signals (ShellRealmTracker *self)
|
||||
{
|
||||
for (int i = 0; i < NUM_BUS_SIGNAL_IDS; i++) {
|
||||
if (self->bus_signal_ids[i]) {
|
||||
if (self->dbus) {
|
||||
g_dbus_connection_signal_unsubscribe (self->dbus, self->bus_signal_ids[i]);
|
||||
}
|
||||
self->bus_signal_ids[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
realm_state_process_elements (ShellRealmTracker *self, GVariant *response)
|
||||
{
|
||||
@ -83,25 +133,26 @@ realm_state_process_elements (ShellRealmTracker *self, GVariant *response)
|
||||
GVariantIter *iter = NULL;
|
||||
const gchar *name = NULL;
|
||||
const gchar *description = NULL;
|
||||
const gchar *namespace = NULL;
|
||||
guint64 namespace = 0;
|
||||
guchar status = 0;
|
||||
|
||||
ShellRealms *realms = shell_realms_get_default();
|
||||
ShellRealms *realms = shell_realms_get_default ();
|
||||
shell_realms_untag_all (realms);
|
||||
|
||||
g_variant_get(response, "(a(ssssy))", &iter);
|
||||
g_variant_get (response, "(a(sssty))", &iter);
|
||||
|
||||
// (name, desc, realmfs, namespace, status)
|
||||
while (g_variant_iter_next(iter, "(&s&ss&sy)", &name, &description, NULL, &namespace, &status)) {
|
||||
shell_realms_update_realm (realms, name, description, namespace, status);
|
||||
while (g_variant_iter_next (iter, "(&s&ssty)", &name, &description, NULL, &namespace, &status)) {
|
||||
shell_realms_process_list_realm (realms, name, description, namespace, status);
|
||||
}
|
||||
|
||||
shell_realms_remove_untagged (realms);
|
||||
g_variant_iter_free(iter);
|
||||
shell_realms_update_contexts (realms);
|
||||
g_variant_iter_free (iter);
|
||||
}
|
||||
|
||||
static void
|
||||
request_realm_state_finish(GObject *object, GAsyncResult *result, gpointer data)
|
||||
request_realm_state_finish (GObject *object, GAsyncResult *result, gpointer data)
|
||||
{
|
||||
ShellRealmTracker *self = data;
|
||||
|
||||
@ -111,7 +162,7 @@ request_realm_state_finish(GObject *object, GAsyncResult *result, gpointer data)
|
||||
|
||||
if (!response) {
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||
g_warning("MetaRealmDbus: Error calling 'List' bus method: %s", error->message);
|
||||
g_warning ("ShellRealmTracker: Error calling 'List' bus method: %s", error->message);
|
||||
}
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
@ -122,8 +173,9 @@ request_realm_state_finish(GObject *object, GAsyncResult *result, gpointer data)
|
||||
return;
|
||||
}
|
||||
|
||||
realm_state_process_elements(self, response);
|
||||
g_variant_unref(response);
|
||||
realm_state_process_elements (self, response);
|
||||
g_variant_unref (response);
|
||||
subscribe_bus_signals (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -163,6 +215,26 @@ call_dbus_method (ShellRealmTracker *self, const gchar *method, GVariant *parame
|
||||
user_data);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
call_dbus_method_sync (ShellRealmTracker *self, const gchar *method, GVariant *parameters, const GVariantType *reply_type, GError **error)
|
||||
{
|
||||
if (!self->dbus) {
|
||||
g_warning("ShellRealmTracker: call_dbus_method_sync (%s) called when no bus connection present", method);
|
||||
return NULL;
|
||||
}
|
||||
return g_dbus_connection_call_sync (self->dbus,
|
||||
REALMS_BUS_NAME,
|
||||
REALMS_OBJECT_PATH,
|
||||
REALMS_MANAGER_INTERFACE,
|
||||
method,
|
||||
parameters,
|
||||
reply_type,
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
static void
|
||||
request_realm_state(ShellRealmTracker *self)
|
||||
{
|
||||
@ -175,49 +247,42 @@ shell_realm_tracker_call_set_current (ShellRealmTracker *self, const char *realm
|
||||
call_dbus_method (self, "SetCurrent", g_variant_new("(s)", realm_name), set_realm_current_finish, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
unsubscribe_signals (ShellRealmTracker *self)
|
||||
gchar *
|
||||
shell_realm_tracker_call_realm_from_citadel_pid (ShellRealmTracker *self, pid_t pid)
|
||||
{
|
||||
for (int i = 0; i < NUM_BUS_SIGNAL_IDS; i++) {
|
||||
if (self->bus_signal_ids[i]) {
|
||||
if (self->dbus) {
|
||||
g_dbus_connection_signal_unsubscribe(self->dbus, self->bus_signal_ids[i]);
|
||||
}
|
||||
self->bus_signal_ids[i] = 0;
|
||||
}
|
||||
GError *error = NULL;
|
||||
GVariant *result;
|
||||
|
||||
guint32 code = 0;
|
||||
gchar *realm_name = NULL;
|
||||
gchar *retval = NULL;
|
||||
|
||||
if (!self->dbus) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static guint
|
||||
bus_signal_subscribe (ShellRealmTracker *self, const gchar *signal_name)
|
||||
{
|
||||
g_assert(self->dbus);
|
||||
result = call_dbus_method_sync (self, "RealmFromCitadelPid",
|
||||
g_variant_new("(u)", pid),
|
||||
G_VARIANT_TYPE("(us)"),
|
||||
&error);
|
||||
|
||||
return g_dbus_connection_signal_subscribe(self->dbus,
|
||||
REALMS_BUS_NAME,
|
||||
REALMS_MANAGER_INTERFACE,
|
||||
signal_name,
|
||||
REALMS_OBJECT_PATH,
|
||||
NULL,
|
||||
G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
on_realm_bus_signal,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
subscribe_bus_signals (ShellRealmTracker *self)
|
||||
{
|
||||
if (self->dbus) {
|
||||
int idx = 0;
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe(self, "RealmStarted");
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe(self, "RealmStopped");
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe(self, "RealmCurrent");
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe(self, "RealmNew");
|
||||
self->bus_signal_ids[idx++] = bus_signal_subscribe(self, "RealmRemoved");
|
||||
g_assert(idx == NUM_BUS_SIGNAL_IDS);
|
||||
if (!result) {
|
||||
if (error != NULL) {
|
||||
g_warning ("Error calling RealmCitadelFromPid(%d): %s", pid, error->message);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_variant_get (result, "(u&s)", &code, &realm_name);
|
||||
// g_warning("Calling RealmFromCitadelPid(%u) -> (%d,'%s')", pid, code, realm_name);
|
||||
|
||||
if (code == REALM_PID_LOOKUP_REALM) {
|
||||
retval = g_strdup (realm_name);
|
||||
} else if (code == REALM_PID_LOOKUP_CITADEL) {
|
||||
retval = g_strdup (CITADEL_REALM_TAG);
|
||||
}
|
||||
g_variant_unref (result);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -231,8 +296,7 @@ on_realm_manager_appeared (GDBusConnection *connection, const gchar *name, const
|
||||
}
|
||||
|
||||
if (!self->dbus) {
|
||||
self->dbus = g_object_ref(connection);
|
||||
subscribe_bus_signals (self);
|
||||
self->dbus = g_object_ref (connection);
|
||||
} else {
|
||||
g_warning("Realm tracker already has a connection in on_realm_manager_appeared()");
|
||||
}
|
||||
@ -240,7 +304,6 @@ on_realm_manager_appeared (GDBusConnection *connection, const gchar *name, const
|
||||
request_realm_state (self);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_realm_manager_vanished (GDBusConnection *connection, const gchar *name, gpointer user_data)
|
||||
{
|
||||
@ -255,7 +318,7 @@ on_realm_manager_vanished (GDBusConnection *connection, const gchar *name, gpoin
|
||||
g_clear_object (&self->dbus);
|
||||
}
|
||||
|
||||
unsubscribe_signals(self);
|
||||
unsubscribe_signals (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -273,7 +336,7 @@ shell_realm_tracker_get_default(void)
|
||||
return instance;
|
||||
}
|
||||
|
||||
void shell_realm_tracker_start ()
|
||||
void shell_realm_tracker_start (void)
|
||||
{
|
||||
ShellRealmTracker *tracker = shell_realm_tracker_get_default();
|
||||
|
||||
@ -282,7 +345,7 @@ void shell_realm_tracker_start ()
|
||||
return;
|
||||
}
|
||||
|
||||
tracker->realms_watch_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
|
||||
tracker->realms_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
|
||||
REALMS_BUS_NAME,
|
||||
G_BUS_NAME_WATCHER_FLAGS_NONE,
|
||||
on_realm_manager_appeared,
|
||||
@ -305,6 +368,6 @@ shell_realm_tracker_destroy(ShellRealmTracker *self)
|
||||
self->destroy_in_progress = TRUE;
|
||||
|
||||
// frees 'self' in destroy notifier
|
||||
g_bus_unwatch_name(self->realms_watch_id);
|
||||
g_bus_unwatch_name (self->realms_watch_id);
|
||||
|
||||
}
|
||||
|
@ -7,8 +7,10 @@
|
||||
G_DECLARE_FINAL_TYPE (ShellRealmTracker, shell_realm_tracker,
|
||||
SHELL, REALM_TRACKER, GObject)
|
||||
|
||||
ShellRealmTracker *shell_realm_tracker_get_default(void);
|
||||
ShellRealmTracker *shell_realm_tracker_get_default (void);
|
||||
void shell_realm_tracker_call_set_current (ShellRealmTracker *self, const char *realm_name);
|
||||
void shell_realm_tracker_start ();
|
||||
gchar *shell_realm_tracker_call_realm_from_citadel_pid (ShellRealmTracker *self, pid_t pid);
|
||||
void shell_realm_tracker_start (void);
|
||||
void shell_realm_tracker_destroy (ShellRealmTracker *self);
|
||||
|
||||
#endif /* __SHELL_REALM_TRACKER_H__ */
|
||||
|
@ -4,16 +4,18 @@
|
||||
#include "shell-realms.h"
|
||||
#include "shell-realms-window-frames.h"
|
||||
|
||||
#define CITADEL_REALM_TAG "[CITADEL]"
|
||||
|
||||
void shell_realms_untag_all (ShellRealms *realms);
|
||||
void shell_realms_remove_untagged (ShellRealms *realms);
|
||||
void shell_realms_update_realm (ShellRealms *realms,
|
||||
const char *realm_name,
|
||||
const char *description,
|
||||
const char *namespace,
|
||||
guint8 status);
|
||||
void shell_realms_update_contexts (ShellRealms *realms);
|
||||
void shell_realms_process_list_realm (ShellRealms *realms,
|
||||
const char *realm_name,
|
||||
const char *description,
|
||||
guint64 namespace,
|
||||
guint8 status);
|
||||
|
||||
void shell_realms_on_realm_started (ShellRealms *realms, const gchar *realm_name, const gchar *namespace, guint8 status);
|
||||
void shell_realms_on_realm_started (ShellRealms *realms, const gchar *realm_name, guint64 namespace, guint8 status);
|
||||
void shell_realms_on_realm_current (ShellRealms *realms, const gchar *realm_name);
|
||||
void shell_realms_on_realm_stopped (ShellRealms *realms, const gchar *realm_name);
|
||||
void shell_realms_on_realm_removed (ShellRealms *realms, const gchar *realm_name);
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
struct _ShellRealmsWindowFrames {
|
||||
GObject parent;
|
||||
ShellRealms *realms;
|
||||
GSettings *settings;
|
||||
GHashTable *realm_frame_colors;
|
||||
GList *default_colors;
|
||||
@ -24,6 +25,17 @@ enum {
|
||||
|
||||
static guint shell_realms_window_frames_signals [LAST_SIGNAL] = { 0 };
|
||||
|
||||
ShellRealmsWindowFrames *
|
||||
shell_realms_window_frames_new (ShellRealms *realms)
|
||||
{
|
||||
ShellRealmsWindowFrames *frames;
|
||||
|
||||
frames = g_object_new (SHELL_TYPE_REALMS_WINDOW_FRAMES, NULL);
|
||||
|
||||
frames->realms = realms;
|
||||
return frames;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_realms_window_frames_process_color (ShellRealmsWindowFrames *frames, const char *entry)
|
||||
{
|
||||
@ -32,13 +44,13 @@ shell_realms_window_frames_process_color (ShellRealmsWindowFrames *frames, const
|
||||
gchar **split = g_strsplit (entry, ":", -1);
|
||||
|
||||
if (g_strv_length (split) != 2) {
|
||||
g_warning("ShellRealmsWindowFrames: Unable to parse realm-frame-colors entry: %s", entry);
|
||||
g_warning ("ShellRealmsWindowFrames: Unable to parse realm-frame-colors entry: %s", entry);
|
||||
g_strfreev (split);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gdk_rgba_parse (&rgba, split[1])) {
|
||||
g_warning("ShellRealmsWindowFrames: Failed to parse RGBA component of realm frame color entry: %s", entry);
|
||||
g_warning ("ShellRealmsWindowFrames: Failed to parse RGBA component of realm frame color entry: %s", entry);
|
||||
} else {
|
||||
g_hash_table_insert (frames->realm_frame_colors, g_strdup (split[0]), gdk_rgba_copy (&rgba));
|
||||
}
|
||||
@ -62,7 +74,7 @@ load_realm_frame_colors (ShellRealmsWindowFrames *frames)
|
||||
}
|
||||
|
||||
static void
|
||||
on_realm_frame_colors_changed(GSettings *settings, const gchar *key, ShellRealmsWindowFrames *frames)
|
||||
on_realm_frame_colors_changed (GSettings *settings, const gchar *key, ShellRealmsWindowFrames *frames)
|
||||
{
|
||||
load_realm_frame_colors (frames);
|
||||
g_signal_emit (frames, shell_realms_window_frames_signals[REALM_FRAME_COLORS_CHANGED], 0);
|
||||
@ -78,7 +90,7 @@ load_default_colors (ShellRealmsWindowFrames *frames)
|
||||
entries = g_settings_get_strv (frames->settings, FRAME_COLOR_LIST_KEY);
|
||||
n_entries = g_strv_length (entries);
|
||||
|
||||
g_clear_list(&frames->default_colors, (GDestroyNotify) gdk_rgba_free);
|
||||
g_clear_list (&frames->default_colors, (GDestroyNotify) gdk_rgba_free);
|
||||
|
||||
for (i = 0; i < n_entries; i++) {
|
||||
if (gdk_rgba_parse (&rgba, entries[i])) {
|
||||
@ -102,12 +114,12 @@ shell_realms_window_frames_init (ShellRealmsWindowFrames *frames)
|
||||
frames->default_colors = NULL;
|
||||
frames->frame_disabled_windows = NULL;
|
||||
|
||||
g_signal_connect(frames->settings,
|
||||
g_signal_connect (frames->settings,
|
||||
"changed::" FRAME_COLOR_LIST_KEY,
|
||||
G_CALLBACK(on_frame_color_list_changed),
|
||||
frames);
|
||||
|
||||
g_signal_connect(frames->settings,
|
||||
g_signal_connect (frames->settings,
|
||||
"changed::" REALM_FRAME_COLORS_KEY,
|
||||
G_CALLBACK(on_realm_frame_colors_changed),
|
||||
frames);
|
||||
@ -172,7 +184,7 @@ add_to_disabled_list (ShellRealmsWindowFrames *frames, guint32 window_id)
|
||||
}
|
||||
|
||||
static gint
|
||||
color_compare(gconstpointer c1, gconstpointer c2) {
|
||||
color_compare (gconstpointer c1, gconstpointer c2) {
|
||||
return gdk_rgba_equal (c1, c2) ? 0 : 1;
|
||||
}
|
||||
|
||||
@ -199,7 +211,7 @@ allocate_color (ShellRealmsWindowFrames *frames)
|
||||
g_list_free (used_colors);
|
||||
|
||||
// 3) Choose a random element of the default list
|
||||
guint index = (guint) g_random_int_range(0, (gint32) n_colors);
|
||||
guint index = (guint) g_random_int_range (0, (gint32) n_colors);
|
||||
return g_list_nth_data (frames->default_colors, index);
|
||||
}
|
||||
|
||||
@ -209,11 +221,11 @@ shell_realms_window_frames_store_colors (ShellRealmsWindowFrames *frames)
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
GPtrArray *entries = g_ptr_array_new_with_free_func(g_free);
|
||||
GPtrArray *entries = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
g_hash_table_iter_init (&iter, frames->realm_frame_colors);
|
||||
|
||||
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
gchar *name = key;
|
||||
GdkRGBA *rgba = value;
|
||||
char *rgba_str = gdk_rgba_to_string (rgba);
|
||||
@ -230,10 +242,10 @@ shell_realms_window_frames_store_colors (ShellRealmsWindowFrames *frames)
|
||||
}
|
||||
|
||||
static const char *
|
||||
shell_realms_window_frames_realm_name_for_window (ShellRealmsWindowFrames *frames, ShellRealms *realms, MetaWindow *window)
|
||||
shell_realms_window_frames_realm_name_for_window (ShellRealmsWindowFrames *frames, MetaWindow *window)
|
||||
{
|
||||
|
||||
ShellRealmItem *realm = shell_realms_realm_by_window (realms, window);
|
||||
ShellRealmItem *realm = shell_realms_realm_by_window (frames->realms, window);
|
||||
|
||||
if (realm) {
|
||||
return shell_realm_item_get_realm_name (realm);
|
||||
@ -292,7 +304,7 @@ shell_realms_window_frames_is_frame_enabled (ShellRealmsWindowFrames *frames, Me
|
||||
gboolean
|
||||
shell_realms_window_frames_has_frame (ShellRealmsWindowFrames *frames, MetaWindow *window)
|
||||
{
|
||||
return !is_ignored_window(window) && meta_window_is_on_foreign_workspace_context (window);
|
||||
return !is_ignored_window (window) && shell_realms_is_foreign_window (frames->realms, window);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -342,9 +354,11 @@ shell_realms_window_frames_color_for_window (ShellRealmsWindowFrames *frames, Me
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ShellRealms *realms = shell_realms_get_default();
|
||||
const gchar *name = shell_realms_window_frames_realm_name_for_window (frames, window);
|
||||
|
||||
const gchar *name = shell_realms_window_frames_realm_name_for_window (frames, realms, window);
|
||||
if (name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkRGBA *rgba = g_hash_table_lookup (frames->realm_frame_colors, name);
|
||||
|
||||
@ -376,11 +390,9 @@ shell_realms_window_frames_label_for_window (ShellRealmsWindowFrames *frames, Me
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ShellRealms *realms = shell_realms_get_default();
|
||||
|
||||
if (shell_realms_is_citadel_window (realms, window)) {
|
||||
if (shell_realms_is_citadel_window (frames->realms, window)) {
|
||||
return "Citadel";
|
||||
} else {
|
||||
return shell_realms_window_frames_realm_name_for_window (frames, realms, window);
|
||||
return shell_realms_window_frames_realm_name_for_window (frames, window);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,9 @@
|
||||
#define SHELL_TYPE_REALMS_WINDOW_FRAMES (shell_realms_window_frames_get_type())
|
||||
G_DECLARE_FINAL_TYPE (ShellRealmsWindowFrames, shell_realms_window_frames, SHELL, REALMS_WINDOW_FRAMES, GObject)
|
||||
|
||||
typedef struct _ShellRealms ShellRealms;
|
||||
|
||||
ShellRealmsWindowFrames *shell_realms_window_frames_new (ShellRealms *realms);
|
||||
gboolean shell_realms_window_frames_has_frame (ShellRealmsWindowFrames *frames, MetaWindow *window);
|
||||
gboolean shell_realms_window_frames_is_frame_enabled (ShellRealmsWindowFrames *frames, MetaWindow *window);
|
||||
void shell_realms_window_frames_set_frame_enabled (ShellRealmsWindowFrames *frames, MetaWindow *window, gboolean enabled);
|
||||
|
@ -50,8 +50,12 @@ shell_realms_current_realm (ShellRealms *realms)
|
||||
* if name not found
|
||||
*/
|
||||
ShellRealmItem *
|
||||
shell_realms_realm_by_name(ShellRealms *realms, const gchar *realm_name)
|
||||
shell_realms_realm_by_name (ShellRealms *realms, const gchar *realm_name)
|
||||
{
|
||||
if (realm_name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ShellRealmItem *item = g_hash_table_lookup (realms->realms, realm_name);
|
||||
if (!item) {
|
||||
g_warning("ShellRealms: No realm found for name '%s'", realm_name);
|
||||
@ -83,6 +87,17 @@ shell_realms_realm_by_context_id (ShellRealms *realms, guint context_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
realm_name_from_window_pid (ShellRealms *realms, MetaWindow *window)
|
||||
{
|
||||
ShellRealmTracker *tracker = shell_realm_tracker_get_default();
|
||||
pid_t pid = meta_window_get_pid (window);
|
||||
if (pid > 0) {
|
||||
return shell_realm_tracker_call_realm_from_citadel_pid (tracker, pid);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_realms_realm_by_window:
|
||||
* @realms: a #ShellRealms instance
|
||||
@ -94,19 +109,14 @@ shell_realms_realm_by_context_id (ShellRealms *realms, guint context_id)
|
||||
ShellRealmItem *
|
||||
shell_realms_realm_by_window (ShellRealms *realms, MetaWindow *window)
|
||||
{
|
||||
const char *window_ns = meta_window_namespace (window);
|
||||
|
||||
if (!window_ns) {
|
||||
return NULL;
|
||||
ShellRealmItem *realm = NULL;
|
||||
gchar *realm_name = realm_name_from_window_pid (realms, window);
|
||||
// g_warning("shell_realms_realm_by_window() realm_name=%s", realm_name);
|
||||
if (realm_name && g_strcmp0 (CITADEL_REALM_TAG, realm_name)) {
|
||||
realm = shell_realms_realm_by_name (realms, realm_name);
|
||||
}
|
||||
|
||||
for (GList *iter = realms->running_realms; iter; iter = iter->next) {
|
||||
ShellRealmItem *item = iter->data;
|
||||
if (g_strcmp0 (window_ns, shell_realm_item_get_namespace (item)) == 0) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
g_free(realm_name);
|
||||
return realm;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,13 +132,26 @@ shell_realms_realm_by_window (ShellRealms *realms, MetaWindow *window)
|
||||
gboolean
|
||||
shell_realms_is_citadel_window (ShellRealms *realms, MetaWindow *window)
|
||||
{
|
||||
MetaDisplay *display = shell_global_get_display (shell_global_get());
|
||||
MetaWorkspaceManager *workspace_manager = meta_display_get_workspace_manager (display);
|
||||
gchar *realm_name = realm_name_from_window_pid (realms, window);
|
||||
gboolean is_citadel = g_strcmp0 (CITADEL_REALM_TAG, realm_name) == 0;
|
||||
g_free(realm_name);
|
||||
return is_citadel;
|
||||
}
|
||||
|
||||
const char *mutter_ns = meta_workspace_manager_mutter_namespace (workspace_manager);
|
||||
const char *window_ns = meta_window_namespace (window);
|
||||
|
||||
return g_strcmp0 (mutter_ns, window_ns) == 0;
|
||||
gboolean
|
||||
shell_realms_is_foreign_window (ShellRealms *realms, MetaWindow *window)
|
||||
{
|
||||
MetaWorkspace *workspace = meta_window_get_workspace (window);
|
||||
guint current_id = meta_workspace_get_context_id (workspace);
|
||||
|
||||
ShellRealmItem *realm_item = shell_realms_realm_by_window (realms, window);
|
||||
|
||||
if (current_id && realm_item) {
|
||||
guint realm_id = shell_realm_item_get_context_id (realm_item);
|
||||
return current_id != realm_id;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -237,9 +260,11 @@ static ShellRealmItem *
|
||||
shell_realms_add_realm_item (ShellRealms *realms,
|
||||
const char *realm_name,
|
||||
const char *description,
|
||||
const char *namespace,
|
||||
guint64 namespace,
|
||||
guint8 status)
|
||||
{
|
||||
g_assert (realm_name != NULL);
|
||||
|
||||
ShellRealmItem *item = g_hash_table_lookup (realms->realms, realm_name);
|
||||
if (item) {
|
||||
shell_realm_item_update (item, realm_name, namespace, status);
|
||||
@ -249,27 +274,120 @@ shell_realms_add_realm_item (ShellRealms *realms,
|
||||
item = shell_realm_item_new (realm_name, description, namespace, status);
|
||||
|
||||
if (shell_realm_item_is_system (item)) {
|
||||
g_clear_object(&item);
|
||||
g_clear_object (&item);
|
||||
return NULL;
|
||||
}
|
||||
g_hash_table_insert (realms->realms, g_strdup (realm_name), item);
|
||||
return item;
|
||||
}
|
||||
|
||||
void
|
||||
shell_realms_update_realm (ShellRealms *realms,
|
||||
const char *realm_name,
|
||||
const char *description,
|
||||
const char *namespace,
|
||||
guint8 status)
|
||||
static void
|
||||
remove_workspace_context (ShellRealmItem *realm)
|
||||
{
|
||||
ShellRealmItem *item = shell_realms_add_realm_item (realms, realm_name, description, namespace, status);
|
||||
MetaWorkspaceContext *context = shell_realm_item_get_context (realm);
|
||||
if (context) {
|
||||
shell_realm_item_set_context (realm, NULL);
|
||||
if (!meta_workspace_context_is_current (context)) {
|
||||
meta_workspace_context_remove (context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ignore system realms
|
||||
if (!item) {
|
||||
static ShellRealmItem *
|
||||
find_realm_with_context (ShellRealms *realms, MetaWorkspaceContext *context)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer value;
|
||||
|
||||
if (context == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, realms->realms);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value)) {
|
||||
ShellRealmItem *item = value;
|
||||
if (shell_realm_item_get_context (item) == context) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
acquire_active_workspace_context (ShellRealms *realms, ShellRealmItem *realm)
|
||||
{
|
||||
|
||||
MetaDisplay *display = shell_global_get_display (shell_global_get ());
|
||||
MetaWorkspaceManager *workspace_manager = meta_display_get_workspace_manager (display);
|
||||
MetaWorkspaceContext *active_context = meta_workspace_manager_active_context (workspace_manager);
|
||||
|
||||
if (shell_realm_item_get_context (realm) == active_context) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!shell_realm_item_is_current (realm)) {
|
||||
g_warning ("ShellRealms: Cannot acquire active workspace context for realm that is not the current realm");
|
||||
return;
|
||||
}
|
||||
|
||||
ShellRealmItem *other_realm = find_realm_with_context (realms, active_context);
|
||||
|
||||
if (other_realm) {
|
||||
g_warning ("Stealing active workspace context from realm-%s for realm-%s",
|
||||
shell_realm_item_get_realm_name(other_realm),
|
||||
shell_realm_item_get_realm_name(realm));
|
||||
|
||||
if (shell_realm_item_is_current (other_realm)) {
|
||||
shell_realm_item_set_current_flag (other_realm, false);
|
||||
}
|
||||
|
||||
shell_realm_item_set_context (other_realm, NULL);
|
||||
|
||||
if (shell_realm_item_is_running (other_realm)) {
|
||||
MetaWorkspaceContext *context = meta_workspace_context_new(workspace_manager);
|
||||
shell_realm_item_set_context(other_realm, context);
|
||||
}
|
||||
}
|
||||
|
||||
shell_realm_item_set_context (realm, active_context);
|
||||
}
|
||||
|
||||
static void
|
||||
acquire_workspace_context (ShellRealms *realms, ShellRealmItem *realm)
|
||||
{
|
||||
|
||||
if (shell_realm_item_is_system (realm) || shell_realm_item_get_context (realm) != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shell_realm_item_is_current (realm)) {
|
||||
acquire_active_workspace_context (realms, realm);
|
||||
return;
|
||||
}
|
||||
|
||||
MetaDisplay *display = shell_global_get_display(shell_global_get());
|
||||
MetaWorkspaceManager *workspace_manager = meta_display_get_workspace_manager(display);
|
||||
MetaWorkspaceContext *context = meta_workspace_context_new(workspace_manager);
|
||||
|
||||
shell_realm_item_set_context(realm, context);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
shell_realms_process_list_realm (ShellRealms *realms,
|
||||
const char *realm_name,
|
||||
const char *description,
|
||||
guint64 namespace,
|
||||
guint8 status)
|
||||
{
|
||||
|
||||
// Ignore system realms
|
||||
if (shell_realm_is_flag_set (status, SHELL_REALM_ITEM_STATUS_SYSTEM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ShellRealmItem *item = shell_realms_add_realm_item (realms, realm_name, description, namespace, status);
|
||||
|
||||
shell_realms_update_running_list_for_item (realms, item);
|
||||
shell_realm_item_set_tagged (item, TRUE);
|
||||
|
||||
@ -277,7 +395,11 @@ shell_realms_update_realm (ShellRealms *realms,
|
||||
// first context requested is for the current realm.
|
||||
if (shell_realm_item_is_current (item)) {
|
||||
shell_realms_set_current_item (realms, item);
|
||||
shell_realm_item_acquire_context (item);
|
||||
acquire_workspace_context (realms, item);
|
||||
}
|
||||
|
||||
if (!shell_realm_item_is_running (item) && shell_realm_item_get_context (item) != NULL) {
|
||||
remove_workspace_context (item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,26 +434,47 @@ shell_realms_remove_untagged (ShellRealms *realms)
|
||||
ShellRealmItem *item = value;
|
||||
if (!shell_realm_item_is_tagged (item)) {
|
||||
shell_realms_remove_running_realm (realms, item);
|
||||
remove_workspace_context (item);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shell_realms_update_contexts (ShellRealms *realms) {
|
||||
for (GList *iter = realms->running_realms; iter; iter = iter->next) {
|
||||
ShellRealmItem *item = iter->data;
|
||||
if (shell_realm_item_get_context (item) == NULL) {
|
||||
acquire_workspace_context (realms, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Signal handlers
|
||||
|
||||
void
|
||||
shell_realms_on_realm_started (ShellRealms *realms, const gchar *realm_name, const gchar *namespace, guint8 status)
|
||||
shell_realms_on_realm_started (ShellRealms *realms, const gchar *realm_name, guint64 namespace, guint8 status)
|
||||
{
|
||||
ShellRealmItem *item = shell_realms_realm_by_name (realms, realm_name);
|
||||
if (item) {
|
||||
shell_realm_item_update (item, realm_name, namespace, status);
|
||||
if (!shell_realm_item_is_system (item)) {
|
||||
shell_realms_update_running_list_for_item (realms, item);
|
||||
shell_realm_item_acquire_context (item);
|
||||
acquire_workspace_context(realms, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
activate_workspace_context (ShellRealmItem *realm)
|
||||
{
|
||||
MetaWorkspaceContext *context = shell_realm_item_get_context (realm);
|
||||
if (context) {
|
||||
meta_workspace_context_activate (context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
shell_realms_on_realm_current (ShellRealms *realms, const gchar *realm_name)
|
||||
{
|
||||
@ -340,7 +483,7 @@ shell_realms_on_realm_current (ShellRealms *realms, const gchar *realm_name)
|
||||
if (item && realms->current_realm != item) {
|
||||
shell_realms_set_current_item (realms, item);
|
||||
shell_realms_update_running_list_for_item (realms, item);
|
||||
shell_realm_item_activate_context (item);
|
||||
activate_workspace_context (item);
|
||||
g_signal_emit (realms, shell_realms_signals[REALM_CONTEXT_SWITCHED], 0);
|
||||
}
|
||||
}
|
||||
@ -351,6 +494,7 @@ shell_realms_on_realm_stopped (ShellRealms *realms, const gchar *realm_name)
|
||||
ShellRealmItem *item = shell_realms_realm_by_name (realms, realm_name);
|
||||
if (item) {
|
||||
shell_realm_item_set_running_flag (item, FALSE);
|
||||
remove_workspace_context (item);
|
||||
shell_realms_remove_running_realm (realms, item);
|
||||
}
|
||||
}
|
||||
@ -360,6 +504,9 @@ shell_realms_on_realm_removed (ShellRealms *realms, const gchar *realm_name)
|
||||
{
|
||||
ShellRealmItem *item = shell_realms_realm_by_name (realms, realm_name);
|
||||
if (item) {
|
||||
shell_realm_item_set_running_flag (item, FALSE);
|
||||
remove_workspace_context (item);
|
||||
|
||||
shell_realms_remove_running_realm (realms, item);
|
||||
g_hash_table_remove (realms->realms, realm_name);
|
||||
}
|
||||
@ -368,10 +515,14 @@ shell_realms_on_realm_removed (ShellRealms *realms, const gchar *realm_name)
|
||||
void
|
||||
shell_realms_on_realm_new (ShellRealms *realms, const gchar *realm_name, const gchar *description, guint8 status)
|
||||
{
|
||||
if (realm_name == NULL || shell_realm_is_flag_set (status, SHELL_REALM_ITEM_STATUS_SYSTEM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_hash_table_contains (realms->realms, realm_name)) {
|
||||
(void) shell_realms_add_realm_item (realms, realm_name, description, NULL, status);
|
||||
(void) shell_realms_add_realm_item (realms, realm_name, description, 0, status);
|
||||
} else {
|
||||
g_warning("ShellRealms: RealmNew signal received for realm '%s' but it already exists", realm_name);
|
||||
g_warning ("ShellRealms: RealmNew signal received for realm '%s' but it already exists", realm_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,7 +548,7 @@ shell_realms_init(ShellRealms *realms)
|
||||
realms->realms = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
realms->running_realms = NULL;
|
||||
realms->current_realm = NULL;
|
||||
realms->frames = g_object_new (SHELL_TYPE_REALMS_WINDOW_FRAMES, NULL);
|
||||
realms->frames = shell_realms_window_frames_new (realms);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -457,4 +608,4 @@ shell_realms_class_init (ShellRealmsClass *klass)
|
||||
"The currently active realm",
|
||||
SHELL_TYPE_REALM_ITEM,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,11 @@ ShellRealms *shell_realms_get_default(void);
|
||||
|
||||
|
||||
ShellRealmItem *shell_realms_current_realm (ShellRealms *realms);
|
||||
ShellRealmItem *shell_realms_realm_by_name(ShellRealms *realms, const gchar *realm_name);
|
||||
ShellRealmItem *shell_realms_realm_by_name (ShellRealms *realms, const gchar *realm_name);
|
||||
ShellRealmItem *shell_realms_realm_by_context_id (ShellRealms *realms, guint context_id);
|
||||
ShellRealmItem *shell_realms_realm_by_window (ShellRealms *realms, MetaWindow *window);
|
||||
gboolean shell_realms_is_citadel_window (ShellRealms *realms, MetaWindow *window);
|
||||
gboolean shell_realms_is_foreign_window (ShellRealms *realms, MetaWindow *window);
|
||||
|
||||
ShellRealmsWindowFrames *shell_realms_window_frames (ShellRealms *realms);
|
||||
|
||||
|
@ -217,6 +217,9 @@ get_app_from_window_wmclass (MetaWindow *window)
|
||||
|
||||
/* first try a match from WM_CLASS (instance part) to StartupWMClass */
|
||||
wm_instance = meta_window_get_wm_class_instance (window);
|
||||
if (realm_name) {
|
||||
// g_warning ("ShellWindowTracker: get_app_from_window_class(wmclass: %s, realm: %s)", wm_instance, realm_name);
|
||||
}
|
||||
app = shell_app_system_lookup_startup_wmclass (appsys, wm_instance, realm_name);
|
||||
if (app != NULL && check_app_id_prefix (app, app_prefix))
|
||||
return g_object_ref (app);
|
||||
|
Loading…
Reference in New Issue
Block a user