add support for _NET_WM_USER_TIME_WINDOW. round 1 ! ding.
This commit is contained in:
parent
f6fd01409a
commit
cdb108c76d
9 changed files with 106 additions and 31 deletions
|
@ -62,6 +62,7 @@ typedef struct
|
|||
} ClientCallback;
|
||||
|
||||
GList *client_list = NULL;
|
||||
GHashTable *client_user_time_window_map;
|
||||
|
||||
static GSList *client_destructors = NULL;
|
||||
|
||||
|
@ -94,15 +95,23 @@ static GSList *client_search_all_top_parents_internal(ObClient *self,
|
|||
gboolean bylayer,
|
||||
ObStackingLayer layer);
|
||||
|
||||
static guint window_hash(Window *w) { return *w; }
|
||||
static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; }
|
||||
|
||||
void client_startup(gboolean reconfig)
|
||||
{
|
||||
if (reconfig) return;
|
||||
|
||||
client_user_time_window_map = g_hash_table_new((GHashFunc)window_hash,
|
||||
(GEqualFunc)window_comp);
|
||||
client_set_list();
|
||||
}
|
||||
|
||||
void client_shutdown(gboolean reconfig)
|
||||
{
|
||||
if (reconfig) return;
|
||||
|
||||
g_hash_table_destroy(client_user_time_window_map);
|
||||
}
|
||||
|
||||
void client_add_destructor(ObClientCallback func, gpointer data)
|
||||
|
@ -503,6 +512,10 @@ void client_unmanage(ObClient *self)
|
|||
/* we dont want events no more. do this before hiding the frame so we
|
||||
don't generate more events */
|
||||
XSelectInput(ob_display, self->window, NoEventMask);
|
||||
if (self->user_time_window) {
|
||||
XSelectInput(ob_display, self->user_time_window, NoEventMask);
|
||||
g_hash_table_remove(client_user_time_window_map, &w);
|
||||
}
|
||||
|
||||
frame_hide(self->frame);
|
||||
/* flush to send the hide to the server quickly */
|
||||
|
@ -1002,7 +1015,9 @@ static void client_get_all(ObClient *self)
|
|||
client_update_title(self);
|
||||
client_update_strut(self);
|
||||
client_update_icons(self);
|
||||
client_update_user_time(self);
|
||||
client_update_user_time_window(self);
|
||||
if (!self->user_time_window) /* check if this would have been called */
|
||||
client_update_user_time(self);
|
||||
client_update_icon_geometry(self);
|
||||
}
|
||||
|
||||
|
@ -2019,8 +2034,15 @@ void client_update_icons(ObClient *self)
|
|||
void client_update_user_time(ObClient *self)
|
||||
{
|
||||
guint32 time;
|
||||
gboolean got = FALSE;
|
||||
|
||||
if (PROP_GET32(self->window, net_wm_user_time, cardinal, &time)) {
|
||||
if (self->user_time_window)
|
||||
got = PROP_GET32(self->user_time_window,
|
||||
net_wm_user_time, cardinal, &time);
|
||||
if (!got)
|
||||
got = PROP_GET32(self->window, net_wm_user_time, cardinal, &time);
|
||||
|
||||
if (got) {
|
||||
/* we set this every time, not just when it grows, because in practice
|
||||
sometimes time goes backwards! (ntpdate.. yay....) so.. if it goes
|
||||
backward we don't want all windows to stop focusing. we'll just
|
||||
|
@ -2029,9 +2051,50 @@ void client_update_user_time(ObClient *self)
|
|||
*/
|
||||
self->user_time = time;
|
||||
|
||||
/*
|
||||
ob_debug("window %s user time %u\n", self->title, time);
|
||||
*/
|
||||
/*ob_debug("window %s user time %u\n", self->title, time);*/
|
||||
}
|
||||
}
|
||||
|
||||
void client_update_user_time_window(ObClient *self)
|
||||
{
|
||||
guint32 w;
|
||||
ObClient *c;
|
||||
|
||||
if (!PROP_GET32(self->window, net_wm_user_time_window, window, &w))
|
||||
w = None;
|
||||
|
||||
if (w != self->user_time_window) {
|
||||
if (self->user_time_window) {
|
||||
XSelectInput(ob_display, self->user_time_window, NoEventMask);
|
||||
g_hash_table_remove(client_user_time_window_map, &w);
|
||||
self->user_time_window = None;
|
||||
}
|
||||
|
||||
if (self->group && self->group->leader == w) {
|
||||
ob_debug_type(OB_DEBUG_APP_BUGS, "Window is setting its "
|
||||
"_NET_WM_USER_TYPE_WINDOW to its group leader\n");
|
||||
/* do it anyways..? */
|
||||
}
|
||||
else if (w == self->window) {
|
||||
ob_debug_type(OB_DEBUG_APP_BUGS, "Window is setting its "
|
||||
"_NET_WM_USER_TIME_WINDOW to itself\n");
|
||||
w = None; /* don't do it */
|
||||
}
|
||||
else if (((c = g_hash_table_lookup(client_user_time_window_map,&w)))) {
|
||||
ob_debug_type(OB_DEBUG_APP_BUGS, "Client %s is trying to use "
|
||||
"the _NET_WM_USER_TIME_WINDOW of %s\n",
|
||||
self->title, c->title);
|
||||
w = None; /* don't do it */
|
||||
}
|
||||
|
||||
self->user_time_window = w;
|
||||
if (self->user_time_window != None) {
|
||||
XSelectInput(ob_display,self->user_time_window,PropertyChangeMask);
|
||||
g_hash_table_insert(client_user_time_window_map,
|
||||
&self->user_time_window, self);
|
||||
}
|
||||
|
||||
client_update_user_time(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -289,13 +289,17 @@ struct _ObClient
|
|||
/*! The number of icons in icons */
|
||||
guint nicons;
|
||||
|
||||
/* Where the window should iconify to/from */
|
||||
/*! Where the window should iconify to/from */
|
||||
Rect icon_geometry;
|
||||
|
||||
/*! The time when the client last received user interaction */
|
||||
guint32 user_time;
|
||||
/*! A separate window for the client to update it's user_time on */
|
||||
Window user_time_window;
|
||||
};
|
||||
|
||||
extern GList *client_list;
|
||||
extern GList *client_list;
|
||||
extern GHashTable *client_user_time_window_map;
|
||||
|
||||
void client_startup(gboolean reconfig);
|
||||
void client_shutdown(gboolean reconfig);
|
||||
|
@ -585,6 +589,8 @@ void client_update_strut(ObClient *self);
|
|||
void client_update_icons(ObClient *self);
|
||||
/*! Updates the window's user time */
|
||||
void client_update_user_time(ObClient *self);
|
||||
/*! Updates the window's user time window */
|
||||
void client_update_user_time_window(ObClient *self);
|
||||
/*! Updates the window's icon geometry (where to iconify to/from) */
|
||||
void client_update_icon_geometry(ObClient *self);
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ static gboolean event_handle_menu(XEvent *e);
|
|||
static void event_handle_dock(ObDock *s, XEvent *e);
|
||||
static void event_handle_dockapp(ObDockApp *app, XEvent *e);
|
||||
static void event_handle_client(ObClient *c, XEvent *e);
|
||||
static void event_handle_group(ObGroup *g, XEvent *e);
|
||||
static void event_handle_user_time_window_client(ObClient *c, XEvent *e);
|
||||
static void event_handle_user_input(ObClient *client, XEvent *e);
|
||||
|
||||
static void focus_delay_dest(gpointer data);
|
||||
|
@ -406,11 +406,11 @@ static gboolean event_ignore(XEvent *e, ObClient *client)
|
|||
static void event_process(const XEvent *ec, gpointer data)
|
||||
{
|
||||
Window window;
|
||||
ObGroup *group = NULL;
|
||||
ObClient *client = NULL;
|
||||
ObDock *dock = NULL;
|
||||
ObDockApp *dockapp = NULL;
|
||||
ObWindow *obwin = NULL;
|
||||
ObClient *timewinclient = NULL;
|
||||
XEvent ee, *e;
|
||||
ObEventData *ed = data;
|
||||
|
||||
|
@ -419,8 +419,9 @@ static void event_process(const XEvent *ec, gpointer data)
|
|||
e = ⅇ
|
||||
|
||||
window = event_get_window(e);
|
||||
if (!(e->type == PropertyNotify &&
|
||||
(group = g_hash_table_lookup(group_map, &window))))
|
||||
if (e->type != PropertyNotify ||
|
||||
!(timewinclient =
|
||||
g_hash_table_lookup(client_user_time_window_map, &window)))
|
||||
if ((obwin = g_hash_table_lookup(window_map, &window))) {
|
||||
switch (obwin->type) {
|
||||
case Window_Dock:
|
||||
|
@ -554,8 +555,8 @@ static void event_process(const XEvent *ec, gpointer data)
|
|||
/* focus_set_client has already been called for sure */
|
||||
client_calc_layer(client);
|
||||
}
|
||||
} else if (group)
|
||||
event_handle_group(group, e);
|
||||
} else if (timewinclient)
|
||||
event_handle_user_time_window_client(timewinclient, e);
|
||||
else if (client)
|
||||
event_handle_client(client, e);
|
||||
else if (dockapp)
|
||||
|
@ -662,16 +663,6 @@ static void event_handle_root(XEvent *e)
|
|||
}
|
||||
}
|
||||
|
||||
static void event_handle_group(ObGroup *group, XEvent *e)
|
||||
{
|
||||
GSList *it;
|
||||
|
||||
g_assert(e->type == PropertyNotify);
|
||||
|
||||
for (it = group->members; it; it = g_slist_next(it))
|
||||
event_handle_client(it->data, e);
|
||||
}
|
||||
|
||||
void event_enter_client(ObClient *client)
|
||||
{
|
||||
g_assert(config_focus_follow);
|
||||
|
@ -699,6 +690,13 @@ void event_enter_client(ObClient *client)
|
|||
}
|
||||
}
|
||||
|
||||
static void event_handle_user_time_window_client(ObClient *client, XEvent *e)
|
||||
{
|
||||
g_assert(e->type == PropertyNotify);
|
||||
if (e->xproperty.atom == prop_atoms.net_wm_user_time)
|
||||
client_update_user_time(client);
|
||||
}
|
||||
|
||||
static void event_handle_client(ObClient *client, XEvent *e)
|
||||
{
|
||||
XEvent ce;
|
||||
|
@ -1191,6 +1189,9 @@ static void event_handle_client(ObClient *client, XEvent *e)
|
|||
else if (msgtype == prop_atoms.net_wm_user_time) {
|
||||
client_update_user_time(client);
|
||||
}
|
||||
else if (msgtype == prop_atoms.net_wm_user_time_window) {
|
||||
client_update_user_time_window(client);
|
||||
}
|
||||
#ifdef SYNC
|
||||
else if (msgtype == prop_atoms.net_wm_sync_request_counter) {
|
||||
client_update_sync_request_counter(client);
|
||||
|
|
|
@ -19,17 +19,17 @@
|
|||
#include "group.h"
|
||||
#include "client.h"
|
||||
|
||||
GHashTable *group_map = NULL;
|
||||
static GHashTable *group_map;
|
||||
|
||||
static guint map_hash(Window *w) { return *w; }
|
||||
static gboolean map_key_comp(Window *w1, Window *w2) { return *w1 == *w2; }
|
||||
static guint window_hash(Window *w) { return *w; }
|
||||
static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; }
|
||||
|
||||
void group_startup(gboolean reconfig)
|
||||
{
|
||||
if (reconfig) return;
|
||||
|
||||
group_map = g_hash_table_new((GHashFunc)map_hash,
|
||||
(GEqualFunc)map_key_comp);
|
||||
group_map = g_hash_table_new((GHashFunc)window_hash,
|
||||
(GEqualFunc)window_comp);
|
||||
}
|
||||
|
||||
void group_shutdown(gboolean reconfig)
|
||||
|
|
|
@ -34,8 +34,6 @@ struct _ObGroup
|
|||
GSList *members;
|
||||
};
|
||||
|
||||
extern GHashTable *group_map;
|
||||
|
||||
void group_startup(gboolean reconfig);
|
||||
void group_shutdown(gboolean reconfig);
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ void prop_startup()
|
|||
/* CREATE(net_wm_pid, "_NET_WM_PID"); */
|
||||
CREATE(net_wm_allowed_actions, "_NET_WM_ALLOWED_ACTIONS");
|
||||
CREATE(net_wm_user_time, "_NET_WM_USER_TIME");
|
||||
CREATE(net_wm_user_time_window, "_NET_WM_USER_TIME_WINDOW");
|
||||
CREATE(kde_net_wm_frame_strut, "_KDE_NET_WM_FRAME_STRUT");
|
||||
CREATE(net_frame_extents, "_NET_FRAME_EXTENTS");
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ typedef struct Atoms {
|
|||
/* Atom net_wm_pid; */
|
||||
Atom net_wm_allowed_actions;
|
||||
Atom net_wm_user_time;
|
||||
Atom net_wm_user_time_window;
|
||||
Atom net_frame_extents;
|
||||
|
||||
/* application protocols */
|
||||
|
|
|
@ -273,6 +273,7 @@ gboolean screen_annex(const gchar *program_name)
|
|||
supported[i++] = prop_atoms.net_moveresize_window;
|
||||
supported[i++] = prop_atoms.net_wm_moveresize;
|
||||
supported[i++] = prop_atoms.net_wm_user_time;
|
||||
supported[i++] = prop_atoms.net_wm_user_time_window;
|
||||
supported[i++] = prop_atoms.net_frame_extents;
|
||||
supported[i++] = prop_atoms.net_startup_id;
|
||||
#ifdef SYNC
|
||||
|
|
|
@ -25,11 +25,15 @@
|
|||
|
||||
GHashTable *window_map;
|
||||
|
||||
static guint window_hash(Window *w) { return *w; }
|
||||
static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; }
|
||||
|
||||
void window_startup(gboolean reconfig)
|
||||
{
|
||||
if (reconfig) return;
|
||||
|
||||
window_map = g_hash_table_new(g_int_hash, g_int_equal);
|
||||
window_map = g_hash_table_new((GHashFunc)window_hash,
|
||||
(GEqualFunc)window_comp);
|
||||
}
|
||||
|
||||
void window_shutdown(gboolean reconfig)
|
||||
|
|
Loading…
Reference in a new issue