Systray: Fix

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2010-10-06 15:38:44 +02:00
parent bddecffe97
commit 742c0dead0
9 changed files with 114 additions and 48 deletions

View file

@ -141,7 +141,7 @@ for s = 1, screen.count() do
-- Widgets that are aligned to the right
local right_layout = wibox.layout.fixed.horizontal()
--if s == 1 then right_layout:add(wibox.widget.systray(true)) end
if s == 1 then right_layout:add(wibox.widget.systray(true)) end
right_layout:add(mytextclock)
right_layout:add(mylayoutbox[s])

View file

@ -330,6 +330,7 @@ event_handle_destroynotify(xcb_destroy_notify_event_t *ev)
if(globalconf.embedded.tab[i].win == ev->window)
{
xembed_window_array_take(&globalconf.embedded, i);
luaA_systray_invalidate();
}
}
@ -561,6 +562,7 @@ event_handle_unmapnotify(xcb_unmap_notify_event_t *ev)
{
xembed_window_array_take(&globalconf.embedded, i);
xcb_change_save_set(globalconf.connection, XCB_SET_MODE_DELETE, ev->window);
luaA_systray_invalidate();
}
}

View file

@ -22,14 +22,12 @@
#ifndef AWESOME_EVENT_H
#define AWESOME_EVENT_H
#include "systray.h"
#include "objects/client.h"
static inline int
awesome_refresh(void)
{
banning_refresh();
systray_refresh();
stack_refresh();
return xcb_flush(globalconf.connection);
}

View file

@ -103,9 +103,7 @@ typedef struct
{
xcb_window_t window;
/** Systray window parent */
xcb_window_t parent;
/** Is awesome the systray owner? */
bool registered;
drawin_t *parent;
} systray;
/** The monitor of startup notifications */
SnMonitorContext *snmonitor;

3
luaa.c
View file

@ -45,6 +45,7 @@
#include "screen.h"
#include "event.h"
#include "selection.h"
#include "systray.h"
#include "common/xcursor.h"
#include "common/buffer.h"
#include "common/backtrace.h"
@ -545,6 +546,7 @@ luaA_init(xdgHandle* xdg)
{ "connect_signal", luaA_awesome_connect_signal },
{ "disconnect_signal", luaA_awesome_disconnect_signal },
{ "emit_signal", luaA_awesome_emit_signal },
{ "systray", luaA_systray },
{ "__index", luaA_awesome_index },
{ "__newindex", luaA_awesome_newindex },
{ NULL, NULL }
@ -672,6 +674,7 @@ luaA_init(xdgHandle* xdg)
signal_add(&global_signals, "debug::error");
signal_add(&global_signals, "debug::index::miss");
signal_add(&global_signals, "debug::newindex::miss");
signal_add(&global_signals, "systray::update");
signal_add(&global_signals, "exit");
}

2
luaa.h
View file

@ -197,5 +197,7 @@ signal_array_t global_signals;
int luaA_class_index_miss_property(lua_State *, lua_object_t *);
int luaA_class_newindex_miss_property(lua_State *, lua_object_t *);
void luaA_systray_invalidate(void);
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View file

@ -27,6 +27,7 @@
#include "xwindow.h"
#include "luaa.h"
#include "ewmh.h"
#include "systray.h"
#include "common/xcursor.h"
#include "common/xutil.h"
@ -37,20 +38,20 @@ LUA_OBJECT_FUNCS(drawin_class, drawin_t, drawin)
/** Kick out systray windows.
*/
static void
drawin_systray_kickout(void)
drawin_systray_kickout(drawin_t *w)
{
xcb_screen_t *s = globalconf.screen;
if(globalconf.systray.parent != s->root)
if(globalconf.systray.parent == w)
{
/* Who! Check that we're not deleting a drawin with a systray, because it
* may be its parent. If so, we reparent to root before, otherwise it will
* hurt very much. */
systray_cleanup();
xcb_reparent_window(globalconf.connection,
globalconf.systray.window,
s->root, -512, -512);
globalconf.screen->root,
-512, -512);
globalconf.systray.parent = s->root;
globalconf.systray.parent = NULL;
}
}
@ -65,8 +66,7 @@ drawin_wipe_resources(drawin_t *w)
/* Activate BMA */
client_ignore_enterleave_events();
/* Make sure we don't accidentally kill the systray window */
if(globalconf.systray.parent == w->window)
drawin_systray_kickout();
drawin_systray_kickout(w);
xcb_destroy_window(globalconf.connection, w->window);
/* Deactivate BMA */
client_restore_enterleave_events();

127
systray.c
View file

