window: Add cgroup management to MetaWindow
Currently the only way to get cgroup for a MetaWindow is to get it's PID and perform a bunch of file accesses and string manipulations. This is especially not feasible if we want to get the cgroup every time a MetaWindow has gained or lost focus. A solution to this is to cache the GFile for a cgroup path. The creation and access of this GFile is handled by `meta_window_get_unit_cgroup` function. `meta_window_unit_cgroup_equal` is a utility function which allows us to compare whether two MetaWindows belong to the same cgroup. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1960>
This commit is contained in:
parent
4a0c86ea4c
commit
c2efe25597
2 changed files with 86 additions and 0 deletions
|
@ -565,6 +565,9 @@ struct _MetaWindow
|
|||
guint unmanage_idle_id;
|
||||
|
||||
pid_t client_pid;
|
||||
|
||||
gboolean has_valid_cgroup;
|
||||
GFile *cgroup_path;
|
||||
};
|
||||
|
||||
struct _MetaWindowClass
|
||||
|
@ -890,4 +893,8 @@ gboolean meta_window_shortcuts_inhibited (MetaWindow *window,
|
|||
ClutterInputDevice *source);
|
||||
gboolean meta_window_is_stackable (MetaWindow *window);
|
||||
gboolean meta_window_is_focus_async (MetaWindow *window);
|
||||
|
||||
GFile *meta_window_get_unit_cgroup (MetaWindow *window);
|
||||
gboolean meta_window_unit_cgroup_equal (MetaWindow *window1,
|
||||
MetaWindow *window2);
|
||||
#endif
|
||||
|
|
|
@ -97,6 +97,10 @@
|
|||
#include "wayland/meta-window-xwayland.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBSYSTEMD
|
||||
#include <systemd/sd-login.h>
|
||||
#endif
|
||||
|
||||
/* Windows that unmaximize to a size bigger than that fraction of the workarea
|
||||
* will be scaled down to that size (while maintaining aspect ratio).
|
||||
* Windows that cover an area greater then this size are automaximized on map.
|
||||
|
@ -332,6 +336,9 @@ meta_window_finalize (GObject *object)
|
|||
if (window->transient_for)
|
||||
g_object_unref (window->transient_for);
|
||||
|
||||
if (window->cgroup_path)
|
||||
g_object_unref (window->cgroup_path);
|
||||
|
||||
g_free (window->sm_client_id);
|
||||
g_free (window->wm_client_machine);
|
||||
g_free (window->startup_id);
|
||||
|
@ -1157,6 +1164,9 @@ _meta_window_shared_new (MetaDisplay *display,
|
|||
|
||||
window->client_pid = 0;
|
||||
|
||||
window->has_valid_cgroup = TRUE;
|
||||
window->cgroup_path = NULL;
|
||||
|
||||
window->xtransient_for = None;
|
||||
window->xclient_leader = None;
|
||||
|
||||
|
@ -7736,6 +7746,75 @@ meta_window_get_pid (MetaWindow *window)
|
|||
return window->client_pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_unit_cgroup:
|
||||
* @window: a #MetaWindow
|
||||
*
|
||||
* Return value: a GFile for the cgroup path, or NULL.
|
||||
*/
|
||||
GFile *
|
||||
meta_window_get_unit_cgroup (MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_LIBSYSTEMD
|
||||
g_autofree char *contents = NULL;
|
||||
g_autofree char *complete_path = NULL;
|
||||
g_autofree char *unit_name = NULL;
|
||||
g_autofree char *unit_path = NULL;
|
||||
char *unit_end;
|
||||
pid_t pid;
|
||||
|
||||
if (!window->has_valid_cgroup)
|
||||
return NULL;
|
||||
|
||||
if (window->cgroup_path)
|
||||
return window->cgroup_path;
|
||||
|
||||
pid = meta_window_get_pid (window);
|
||||
if (pid < 1)
|
||||
return NULL;
|
||||
|
||||
if (sd_pid_get_cgroup (pid, &contents) < 0)
|
||||
{
|
||||
window->has_valid_cgroup = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
g_strstrip (contents);
|
||||
|
||||
complete_path = g_strdup_printf ("%s%s", "/sys/fs/cgroup", contents);
|
||||
|
||||
if (sd_pid_get_user_unit (pid, &unit_name) < 0)
|
||||
{
|
||||
window->has_valid_cgroup = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
g_strstrip (unit_name);
|
||||
|
||||
unit_end = strstr (complete_path, unit_name) + strlen (unit_name);
|
||||
*unit_end = '\0';
|
||||
|
||||
window->cgroup_path = g_file_new_for_path (complete_path);
|
||||
|
||||
return window->cgroup_path;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_unit_cgroup_equal (MetaWindow *window1,
|
||||
MetaWindow *window2)
|
||||
{
|
||||
GFile *window1_file, *window2_file;
|
||||
|
||||
window1_file = meta_window_get_unit_cgroup (window1);
|
||||
window2_file = meta_window_get_unit_cgroup (window2);
|
||||
|
||||
if (!window1_file || !window2_file)
|
||||
return FALSE;
|
||||
|
||||
return g_file_equal (window1_file, window2_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_get_client_machine:
|
||||
* @window: a #MetaWindow
|
||||
|
|
Loading…
Reference in a new issue