summaryrefslogtreecommitdiffstats
path: root/sesman/chansrv/rail.c
diff options
context:
space:
mode:
Diffstat (limited to 'sesman/chansrv/rail.c')
-rw-r--r--sesman/chansrv/rail.c93
1 files changed, 64 insertions, 29 deletions
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
index 4bfeef7e..f3777970 100644
--- a/sesman/chansrv/rail.c
+++ b/sesman/chansrv/rail.c
@@ -71,6 +71,8 @@ static int g_xrr_event_base = 0; /* non zero means we got extension */
static Cursor g_default_cursor = 0;
+static char *g_override_window_title = 0;
+
/* used in valid field of struct rail_window_data */
#define RWD_X (1 << 0)
#define RWD_Y (1 << 1)
@@ -621,6 +623,18 @@ rail_process_activate(struct stream *s, int size)
}
/*****************************************************************************/
+static int
+rail_select_input(Window window_id)
+{
+ XSelectInput(g_display, window_id,
+ PropertyChangeMask | StructureNotifyMask |
+ SubstructureNotifyMask | FocusChangeMask |
+ EnterWindowMask | LeaveWindowMask);
+ XSync(g_display, 0);
+ return 0;
+}
+
+/*****************************************************************************/
static int APP_CC
rail_restore_windows(void)
{
@@ -637,6 +651,7 @@ rail_restore_windows(void)
XGetWindowAttributes(g_display, children[i], &window_attributes);
if (!window_attributes.override_redirect)
{
+ rail_select_input(children[i]);
if (window_attributes.map_state == IsViewable)
{
rail_win_set_state(children[i], 0x0); /* WithdrawnState */
@@ -724,7 +739,7 @@ rail_win_get_state(Window win)
(unsigned char **)&data,
&nitems);
- if (data || nitems > 0)
+ if (data && nitems > 0)
{
rv = *(unsigned long *)data;
XFree(data);
@@ -760,31 +775,40 @@ rail_win_set_state(Window win, unsigned long state)
}
/*****************************************************************************/
+/* *data pointer that needs g_free */
static int APP_CC
rail_win_get_text(Window win, char **data)
{
int ret = 0;
int i = 0;
unsigned long nitems = 0;
+ unsigned char *ldata = 0;
+ char *lldata = 0;
+ if (g_override_window_title != 0)
+ {
+ *data = g_strdup(g_override_window_title);
+ return g_strlen(*data);
+ }
ret = rail_get_property(g_display, win, g_utf8_string, g_net_wm_name,
- (unsigned char **)data, &nitems);
+ &ldata, &nitems);
if (ret != 0)
{
/* _NET_WM_NAME isn't set, use WM_NAME (XFetchName) instead */
- XFetchName(g_display, win, data);
+ XFetchName(g_display, win, &lldata);
+ *data = g_strdup(lldata);
+ i = g_strlen(*data);
+ XFree(lldata);
+ return i;
}
- if (data)
+ *data = 0;
+ if (ldata)
{
- char *ptr = *data;
- for (; ptr != NULL; i++)
- {
- if (ptr[i] == '\0')
- {
- break;
- }
- }
+ *data = g_strdup((char *)ldata);
+ i = g_strlen(*data);
+ XFree(ldata);
+ return i;
}
return i;
@@ -1207,6 +1231,7 @@ rail_win_send_text(Window win)
int crc;
struct rail_window_data* rwd;
+ LOG(10, ("chansrv::rail_win_send_text:"));
len = rail_win_get_text(win, &data);
rwd = rail_get_window_data_safe(win);
if (rwd != 0)
@@ -1219,7 +1244,7 @@ rail_win_send_text(Window win)
if (rwd->title_crc == crc)
{
LOG(10, ("chansrv::rail_win_send_text: skipping, title not changed"));
- XFree(data);
+ g_free(data);
XFree(rwd);
return 0;
}
@@ -1229,13 +1254,15 @@ rail_win_send_text(Window win)
else
{
LOG(0, ("chansrv::rail_win_send_text: error rail_get_window_data_safe failed"));
+ g_free(data);
return 1;
}
- if (data && len > 0) {
+ if (data && len > 0)
+ {
LOG(10, ("chansrv::rail_win_send_text: 0x%8.8x text %s length %d",
win, data, len));
make_stream(s);
- init_stream(s, 1024);
+ init_stream(s, len + 1024);
flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_FIELD_TITLE;
out_uint32_le(s, 8); /* update title info */
out_uint32_le(s, win); /* window id */
@@ -1251,10 +1278,7 @@ rail_win_send_text(Window win)
rwd->title_crc = crc;
rail_set_window_data(win, rwd);
}
- if (data != 0)
- {
- XFree(data);
- }
+ g_free(data);
XFree(rwd);
return 0;
}
@@ -1355,7 +1379,8 @@ rail_create_window(Window window_id, Window owner_id)
flags = WINDOW_ORDER_TYPE_WINDOW;
}
- title_size = rail_win_get_text(window_id, &title_bytes);
+ title_size = 0;
+ title_bytes = 0;
XGetTransientForHint(g_display, window_id, &transient_for);
@@ -1363,21 +1388,24 @@ rail_create_window(Window window_id, Window owner_id)
{
style = RAIL_STYLE_TOOLTIP;
ext_style = RAIL_EXT_STYLE_TOOLTIP;
+ /* for tooltips, we don't grab the window text */
}
else if (transient_for > 0)
{
style = RAIL_STYLE_DIALOG;
ext_style = RAIL_EXT_STYLE_DIALOG;
owner_id = transient_for;
+ title_size = rail_win_get_text(window_id, &title_bytes);
}
else
{
style = RAIL_STYLE_NORMAL;
ext_style = RAIL_EXT_STYLE_NORMAL;
+ title_size = rail_win_get_text(window_id, &title_bytes);
}
make_stream(s);
- init_stream(s, 1024);
+ init_stream(s, title_size + 1024 + num_window_rects * 8 + num_visibility_rects * 8);
out_uint32_le(s, 2); /* create_window */
out_uint32_le(s, window_id); /* window_id */
@@ -1387,6 +1415,7 @@ rail_create_window(Window window_id, Window owner_id)
out_uint32_le(s, ext_style); /* extended_style */
flags |= WINDOW_ORDER_FIELD_STYLE;
out_uint32_le(s, 0x05); /* show_state */
+ LOG(10, (" title %s", title_bytes));
flags |= WINDOW_ORDER_FIELD_SHOW;
if (title_size > 0)
{
@@ -1449,7 +1478,7 @@ rail_create_window(Window window_id, Window owner_id)
s_mark_end(s);
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
free_stream(s);
- XFree(title_bytes);
+ g_free(title_bytes);
rail_set_window_data(window_id, rwd);
XFree(rwd);
return 0;
@@ -1608,7 +1637,7 @@ rail_configure_request_window(XConfigureRequestEvent* config)
flags = WINDOW_ORDER_TYPE_WINDOW;
make_stream(s);
- init_stream(s, 1024);
+ init_stream(s, 1024 + num_window_rects * 8 + num_visibility_rects * 8);
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
@@ -1692,7 +1721,7 @@ rail_configure_window(XConfigureEvent *config)
flags = WINDOW_ORDER_TYPE_WINDOW;
make_stream(s);
- init_stream(s, 1024);
+ init_stream(s, 1024 + num_window_rects * 8 + num_visibility_rects * 8);
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
@@ -1822,10 +1851,7 @@ rail_xevent(void *xevent)
case CreateNotify:
LOG(10, (" got CreateNotify window 0x%8.8x parent 0x%8.8x",
lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent));
- XSelectInput(g_display, lxevent->xcreatewindow.window,
- PropertyChangeMask | StructureNotifyMask |
- SubstructureNotifyMask | FocusChangeMask |
- EnterWindowMask | LeaveWindowMask);
+ rail_select_input(lxevent->xcreatewindow.window);
break;
case DestroyNotify:
@@ -1865,7 +1891,7 @@ rail_xevent(void *xevent)
XGetWindowAttributes(g_display, lxevent->xmap.window, &wnd_attributes);
if (wnd_attributes.map_state == IsViewable)
{
- rail_create_window(lxevent->xmap.window, lxevent->xmap.event);
+ rail_create_window(lxevent->xmap.window, g_root_window);
if (!wnd_attributes.override_redirect)
{
rail_win_set_state(lxevent->xmap.window, 0x1); /* NormalState */
@@ -1887,7 +1913,16 @@ rail_xevent(void *xevent)
LOG(10, (" window 0x%8.8x is unmapped", lxevent->xunmap.window));
if (index >= 0)
{
+ XGetWindowAttributes(g_display, lxevent->xunmap.window, &wnd_attributes);
+ if (wnd_attributes.override_redirect)
+ {
+ // remove popups
+ rail_destroy_window(lxevent->xunmap.window);
+ list_remove_item(g_window_list, index);
+ } else {
rail_show_window(lxevent->xunmap.window, 0x0);
+ }
+
rv = 0;
}
}