@ -23,12 +23,14 @@
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_atom.h>
#include "luaa.h"
#include "screen.h"
#include "systray.h"
#include "xwindow.h"
#include "common/array.h"
#include "common/atoms.h"
#include "common/xutil.h"
#include "objects/drawin.h"
#define SYSTEM_TRAY_REQUEST_DOCK 0 /* Begin icon docking */
@ -47,31 +49,9 @@ systray_init(void)
XCB_COPY_FROM_PARENT, xscreen->root_visual, 0, NULL);
}
/** Refresh all systrays registrations per physical screen
*/
void
systray_refresh(void)
{
#warning
#if 0
bool has_systray = false;
foreach(w, globalconf.wiboxes)
if((*w)->has_systray)
/* Can't use "break" with foreach() :( */
has_systray = true;
if(has_systray)
systray_register();
else
systray_cleanup();
#endif
}
/** Register systray in X.
*/
void
static void
systray_register(void)
{
xcb_client_message_event_t ev;
@ -81,11 +61,6 @@ systray_register(void)
xcb_intern_atom_reply_t *atom_systray_r;
xcb_atom_t atom_systray;
/* Set registered even if it fails to don't try again unless forced */
if(globalconf.systray.registered)
return;
globalconf.systray.registered = true;
/* Send requests */
if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", globalconf.default_screen)))
{
@ -134,10 +109,6 @@ systray_cleanup(void)
xcb_intern_atom_reply_t *atom_systray_r;
char *atom_name;
if(!globalconf.systray.registered)
return;
globalconf.systray.registered = false;
if(!(atom_name = xcb_atom_name_by_screen("_NET_SYSTEM_TRAY", globalconf.default_screen))
|| !(atom_systray_r = xcb_intern_atom_reply(globalconf.connection,
xcb_intern_atom_unchecked(globalconf.connection,
@ -159,6 +130,9 @@ systray_cleanup(void)
XCB_CURRENT_TIME);
p_delete(&atom_systray_r);
xcb_unmap_window(globalconf.connection,
globalconf.systray.window);
}
/** Handle a systray request.
@ -211,6 +185,7 @@ systray_request_handle(xcb_window_t embed_win, xembed_info_t *info)
MIN(XEMBED_VERSION, em.info.version));
xembed_window_array_append(&globalconf.embedded, em);
luaA_systray_invalidate();
return 0;
}
@ -287,4 +262,92 @@ xembed_process_client_message(xcb_client_message_event_t *ev)
return 0;
}
/** Inform lua that the systray needs to be updated.
*/
void
luaA_systray_invalidate(void)
{
signal_object_emit(globalconf.L, &global_signals, "systray::update", 0);
}
static void
systray_update(int base_size, bool horizontal)
{
if(base_size <= 0)
return;
/* Give the systray window the correct size */
uint32_t config_vals[4] = { base_size, base_size, 0, 0 };
if(horizontal)
config_vals[0] = base_size * globalconf.embedded.len;
else
config_vals[1] = base_size * globalconf.embedded.len;
xcb_configure_window(globalconf.connection,
globalconf.systray.window,
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
config_vals);
/* Now resize each embedded window */
config_vals[0] = config_vals[1] = 0;
config_vals[2] = config_vals[3] = base_size;
for(int i = 0; i < globalconf.embedded.len; i++)
{
xembed_window_t *em = &globalconf.embedded.tab[i];
xcb_configure_window(globalconf.connection, em->win,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
config_vals);
xcb_map_window(globalconf.connection, em->win);
if(horizontal)
config_vals[0] += base_size;
else
config_vals[1] += base_size;
}
}
/** Update the systray
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam The drawin to display the systray in.
* \lparam x X position for the systray.
* \lparam y Y position for the systray.
* \lparam base_size The size (width and height) each systray item gets.
* \lparam horiz If true, the systray is horizontal, else vertical
*/
int
luaA_systray(lua_State *L)
{
if(lua_gettop(L) != 0)
{
drawin_t *w = luaA_checkudata(L, 1, &drawin_class);
int x = luaL_checknumber(L, 2);
int y = luaL_checknumber(L, 3);
int base_size = luaL_checknumber(L, 4);
bool horiz = lua_toboolean(L, 5);
if(globalconf.systray.parent == NULL)
systray_register();
globalconf.systray.parent = w;
if(globalconf.embedded.len != 0)
{
xcb_reparent_window(globalconf.connection,
globalconf.systray.window,
w->window,
x, y);
systray_update(base_size, horiz);
xcb_map_window(globalconf.connection,
globalconf.systray.window);
}
else
xcb_unmap_window(globalconf.connection,
globalconf.systray.window);
}
lua_pushnumber(L, globalconf.embedded.len);
luaA_object_push(L, globalconf.systray.parent);
return 2;
}
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80

View file

@ -23,16 +23,16 @@
#define AWESOME_SYSTRAY_H
#include <xcb/xcb.h>
#include <lua.h>
#include "common/xembed.h"
void systray_init(void);
void systray_refresh(void);
void systray_register(void);
void systray_cleanup(void);
int systray_request_handle(xcb_window_t, xembed_info_t *);
bool systray_iskdedockapp(xcb_window_t);
int systray_process_client_message(xcb_client_message_event_t *);
int xembed_process_client_message(xcb_client_message_event_t *);
int luaA_systray(lua_State *);
#endif
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80