summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Wong <gtw@gnu.org>2009-08-29 12:57:36 -0600
committerGary Wong <gtw@gnu.org>2009-08-29 12:57:36 -0600
commitdd0c6b4a8321be8f50d06b6a2c67abb63f349ba2 (patch)
treecc0ade55e491e1cc56221d1788e9232657d2db79
parent6c9f78350676e8d364a2ffc499907b6ab5257c5b (diff)
Use _NET_WM_NAME in preference to WM_NAME.
-rw-r--r--ChangeLog9
-rw-r--r--gwm.c4
-rw-r--r--gwm.h5
-rw-r--r--managed.c123
4 files changed, 97 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog
index d0b6a94..b1fe3a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-08-29 Gary Wong <gtw@gnu.org>
+
+ * managed.c (managed_property_change): Use _NET_WM_NAME in preference
+ to WM_NAME.
+ (async_get_property): New function.
+ (managed_property_notify): Use async_get_property.
+ * gwm.c (start_managing_window): Initialise net_wm_name.
+ (setup_display): Add _NET_WM_NAME property.
+
2009-08-28 Gary Wong <gtw@gnu.org>
* frame.c (recalc_size): Initialise feedback->u.feedback.
diff --git a/gwm.c b/gwm.c
index ccd40d8..ef8761b 100644
--- a/gwm.c
+++ b/gwm.c
@@ -89,6 +89,7 @@ xcb_atom_t atoms[ NUM_ATOMS ];
static const char *atom_names[ NUM_ATOMS ] = {
"COMPOUND_TEXT",
"MANAGER",
+ "_NET_WM_NAME",
"UTF8_STRING",
"VERSION",
"WM_CHANGE_STATE",
@@ -1265,6 +1266,7 @@ static void start_managing_window( struct gwm_window *window,
window->u.managed.cmap = attr->colormap;
window->u.managed.hints = 0;
window->u.managed.name = NULL;
+ window->u.managed.net_wm_name = 0;
window->u.managed.state = STATE_WITHDRAWN;
frame->screen = window->screen;
frame->type = WINDOW_FRAME;
@@ -1890,12 +1892,14 @@ static void setup_display( void ) {
_NET_WM_NAME, UTF-8 in preference to WM_NAME
_NET_WM_ICON, ARGB icon(s)
and set _NET_FRAME_EXTENTS. */
+ prop_atoms[ PROP__NET_WM_NAME ] = atoms[ ATOM__NET_WM_NAME ];
prop_atoms[ PROP_WM_COLORMAP_WINDOWS ] = atoms[ ATOM_WM_COLORMAP_WINDOWS ];
prop_atoms[ PROP_WM_HINTS ] = WM_HINTS;
prop_atoms[ PROP_WM_NAME ] = WM_NAME;
prop_atoms[ PROP_WM_NORMAL_HINTS ] = WM_NORMAL_HINTS;
prop_atoms[ PROP_WM_PROTOCOLS ] = atoms[ ATOM_WM_PROTOCOLS ];
+ prop_types[ PROP__NET_WM_NAME ] = atoms[ ATOM_UTF8_STRING ];
prop_types[ PROP_WM_COLORMAP_WINDOWS ] = WINDOW;
prop_types[ PROP_WM_HINTS ] = WM_HINTS;
prop_types[ PROP_WM_NAME ] = XCB_GET_PROPERTY_TYPE_ANY;
diff --git a/gwm.h b/gwm.h
index 5f02ade..1ee7540 100644
--- a/gwm.h
+++ b/gwm.h
@@ -65,6 +65,7 @@ enum x_atom {
enum gwm_atom {
ATOM_COMPOUND_TEXT,
ATOM_MANAGER,
+ ATOM__NET_WM_NAME,
ATOM_UTF8_STRING,
ATOM_VERSION,
ATOM_WM_CHANGE_STATE,
@@ -80,6 +81,7 @@ enum gwm_atom {
extern xcb_atom_t atoms[ NUM_ATOMS ];
enum gwm_property_type {
+ PROP__NET_WM_NAME,
PROP_WM_COLORMAP_WINDOWS,
PROP_WM_HINTS,
PROP_WM_NAME,
@@ -202,8 +204,9 @@ struct gwm_window {
xcb_window_t cmap_window;
/* from WM_HINTS: */
int hints; /* see HINT_* above */
- /* from WM_NAME: */
+ /* from WM_NAME and _NET_WM_NAME: */
char *name; /* must be free()d */
+ int net_wm_name;
/* from WM_NORMAL_HINTS: */
int min_width, min_height, max_width, max_height, width_inc,
height_inc, min_aspect_x, min_aspect_y, max_aspect_x,
diff --git a/managed.c b/managed.c
index 43d6ea9..c76bb19 100644
--- a/managed.c
+++ b/managed.c
@@ -25,6 +25,7 @@
#include <assert.h>
#include <stdlib.h>
+#include <string.h>
#include <xcb/xcb.h>
#if USE_SHAPE
#include <xcb/shape.h>
@@ -70,6 +71,52 @@ static void managed_reparent_notify( struct gwm_window *window,
unmanage_window( window->u.frame.child );
}
+struct managed_get_property {
+ struct gwm_window *window;
+ enum gwm_property_type prop;
+};
+
+static void handle_managed_get_property( unsigned int sequence, void *reply,
+ xcb_generic_error_t *error,
+ union callback_param cp ) {
+
+ struct managed_get_property *p = cp.p;
+
+ if( error ) {
+ /* Ignore Window errors, since the window might have been destroyed
+ in the meantime. */
+ if( error->error_code != XCB_WINDOW )
+ show_error( error );
+
+ free( error );
+ }
+
+ if( reply ) {
+ managed_property_change( p->window, p->prop, reply );
+
+ free( reply );
+ }
+
+ free( p );
+}
+
+static void async_get_property( struct gwm_window *window,
+ enum gwm_property_type prop ) {
+
+ struct managed_get_property *p = xmalloc( sizeof *p );
+ union callback_param cp;
+
+ p->window = window;
+ p->prop = prop;
+
+ cp.p = p;
+ handle_async_reply( xcb_get_property( c, FALSE, window->w,
+ prop_atoms[ prop ],
+ prop_types[ prop ], 0,
+ PROP_SIZE ).sequence,
+ handle_managed_get_property, cp );
+}
+
#define WM_HINTS_INPUT 0x1
#define WM_HINTS_STATE 0x2
@@ -109,6 +156,31 @@ extern void managed_property_change( struct gwm_window *window, int prop,
assert( window->type == WINDOW_MANAGED );
switch( prop ) {
+ case PROP__NET_WM_NAME:
+ if( window->u.managed.name )
+ free( window->u.managed.name );
+
+ if( p->value_len && p->format == 8 ) {
+ window->u.managed.name = xmalloc( p->value_len + 1 );
+ memcpy( window->u.managed.name, xcb_get_property_value( p ),
+ p->value_len );
+ window->u.managed.name[ p->value_len ] = 0;
+ window->u.managed.net_wm_name = 1;
+
+ if( window->u.managed.state == STATE_NORMAL )
+ queue_window_update( window->u.managed.frame, 0, 0,
+ window->u.managed.frame->u.frame.width,
+ FRAME_TITLE_HEIGHT, FALSE );
+ } else {
+ window->u.managed.name = NULL;
+ window->u.managed.net_wm_name = 0;
+ /* We've lost the _NET_WM_NAME property. If the window still
+ has a plain WM_NAME, then fall back to that. */
+ async_get_property( window, PROP_WM_NAME );
+ }
+
+ break;
+
case PROP_WM_COLORMAP_WINDOWS:
/* WM_COLORMAP_WINDOWS property (see ICCCM 2.0, section 4.1.8). */
window->u.managed.cmap_window = XCB_NONE;
@@ -156,6 +228,10 @@ extern void managed_property_change( struct gwm_window *window, int prop,
case PROP_WM_NAME:
/* WM_NAME property (see ICCCM 2.0, section 4.1.2.1). */
+ if( window->u.managed.net_wm_name )
+ /* Ignore WM_NAME if _NET_WM_NAME is set. */
+ break;
+
if( window->u.managed.name )
free( window->u.managed.name );
@@ -361,53 +437,14 @@ extern void managed_property_change( struct gwm_window *window, int prop,
}
}
-struct managed_get_property {
- struct gwm_window *window;
- int prop;
-};
-
-static void handle_managed_get_property( unsigned int sequence, void *reply,
- xcb_generic_error_t *error,
- union callback_param cp ) {
-
- struct managed_get_property *p = cp.p;
-
- if( error ) {
- /* Ignore Window errors, since the window might have been destroyed
- in the meantime. */
- if( error->error_code != XCB_WINDOW )
- show_error( error );
-
- free( error );
- }
-
- if( reply ) {
- managed_property_change( p->window, p->prop, reply );
-
- free( reply );
- }
-
- free( p );
-}
-
static void managed_property_notify( struct gwm_window *window,
xcb_property_notify_event_t *ev ) {
- int i;
- for( i = 0; i < NUM_PROPS; i++ )
- if( ev->atom == prop_atoms[ i ] ) {
- struct managed_get_property *p = xmalloc( sizeof *p );
- union callback_param cp;
+ enum gwm_property_type i;
- p->window = window;
- p->prop = i;
-
- cp.p = p;
- handle_async_reply( xcb_get_property( c, FALSE, window->w,
- prop_atoms[ i ],
- prop_types[ i ], 0,
- PROP_SIZE ).sequence,
- handle_managed_get_property, cp );
+ for( i = 0; i < NUM_PROPS; i++ )
+ if( ev->atom == prop_atoms[ i ] ) {
+ async_get_property( window, i );
return;
}
}