Add a panel containing tasklist to bottom screen
This is implemented as a separate process, since creating and running toplevel windows from inside Metacity has issues. We now grab a DBus name, and exec the child process. The child monitors our name to know when to exit. svn path=/trunk/; revision=153
This commit is contained in:
parent
5afcf07782
commit
70a3434b5a
@ -98,8 +98,8 @@ Signals.addSignalMethods(ClutterFrameTicker.prototype);
|
|||||||
function start() {
|
function start() {
|
||||||
let global = Shell.Global.get();
|
let global = Shell.Global.get();
|
||||||
|
|
||||||
// Here we grab our DBus name, etc.
|
global.grab_dbus_service();
|
||||||
global.late_init();
|
global.start_task_panel();
|
||||||
|
|
||||||
Tweener.setFrameTicker(new ClutterFrameTicker());
|
Tweener.setFrameTicker(new ClutterFrameTicker());
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ class Launcher:
|
|||||||
env.update({'GNOME_SHELL_JS' : self.js_dir,
|
env.update({'GNOME_SHELL_JS' : self.js_dir,
|
||||||
'GNOME_SHELL_DATADIR' : self.data_dir,
|
'GNOME_SHELL_DATADIR' : self.data_dir,
|
||||||
'GI_TYPELIB_PATH' : self.plugin_dir,
|
'GI_TYPELIB_PATH' : self.plugin_dir,
|
||||||
|
'PATH' : os.environ.get('PATH', '') + ':' + self.plugin_dir,
|
||||||
'LD_LIBRARY_PATH' : os.environ.get('LD_LIBRARY_PATH', '') + ':' + self.plugin_dir,
|
'LD_LIBRARY_PATH' : os.environ.get('LD_LIBRARY_PATH', '') + ':' + self.plugin_dir,
|
||||||
'GNOME_DISABLE_CRASH_DIALOG' : '1'})
|
'GNOME_DISABLE_CRASH_DIALOG' : '1'})
|
||||||
|
|
||||||
|
@ -18,10 +18,12 @@ on_name_owner_changed (DBusGProxy *proxy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
monitor_main_shell ()
|
monitor_main_shell (const char *shell_name)
|
||||||
{
|
{
|
||||||
DBusGConnection *session;
|
DBusGConnection *session;
|
||||||
DBusGProxy *driver;
|
DBusGProxy *driver;
|
||||||
|
GError *error = NULL;
|
||||||
|
gboolean have_shell;
|
||||||
|
|
||||||
session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
|
session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
|
||||||
|
|
||||||
@ -30,6 +32,19 @@ monitor_main_shell ()
|
|||||||
DBUS_PATH_DBUS,
|
DBUS_PATH_DBUS,
|
||||||
DBUS_INTERFACE_DBUS);
|
DBUS_INTERFACE_DBUS);
|
||||||
|
|
||||||
|
if (!dbus_g_proxy_call (driver, "NameHasOwner", &error, G_TYPE_STRING,
|
||||||
|
shell_name, G_TYPE_INVALID, G_TYPE_BOOLEAN,
|
||||||
|
&have_shell, G_TYPE_INVALID))
|
||||||
|
{
|
||||||
|
/* Shouldn't happen */
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
if (!have_shell)
|
||||||
|
{
|
||||||
|
/* Shell doesn't exist; either crashed or was restarted. Just abort. */
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
dbus_g_proxy_add_signal (driver,
|
dbus_g_proxy_add_signal (driver,
|
||||||
"NameOwnerChanged",
|
"NameOwnerChanged",
|
||||||
G_TYPE_STRING,
|
G_TYPE_STRING,
|
||||||
@ -53,7 +68,12 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
gtk_init (&argc, &argv);
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
monitor_main_shell ();
|
if (argc != 2) {
|
||||||
|
g_printerr ("Usage: gnomeshell-taskpanel [PARENT_DBUS_SERVICE]\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor_main_shell (argv[1]);
|
||||||
|
|
||||||
panel = shell_panel_window_new ();
|
panel = shell_panel_window_new ();
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
#include <dbus/dbus-glib.h>
|
#include <dbus/dbus-glib.h>
|
||||||
#include <libgnomeui/gnome-thumbnail.h>
|
#include <libgnomeui/gnome-thumbnail.h>
|
||||||
|
|
||||||
|
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
|
||||||
|
|
||||||
struct _ShellGlobal {
|
struct _ShellGlobal {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
@ -460,25 +462,13 @@ shell_global_reexec_self (ShellGlobal *global)
|
|||||||
g_ptr_array_free (arr, TRUE);
|
g_ptr_array_free (arr, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* shell_global_late_init
|
|
||||||
*
|
|
||||||
* Perform once-only global initialization; currently this executes
|
|
||||||
* the external tasklist process and grabs the org.gnome.Shell DBus name.
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
shell_global_late_init (ShellGlobal *global)
|
shell_global_grab_dbus_service (ShellGlobal *global)
|
||||||
{
|
{
|
||||||
static gboolean initialized = FALSE;
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
DBusGConnection *session;
|
DBusGConnection *session;
|
||||||
DBusGProxy *bus;
|
DBusGProxy *bus;
|
||||||
guint32 request_name_result;
|
guint32 request_name_result;
|
||||||
const char* panel_args[] = {"gnomeshell-taskpanel", NULL};
|
|
||||||
|
|
||||||
if (initialized)
|
|
||||||
return;
|
|
||||||
initialized = TRUE;
|
|
||||||
|
|
||||||
session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
|
session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
|
||||||
|
|
||||||
@ -488,20 +478,32 @@ shell_global_late_init (ShellGlobal *global)
|
|||||||
DBUS_INTERFACE_DBUS);
|
DBUS_INTERFACE_DBUS);
|
||||||
|
|
||||||
if (!dbus_g_proxy_call (bus, "RequestName", &error,
|
if (!dbus_g_proxy_call (bus, "RequestName", &error,
|
||||||
G_TYPE_STRING, "org.gnome.Shell",
|
G_TYPE_STRING, SHELL_DBUS_SERVICE,
|
||||||
G_TYPE_UINT, 0,
|
G_TYPE_UINT, 0,
|
||||||
G_TYPE_INVALID,
|
G_TYPE_INVALID,
|
||||||
G_TYPE_UINT, &request_name_result,
|
G_TYPE_UINT, &request_name_result,
|
||||||
G_TYPE_INVALID)) {
|
G_TYPE_INVALID))
|
||||||
|
{
|
||||||
g_print ("failed to acquire org.gnome.Shell: %s\n", error->message);
|
g_print ("failed to acquire org.gnome.Shell: %s\n", error->message);
|
||||||
|
/* If we somehow got started again, it's not an error to be running
|
||||||
|
* already. So just exit 0.
|
||||||
|
*/
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!g_spawn_async (NULL, &panel_args, NULL, G_SPAWN_SEARCH_PATH, NULL,
|
|
||||||
NULL, NULL, &error)) {
|
|
||||||
g_critical ("failed to execute %s: %s", panel_args[0], error->message);
|
|
||||||
g_clear_error (&error);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (bus);
|
g_object_unref (bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
shell_global_start_task_panel (ShellGlobal *global)
|
||||||
|
{
|
||||||
|
const char* panel_args[] = {"gnomeshell-taskpanel", SHELL_DBUS_SERVICE, NULL};
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!g_spawn_async (NULL, (char**) panel_args, NULL, G_SPAWN_SEARCH_PATH, NULL,
|
||||||
|
NULL, NULL, &error))
|
||||||
|
{
|
||||||
|
g_critical ("failed to execute %s: %s", panel_args[0], error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,9 @@ GdkPixbuf *shell_get_thumbnail_for_recent_info(GtkRecentInfo *recent_info);
|
|||||||
|
|
||||||
ShellGlobal *shell_global_get (void);
|
ShellGlobal *shell_global_get (void);
|
||||||
|
|
||||||
void shell_global_late_init (ShellGlobal *global);
|
void shell_global_grab_dbus_service (ShellGlobal *global);
|
||||||
|
|
||||||
|
void shell_global_start_task_panel (ShellGlobal *global);
|
||||||
|
|
||||||
void shell_global_set_stage_input_area (ShellGlobal *global,
|
void shell_global_set_stage_input_area (ShellGlobal *global,
|
||||||
int x,
|
int x,
|
||||||
|
@ -10,16 +10,7 @@ enum {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void shell_panel_window_dispose (GObject *object);
|
|
||||||
static void shell_panel_window_finalize (GObject *object);
|
static void shell_panel_window_finalize (GObject *object);
|
||||||
static void shell_panel_window_set_property ( GObject *object,
|
|
||||||
guint property_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec );
|
|
||||||
static void shell_panel_window_get_property( GObject *object,
|
|
||||||
guint property_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec );
|
|
||||||
static void shell_panel_window_size_request (GtkWidget *self, GtkRequisition *req);
|
static void shell_panel_window_size_request (GtkWidget *self, GtkRequisition *req);
|
||||||
static void shell_panel_window_size_allocate (GtkWidget *self, GtkAllocation *allocation);
|
static void shell_panel_window_size_allocate (GtkWidget *self, GtkAllocation *allocation);
|
||||||
static void shell_panel_window_realize (GtkWidget *self);
|
static void shell_panel_window_realize (GtkWidget *self);
|
||||||
@ -36,6 +27,8 @@ G_DEFINE_TYPE(ShellPanelWindow, shell_panel_window, GTK_TYPE_WINDOW);
|
|||||||
struct ShellPanelWindowPrivate {
|
struct ShellPanelWindowPrivate {
|
||||||
GtkAllocation workarea;
|
GtkAllocation workarea;
|
||||||
guint width;
|
guint width;
|
||||||
|
guint height;
|
||||||
|
Atom workarea_atom;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -44,10 +37,7 @@ shell_panel_window_class_init(ShellPanelWindowClass *klass)
|
|||||||
GObjectClass *gobject_class = (GObjectClass *)klass;
|
GObjectClass *gobject_class = (GObjectClass *)klass;
|
||||||
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
|
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
|
||||||
|
|
||||||
gobject_class->dispose = shell_panel_window_dispose;
|
|
||||||
gobject_class->finalize = shell_panel_window_finalize;
|
gobject_class->finalize = shell_panel_window_finalize;
|
||||||
gobject_class->set_property = shell_panel_window_set_property;
|
|
||||||
gobject_class->get_property = shell_panel_window_get_property;
|
|
||||||
|
|
||||||
widget_class->realize = shell_panel_window_realize;
|
widget_class->realize = shell_panel_window_realize;
|
||||||
widget_class->size_request = shell_panel_window_size_request;
|
widget_class->size_request = shell_panel_window_size_request;
|
||||||
@ -59,18 +49,13 @@ static void shell_panel_window_init (ShellPanelWindow *self)
|
|||||||
{
|
{
|
||||||
self->priv = g_new0 (ShellPanelWindowPrivate, 1);
|
self->priv = g_new0 (ShellPanelWindowPrivate, 1);
|
||||||
|
|
||||||
|
self->priv->workarea_atom = gdk_x11_get_xatom_by_name_for_display (gdk_display_get_default (), "_NET_WORKAREA");
|
||||||
|
|
||||||
gtk_window_set_type_hint (GTK_WINDOW (self), GDK_WINDOW_TYPE_HINT_DOCK);
|
gtk_window_set_type_hint (GTK_WINDOW (self), GDK_WINDOW_TYPE_HINT_DOCK);
|
||||||
gtk_window_set_focus_on_map (GTK_WINDOW (self), FALSE);
|
gtk_window_set_focus_on_map (GTK_WINDOW (self), FALSE);
|
||||||
gdk_window_add_filter (NULL, filter_func, self);
|
gdk_window_add_filter (NULL, filter_func, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shell_panel_window_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
ShellPanelWindow *self = (ShellPanelWindow*)object;
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (shell_panel_window_parent_class)->dispose(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void shell_panel_window_finalize (GObject *object)
|
static void shell_panel_window_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
ShellPanelWindow *self = (ShellPanelWindow*)object;
|
ShellPanelWindow *self = (ShellPanelWindow*)object;
|
||||||
@ -80,53 +65,24 @@ static void shell_panel_window_finalize (GObject *object)
|
|||||||
G_OBJECT_CLASS (shell_panel_window_parent_class)->finalize(object);
|
G_OBJECT_CLASS (shell_panel_window_parent_class)->finalize(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shell_panel_window_set_property ( GObject *object,
|
ShellPanelWindow* shell_panel_window_new(void) {
|
||||||
guint property_id,
|
|
||||||
const GValue *value,
|
|
||||||
GParamSpec *pspec )
|
|
||||||
{
|
|
||||||
ShellPanelWindow* self = SHELL_PANEL_WINDOW(object);
|
|
||||||
switch (property_id) {
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void shell_panel_window_get_property ( GObject *object,
|
|
||||||
guint property_id,
|
|
||||||
GValue *value,
|
|
||||||
GParamSpec *pspec )
|
|
||||||
{
|
|
||||||
ShellPanelWindow* self = SHELL_PANEL_WINDOW(object);
|
|
||||||
switch (property_id) {
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ShellPanelWindow* shell_panel_window_new(void)
|
|
||||||
{
|
|
||||||
return (ShellPanelWindow*) g_object_new(SHELL_TYPE_PANEL_WINDOW,
|
return (ShellPanelWindow*) g_object_new(SHELL_TYPE_PANEL_WINDOW,
|
||||||
"type", GTK_WINDOW_TOPLEVEL, NULL);
|
"type", GTK_WINDOW_TOPLEVEL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_strut (ShellPanelWindow *self)
|
set_strut (ShellPanelWindow *self)
|
||||||
{
|
{
|
||||||
long *buf;
|
long *buf;
|
||||||
int x, y;
|
|
||||||
int strut_size;
|
int strut_size;
|
||||||
|
|
||||||
strut_size = GTK_WIDGET (self)->allocation.height;
|
strut_size = GTK_WIDGET (self)->allocation.height;
|
||||||
|
|
||||||
gtk_window_get_position (GTK_WINDOW (self), &x, &y);
|
buf = g_new0 (long, 4);
|
||||||
|
buf[0] = 0; /* left */
|
||||||
buf = g_new0(long, 4);
|
buf[1] = 0; /* right */
|
||||||
buf[3] = strut_size;
|
buf[2] = 0; /* top */
|
||||||
|
buf[3] = strut_size; /* bottom */
|
||||||
gdk_property_change (GTK_WIDGET (self)->window, gdk_atom_intern_static_string ("_NET_WM_STRUT"),
|
gdk_property_change (GTK_WIDGET (self)->window, gdk_atom_intern_static_string ("_NET_WM_STRUT"),
|
||||||
gdk_atom_intern_static_string ("CARDINAL"), 32,
|
gdk_atom_intern_static_string ("CARDINAL"), 32,
|
||||||
GDK_PROP_MODE_REPLACE,
|
GDK_PROP_MODE_REPLACE,
|
||||||
@ -171,26 +127,44 @@ shell_panel_window_show (GtkWidget *widget)
|
|||||||
static void
|
static void
|
||||||
handle_new_workarea (ShellPanelWindow *self)
|
handle_new_workarea (ShellPanelWindow *self)
|
||||||
{
|
{
|
||||||
int monitor;
|
|
||||||
GtkRequisition requisition;
|
GtkRequisition requisition;
|
||||||
GdkRectangle monitor_geometry;
|
|
||||||
int x, y;
|
int x, y;
|
||||||
int width;
|
int width;
|
||||||
|
int height;
|
||||||
|
int x_target, y_target;
|
||||||
|
|
||||||
monitor = gdk_screen_get_monitor_at_point (gdk_screen_get_default (),
|
|
||||||
self->priv->workarea.x,
|
|
||||||
self->priv->workarea.y);
|
|
||||||
gdk_screen_get_monitor_geometry (gdk_screen_get_default (),
|
|
||||||
monitor, &monitor_geometry);
|
|
||||||
gtk_widget_size_request (GTK_WIDGET (self), &requisition);
|
gtk_widget_size_request (GTK_WIDGET (self), &requisition);
|
||||||
|
|
||||||
|
/* If we don't have a workarea, just use monitor */
|
||||||
|
if (self->priv->workarea.width == 0)
|
||||||
|
{
|
||||||
|
int monitor;
|
||||||
|
GdkRectangle monitor_geometry;
|
||||||
|
|
||||||
|
monitor = gdk_screen_get_monitor_at_point (gdk_screen_get_default (),
|
||||||
|
0, 0);
|
||||||
|
gdk_screen_get_monitor_geometry (gdk_screen_get_default (),
|
||||||
|
monitor, &monitor_geometry);
|
||||||
|
x = monitor_geometry.x;
|
||||||
|
y = monitor_geometry.y;
|
||||||
|
width = monitor_geometry.width;
|
||||||
|
height = monitor_geometry.height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
x = self->priv->workarea.x;
|
x = self->priv->workarea.x;
|
||||||
y = monitor_geometry.y + monitor_geometry.height - requisition.height;
|
y = self->priv->workarea.y;
|
||||||
width = monitor_geometry.width - x;
|
width = self->priv->workarea.width;
|
||||||
|
height = self->priv->workarea.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
x_target = x;
|
||||||
|
y_target = y + height - requisition.height;
|
||||||
|
|
||||||
self->priv->width = width;
|
self->priv->width = width;
|
||||||
gtk_widget_set_size_request (GTK_WIDGET (self), width, PANEL_HEIGHT);
|
self->priv->height = height;
|
||||||
gtk_window_move (GTK_WINDOW (self), x, y);
|
gtk_widget_set_size_request (GTK_WIDGET (self), width - x_target, PANEL_HEIGHT);
|
||||||
|
gtk_window_move (GTK_WINDOW (self), x_target, y_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -207,15 +181,17 @@ on_workarea_changed (ShellPanelWindow *self)
|
|||||||
workarea,
|
workarea,
|
||||||
0, 4, FALSE, workarea,
|
0, 4, FALSE, workarea,
|
||||||
&type, &format, &nitems, &bytes_after, &data);
|
&type, &format, &nitems, &bytes_after, &data);
|
||||||
if ((format == 32) && (nitems == 4) && (bytes_after == 0)) {
|
if ((format == 32) && (nitems == 4) && (bytes_after == 0))
|
||||||
|
{
|
||||||
int x, y, width, height;
|
int x, y, width, height;
|
||||||
data32 = (long*)data;
|
data32 = (long*) data;
|
||||||
x = data32[0]; y = data32[1];
|
x = data32[0];
|
||||||
width = data32[2]; height = data32[3];
|
y = data32[1];
|
||||||
if (x == self->priv->workarea.x &&
|
width = data32[2];
|
||||||
y == self->priv->workarea.y &&
|
height = data32[3];
|
||||||
width == self->priv->workarea.width &&
|
if (x == self->priv->workarea.x && y == self->priv->workarea.y
|
||||||
height == self->priv->workarea.height)
|
&& width == self->priv->workarea.width
|
||||||
|
&& height == self->priv->workarea.height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
self->priv->workarea.x = x;
|
self->priv->workarea.x = x;
|
||||||
@ -224,11 +200,16 @@ on_workarea_changed (ShellPanelWindow *self)
|
|||||||
self->priv->workarea.height = height;
|
self->priv->workarea.height = height;
|
||||||
|
|
||||||
handle_new_workarea (self);
|
handle_new_workarea (self);
|
||||||
} else if (nitems == 0) {
|
}
|
||||||
|
else if (nitems == 0)
|
||||||
|
{
|
||||||
|
/* We have no workarea set; assume there are no other panels at this time */
|
||||||
self->priv->workarea.x = self->priv->workarea.y = 0;
|
self->priv->workarea.x = self->priv->workarea.y = 0;
|
||||||
self->priv->workarea.width = self->priv->workarea.height = -1;
|
self->priv->workarea.width = self->priv->workarea.height = 0;
|
||||||
handle_new_workarea (self);
|
handle_new_workarea (self);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
g_printerr ("unexpected return from XGetWindowProperty: %d %ld %ld\n",
|
g_printerr ("unexpected return from XGetWindowProperty: %d %ld %ld\n",
|
||||||
format, nitems, bytes_after);
|
format, nitems, bytes_after);
|
||||||
}
|
}
|
||||||
@ -242,14 +223,13 @@ filter_func (GdkXEvent *gdk_xevent,
|
|||||||
ShellPanelWindow *self = SHELL_PANEL_WINDOW (data);
|
ShellPanelWindow *self = SHELL_PANEL_WINDOW (data);
|
||||||
GdkFilterReturn ret = GDK_FILTER_CONTINUE;
|
GdkFilterReturn ret = GDK_FILTER_CONTINUE;
|
||||||
XEvent *xevent = (XEvent *) event;
|
XEvent *xevent = (XEvent *) event;
|
||||||
Atom workarea = gdk_x11_get_xatom_by_name_for_display (gdk_display_get_default (), "_NET_WORKAREA");
|
|
||||||
|
|
||||||
switch (xevent->type) {
|
switch (xevent->type)
|
||||||
|
{
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
{
|
{
|
||||||
if (xevent->xproperty.atom != workarea)
|
if (xevent->xproperty.atom != self->priv->workarea_atom)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
on_workarea_changed (self);
|
on_workarea_changed (self);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user