xembed: store windows in an array

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-12-01 16:43:44 +01:00
parent c3c20c4f8e
commit 8b88541f0a
9 changed files with 61 additions and 52 deletions

View File

@ -59,17 +59,17 @@ void
awesome_atexit(void) awesome_atexit(void)
{ {
client_t *c; client_t *c;
xembed_window_t *em;
int screen_nbr; int screen_nbr;
a_dbus_cleanup(); a_dbus_cleanup();
luaA_cs_cleanup(); luaA_cs_cleanup();
/* reparent systray windows, otherwise they may die with their master */ /* reparent systray windows, otherwise they may die with their master */
for(em = globalconf.embedded; em; em = em->next) for(int i = 0; i < globalconf.embedded.len; i++)
{ {
xcb_screen_t *s = xutil_screen_get(globalconf.connection, em->phys_screen); xcb_screen_t *s = xutil_screen_get(globalconf.connection,
xembed_window_unembed(globalconf.connection, em->win, s->root); globalconf.embedded.tab[i].phys_screen);
xembed_window_unembed(globalconf.connection, globalconf.embedded.tab[i].win, s->root);
} }
/* do this only for real screen */ /* do this only for real screen */

View File

@ -100,14 +100,14 @@ xembed_info_get_reply(xcb_connection_t *connection,
/** Get a XEMBED window from a xembed_window_t list. /** Get a XEMBED window from a xembed_window_t list.
* \param list The xembed window list. * \param list The xembed window list.
* \param win The window to look for. * \param win The window to look for.
* \return The xembed window if found, NULL otherwise.
*/ */
xembed_window_t * xembed_window_t *
xembed_getbywin(xembed_window_t *list, xcb_window_t win) xembed_getbywin(xembed_window_array_t *list, xcb_window_t win)
{ {
xembed_window_t *n; for(int i = 0; i < list->len; i++)
for(n = list; n; n = n->next) if(list->tab[i].win == win)
if(win == n->win) return &list->tab[i];
return n;
return NULL; return NULL;
} }

View File

@ -27,7 +27,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "common/list.h" #include "common/array.h"
#include "common/util.h" #include "common/util.h"
/** XEMBED information for a window. /** XEMBED information for a window.
@ -38,16 +38,15 @@ typedef struct
unsigned long flags; unsigned long flags;
} xembed_info_t; } xembed_info_t;
typedef struct xembed_window_t xembed_window_t; typedef struct xembed_window xembed_window_t;
struct xembed_window_t struct xembed_window
{ {
xcb_window_t win; xcb_window_t win;
int phys_screen; int phys_screen;
xembed_info_t info; xembed_info_t info;
xembed_window_t *prev, *next;
}; };
DO_SLIST(xembed_window_t, xembed_window, p_delete) DO_ARRAY(xembed_window_t, xembed_window, DO_NOTHING)
/** The version of the XEMBED protocol that this library supports. */ /** The version of the XEMBED protocol that this library supports. */
#define XEMBED_VERSION 0 #define XEMBED_VERSION 0
@ -91,7 +90,7 @@ DO_SLIST(xembed_window_t, xembed_window, p_delete)
void xembed_message_send(xcb_connection_t *, xcb_window_t, long, long, long, long); void xembed_message_send(xcb_connection_t *, xcb_window_t, long, long, long, long);
xembed_window_t * xembed_getbywin(xembed_window_t *, xcb_window_t); xembed_window_t * xembed_getbywin(xembed_window_array_t *, xcb_window_t);
void xembed_property_update(xcb_connection_t *, xembed_window_t *, xcb_get_property_reply_t *); void xembed_property_update(xcb_connection_t *, xembed_window_t *, xcb_get_property_reply_t *);
xcb_get_property_cookie_t xembed_info_get_unchecked(xcb_connection_t *, xcb_get_property_cookie_t xembed_info_get_unchecked(xcb_connection_t *,
xcb_window_t); xcb_window_t);

34
event.c
View File

@ -362,16 +362,17 @@ event_handle_destroynotify(void *data __attribute__ ((unused)),
xcb_destroy_notify_event_t *ev) xcb_destroy_notify_event_t *ev)
{ {
client_t *c; client_t *c;
xembed_window_t *emwin;
if((c = client_getbywin(ev->window))) if((c = client_getbywin(ev->window)))
client_unmanage(c); client_unmanage(c);
else if((emwin = xembed_getbywin(globalconf.embedded, ev->event))) else
{ for(int i = 0; i < globalconf.embedded.len; i++)
xembed_window_list_detach(&globalconf.embedded, emwin); if(globalconf.embedded.tab[i].win == ev->window)
for(int i = 0; i < globalconf.nscreen; i++) {
widget_invalidate_bytype(i, widget_systray); xembed_window_array_take(&globalconf.embedded, i);
} for(int j = 0; j < globalconf.nscreen; j++)
widget_invalidate_bytype(j, widget_systray);
}
return 0; return 0;
} }
@ -524,7 +525,7 @@ event_handle_enternotify(void *data __attribute__ ((unused)),
luaA_dofunction(globalconf.L, globalconf.hooks.mouse_enter, 1, 0); luaA_dofunction(globalconf.L, globalconf.hooks.mouse_enter, 1, 0);
} }
} }
else if((emwin = xembed_getbywin(globalconf.embedded, ev->event))) else if((emwin = xembed_getbywin(&globalconf.embedded, ev->event)))
xcb_ungrab_button(globalconf.connection, XCB_BUTTON_INDEX_ANY, xcb_ungrab_button(globalconf.connection, XCB_BUTTON_INDEX_ANY,
xutil_screen_get(connection, emwin->phys_screen)->root, xutil_screen_get(connection, emwin->phys_screen)->root,
XCB_BUTTON_MASK_ANY); XCB_BUTTON_MASK_ANY);
@ -615,7 +616,7 @@ event_handle_maprequest(void *data __attribute__ ((unused)),
if(wa_r->override_redirect) if(wa_r->override_redirect)
goto bailout; goto bailout;
if(xembed_getbywin(globalconf.embedded, ev->window)) if(xembed_getbywin(&globalconf.embedded, ev->window))
{ {
xcb_map_window(connection, ev->window); xcb_map_window(connection, ev->window);
xembed_window_activate(connection, ev->window); xembed_window_activate(connection, ev->window);
@ -676,7 +677,6 @@ event_handle_unmapnotify(void *data __attribute__ ((unused)),
xcb_connection_t *connection, xcb_unmap_notify_event_t *ev) xcb_connection_t *connection, xcb_unmap_notify_event_t *ev)
{ {
client_t *c; client_t *c;
xembed_window_t *em;
if((c = client_getbywin(ev->window))) if((c = client_getbywin(ev->window)))
{ {
@ -685,12 +685,14 @@ event_handle_unmapnotify(void *data __attribute__ ((unused)),
&& window_state_get_reply(window_state_get_unchecked(c->win)) == XCB_WM_STATE_NORMAL) && window_state_get_reply(window_state_get_unchecked(c->win)) == XCB_WM_STATE_NORMAL)
client_unmanage(c); client_unmanage(c);
} }
else if((em = xembed_getbywin(globalconf.embedded, ev->window))) else
{ for(int i = 0; i < globalconf.embedded.len; i++)
xembed_window_list_detach(&globalconf.embedded, em); if(globalconf.embedded.tab[i].win == ev->window)
for(int i = 0; i < globalconf.nscreen; i++) {
widget_invalidate_bytype(i, widget_systray); xembed_window_array_take(&globalconf.embedded, i);
} for(int j = 0; j < globalconf.nscreen; j++)
widget_invalidate_bytype(j, widget_systray);
}
return 0; return 0;
} }

View File

@ -345,7 +345,7 @@ property_handle_xembed_info(void *data __attribute__ ((unused)),
xcb_atom_t name, xcb_atom_t name,
xcb_get_property_reply_t *reply) xcb_get_property_reply_t *reply)
{ {
xembed_window_t *emwin = xembed_getbywin(globalconf.embedded, window); xembed_window_t *emwin = xembed_getbywin(&globalconf.embedded, window);
if(emwin) if(emwin)
xembed_property_update(connection, emwin, reply); xembed_property_update(connection, emwin, reply);

View File

@ -316,7 +316,7 @@ struct awesome_t
/** Clients list */ /** Clients list */
client_t *clients; client_t *clients;
/** Embedded windows */ /** Embedded windows */
xembed_window_t *embedded; xembed_window_array_t embedded;
/** Path to config file */ /** Path to config file */
char *conffile; char *conffile;
/** Stack client history */ /** Stack client history */

View File

@ -130,7 +130,7 @@ systray_cleanup(int phys_screen)
int int
systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *info) systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *info)
{ {
xembed_window_t *em; xembed_window_t em;
xcb_get_property_cookie_t em_cookie; xcb_get_property_cookie_t em_cookie;
int i; int i;
const uint32_t select_input_val[] = const uint32_t select_input_val[] =
@ -141,7 +141,7 @@ systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *i
}; };
/* check if not already trayed */ /* check if not already trayed */
if((em = xembed_getbywin(globalconf.embedded, embed_win))) if(xembed_getbywin(&globalconf.embedded, embed_win))
return -1; return -1;
p_clear(&em_cookie, 1); p_clear(&em_cookie, 1);
@ -157,20 +157,19 @@ systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *i
globalconf.screens[phys_screen].systray.window, globalconf.screens[phys_screen].systray.window,
0, 0); 0, 0);
em = p_new(xembed_window_t, 1); em.win = embed_win;
em->win = embed_win; em.phys_screen = phys_screen;
em->phys_screen = phys_screen;
xembed_window_list_append(&globalconf.embedded, em);
if(info) if(info)
em->info = *info; em.info = *info;
else else
xembed_info_get_reply(globalconf.connection, em_cookie, &em->info); xembed_info_get_reply(globalconf.connection, em_cookie, &em.info);
xembed_embedded_notify(globalconf.connection, em->win, xembed_embedded_notify(globalconf.connection, em.win,
globalconf.screens[phys_screen].systray.window, globalconf.screens[phys_screen].systray.window,
MIN(XEMBED_VERSION, em->info.version)); MIN(XEMBED_VERSION, em.info.version));
xembed_window_array_append(&globalconf.embedded, em);
for(i = 0; i < globalconf.nscreen; i++) for(i = 0; i < globalconf.nscreen; i++)
widget_invalidate_bytype(i, widget_systray); widget_invalidate_bytype(i, widget_systray);

