diff options
author | Gary Wong <gtw@gnu.org> | 2009-08-29 12:57:36 -0600 |
---|---|---|
committer | Gary Wong <gtw@gnu.org> | 2009-08-29 12:57:36 -0600 |
commit | dd0c6b4a8321be8f50d06b6a2c67abb63f349ba2 (patch) | |
tree | cc0ade55e491e1cc56221d1788e9232657d2db79 | |
parent | 6c9f78350676e8d364a2ffc499907b6ab5257c5b (diff) |
Use _NET_WM_NAME in preference to WM_NAME.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | gwm.c | 4 | ||||
-rw-r--r-- | gwm.h | 5 | ||||
-rw-r--r-- | managed.c | 123 |
4 files changed, 97 insertions, 44 deletions
@@ -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. @@ -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; @@ -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, @@ -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; } } |