add support for _NET_WM_USER_TIME_WINDOW. round 1 ! ding.

This commit is contained in:
Dana Jansens 2007-05-09 17:01:30 +00:00
parent f6fd01409a
commit cdb108c76d
9 changed files with 106 additions and 31 deletions

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -34,8 +34,6 @@ struct _ObGroup
GSList *members;
};
extern GHashTable *group_map;
void group_startup(gboolean reconfig);
void group_shutdown(gboolean reconfig);

View file

@ -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");

View file

@ -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 */

View file

@ -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

View file

@ -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)