introspect: Enhance WindowsChanged DBus API

Splits WindowsChanged into 3 signals: WindowAdded, WindowChanged,
WindowRemoved and nclude the window as an argument.  This gives us
the necessary information to tracked each window changed, rather than
requiring continuous calls to GetWindows (returning all windows).

The main consumer of the shell-introspect signals is
xdg-desktop-portal-gnome, so an API break seems reasonable, rather
than introducing a new API.

See: https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/merge_requests/93
This commit is contained in:
Corey Berla 2023-08-16 10:24:19 -07:00
parent 4326a2d568
commit 7b45ac72ec
4 changed files with 56 additions and 9 deletions

View file

@ -19,11 +19,26 @@
<signal name="RunningApplicationsChanged" />
<!--
WindowsChanged:
@short_description: Notifies when any window opens or closes
WindowAdded:
@short_description: Notifies when any window opens
-->
<signal name="WindowsChanged" />
<signal name="WindowAdded">
<arg type="a{sv}" name="window" />
</signal>
<!--
WindowChanged:
@short_description: Notifies when any window changes
-->
<signal name="WindowChanged">
<arg type="a{sv}" name="window" />
</signal>
<!--
WindowRemoved:
@short_description: Notifies when any window closes
-->
<signal name="WindowRemoved">
<arg type="a{sv}" name="window" />
</signal>
<!--
GetRunningApplications:
@short_description: Retrieves the description of all running applications

View file

@ -44,7 +44,25 @@ export class IntrospectService {
});
tracker.connect('tracked-windows-changed',
() => this._dbusImpl.emit_signal('WindowsChanged', null));
(self, window, app, action) => {
if (!this._isEligibleWindow(window))
return;
let windowDict = this._getWindowDict(window, app);
let windowVariant = new GLib.Variant('(a{sv})', [windowDict]);
switch (action) {
case Shell.WindowTrackerAction.ADDED:
this._dbusImpl.emit_signal('WindowAdded', windowVariant);
break;
case Shell.WindowTrackerAction.CHANGED:
this._dbusImpl.emit_signal('WindowChanged', windowVariant);
break;
case Shell.WindowTrackerAction.REMOVED:
this._dbusImpl.emit_signal('WindowRemoved', windowVariant);
break;
default:
log(`Incorrect window action ${action}`);
}
});
this._syncRunningApplications();

View file

@ -122,7 +122,9 @@ shell_window_tracker_class_init (ShellWindowTrackerClass *klass)
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
G_TYPE_NONE,
3, META_TYPE_WINDOW, SHELL_TYPE_APP,
G_TYPE_INT);
}
static gboolean
@ -529,8 +531,12 @@ on_title_changed (MetaWindow *window,
GParamSpec *pspec,
gpointer user_data)
{
ShellApp *app;
ShellWindowTracker *self = SHELL_WINDOW_TRACKER (user_data);
g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0);
app = get_app_for_window (self, window);
g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0, window, app, SHELL_WINDOW_TRACKER_CHANGED);
}
static void
@ -569,7 +575,7 @@ track_window (ShellWindowTracker *self,
_shell_app_add_window (app, window);
g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0);
g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0, window, app, SHELL_WINDOW_TRACKER_ADDED);
}
static void
@ -590,6 +596,7 @@ disassociate_window (ShellWindowTracker *self,
if (!app)
return;
g_object_ref (window);
g_object_ref (app);
g_hash_table_remove (self->window_to_app, window);
@ -600,8 +607,9 @@ disassociate_window (ShellWindowTracker *self,
g_signal_handlers_disconnect_by_func (window, G_CALLBACK (on_gtk_application_id_changed), self);
g_signal_handlers_disconnect_by_func (window, G_CALLBACK (on_window_unmanaged), self);
g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0);
g_signal_emit (self, signals[TRACKED_WINDOWS_CHANGED], 0, window, app, SHELL_WINDOW_TRACKER_REMOVED);
g_object_unref (window);
g_object_unref (app);
}

View file

@ -16,6 +16,12 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (ShellWindowTracker, shell_window_tracker,
SHELL, WINDOW_TRACKER, GObject)
typedef enum {
SHELL_WINDOW_TRACKER_ADDED,
SHELL_WINDOW_TRACKER_CHANGED,
SHELL_WINDOW_TRACKER_REMOVED
} ShellWindowTrackerAction;
ShellWindowTracker* shell_window_tracker_get_default(void);
ShellApp *shell_window_tracker_get_window_app (ShellWindowTracker *tracker, MetaWindow *metawin);