15
wibox.c
View File

@ -191,7 +191,9 @@ wibox_systray_refresh(wibox_t *wibox)
{ {
case Left: case Left:
config_win_vals[1] = systray->geometry.width - config_win_vals[3]; config_win_vals[1] = systray->geometry.width - config_win_vals[3];
for(em = globalconf.embedded; em; em = em->next) for(int j = 0; j < globalconf.embedded.len; j++)
{
em = &globalconf.embedded.tab[j];
if(em->phys_screen == phys_screen) if(em->phys_screen == phys_screen)
{ {
if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) wibox->sw.geometry.y) if(config_win_vals[1] - config_win_vals[2] >= (uint32_t) wibox->sw.geometry.y)
@ -211,10 +213,13 @@ wibox_systray_refresh(wibox_t *wibox)
| XCB_CONFIG_WINDOW_Y, | XCB_CONFIG_WINDOW_Y,
config_win_vals_off); config_win_vals_off);
} }
}
break; break;
case Right: case Right:
config_win_vals[1] = 0; config_win_vals[1] = 0;
for(em = globalconf.embedded; em; em = em->next) for(int j = 0; j < globalconf.embedded.len; j++)
{
em = &globalconf.embedded.tab[j];
if(em->phys_screen == phys_screen) if(em->phys_screen == phys_screen)
{ {
if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) wibox->sw.geometry.y + wibox->sw.geometry.width) if(config_win_vals[1] + config_win_vals[3] <= (uint32_t) wibox->sw.geometry.y + wibox->sw.geometry.width)
@ -234,12 +239,15 @@ wibox_systray_refresh(wibox_t *wibox)
| XCB_CONFIG_WINDOW_Y, | XCB_CONFIG_WINDOW_Y,
config_win_vals_off); config_win_vals_off);
} }
}
break; break;
case Floating: case Floating:
case Top: case Top:
case Bottom: case Bottom:
config_win_vals[1] = 0; config_win_vals[1] = 0;
for(em = globalconf.embedded; em; em = em->next) for(int j = 0; j < globalconf.embedded.len; j++)
{
em = &globalconf.embedded.tab[j];
if(em->phys_screen == phys_screen) if(em->phys_screen == phys_screen)
{ {
/* if(x + width < systray.x + systray.width) */ /* if(x + width < systray.x + systray.width) */
@ -260,6 +268,7 @@ wibox_systray_refresh(wibox_t *wibox)
| XCB_CONFIG_WINDOW_Y, | XCB_CONFIG_WINDOW_Y,
config_win_vals_off); config_win_vals_off);
} }
}
break; break;
} }
break; break;

View File

@ -36,16 +36,16 @@ static area_t
systray_geometry(widget_t *widget, int screen, int height, int width) systray_geometry(widget_t *widget, int screen, int height, int width)
{ {
area_t geometry; area_t geometry;
int phys_screen = screen_virttophys(screen), i = 0; int phys_screen = screen_virttophys(screen), n = 0;
geometry.height = height; geometry.height = height;
for(xembed_window_t *em = globalconf.embedded; em; em = em->next) for(int i = 0; i < globalconf.embedded.len; i++)
if(em->phys_screen == phys_screen) if(globalconf.embedded.tab[i].phys_screen == phys_screen)
i++; n++;
/** \todo use class hints */ /** \todo use class hints */
geometry.width = MIN(i * height, width); geometry.width = MIN(n * height, width);
return geometry; return geometry;
} }