diff options
author | Gary Wong <gtw@gnu.org> | 2009-09-01 21:27:49 -0600 |
---|---|---|
committer | Gary Wong <gtw@gnu.org> | 2009-09-01 21:27:49 -0600 |
commit | cc9aee3cc95f16bc95537535ef2413da50686623 (patch) | |
tree | 7cbaea0581170e3309e346783445657b98a85057 | |
parent | db6024a4eb1f55605e344d9cb640424038a239be (diff) |
Add new icon handling actions.
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | actions.c | 26 | ||||
-rw-r--r-- | actions.h | 8 | ||||
-rw-r--r-- | gwm.c | 57 | ||||
-rw-r--r-- | gwm.h | 2 | ||||
-rw-r--r-- | keyboard.c | 6 | ||||
-rw-r--r-- | keyboard.h | 5 | ||||
-rw-r--r-- | managed.c | 57 | ||||
-rw-r--r-- | managed.h | 5 | ||||
-rw-r--r-- | root.c | 2 |
10 files changed, 116 insertions, 63 deletions
@@ -1,5 +1,16 @@ 2009-09-01 Gary Wong <gtw@gnu.org> + * actions.c (action_iconify_window, action_deiconify_window): New + functions. + * keyboard.c (establish_grabs): Replace NUM_KEY_ACTIONS with new + num_key_actions symbol. + * managed.c (set_managed_state, iconic_to_normal): Moved from gwm.c. + (normal_to_iconic): New function. + * gwm.c (handle_client_message): Use new normal_to_iconic() function. + * root.c (root_key_press): Likewise. + +2009-09-01 Gary Wong <gtw@gnu.org> + * menu.c, menu.h: New files. * actions.c: Added callback parameter to all actions. All callers changed. @@ -34,6 +34,7 @@ #include "actions.h" #include "frame.h" +#include "managed.h" #include "menu.h" #include "window-table.h" @@ -101,6 +102,30 @@ extern void action_root_menu( struct gwm_window *window, popup_menu( window, ev, sizeof root_menu / sizeof *root_menu, root_menu ); } +extern void action_iconify_window( struct gwm_window *window, + xcb_generic_event_t *ev, + union callback_param cp ) { + + if( window->type == WINDOW_FRAME ) + window = window->u.frame.child; + + if( window->type == WINDOW_MANAGED && + window->u.managed.state == STATE_NORMAL ) + normal_to_iconic( window ); +} + +extern void action_deiconify_window( struct gwm_window *window, + xcb_generic_event_t *ev, + union callback_param cp ) { + + if( window->type == WINDOW_FRAME ) + window = window->u.frame.child; + + if( window->type == WINDOW_MANAGED && + window->u.managed.state == STATE_ICONIC ) + iconic_to_normal( window ); +} + extern void action_map_all_icons( struct gwm_window *window, xcb_generic_event_t *ev, union callback_param cp ) { @@ -126,6 +151,7 @@ extern void action_window_menu( struct gwm_window *window, /* FIXME this should be configurable, of course */ const struct menuitem window_menu[] = { + { "Iconify", action_iconify_window }, { "Raise/lower", action_stack_opposite } }; @@ -13,6 +13,14 @@ extern void action_root_menu( struct gwm_window *window, xcb_generic_event_t *ev, union callback_param cp ); +extern void action_iconify_window( struct gwm_window *window, + xcb_generic_event_t *ev, + union callback_param cp ); + +extern void action_deiconify_window( struct gwm_window *window, + xcb_generic_event_t *ev, + union callback_param cp ); + extern void action_map_all_icons( struct gwm_window *window, xcb_generic_event_t *ev, union callback_param cp ); @@ -1012,21 +1012,6 @@ static void stop_listening( struct gwm_window *window ) { #endif } -static void set_managed_state( struct gwm_window *window, int state ) { - - uint32_t values[ 2 ]; - - assert( window->type == WINDOW_MANAGED ); - - /* Place a WM_STATE property on the client window (ICCCM 2.0, section - 4.1.3.1). */ - values[ 0 ] = window->u.managed.state = state; - values[ 1 ] = XCB_NONE; - xcb_change_property( c, XCB_PROP_MODE_REPLACE, window->w, - atoms[ ATOM_WM_STATE ], atoms[ ATOM_WM_STATE ], - 32, 2, values ); -} - static void place_window( struct gwm_window *window, int *x, int *y, int width, int height ) { @@ -1436,15 +1421,6 @@ extern void unmanage_window( struct gwm_window *window ) { frame->type = WINDOW_CHILDLESS; } -extern void iconic_to_normal( struct gwm_window *window ) { - - assert( window->type == WINDOW_MANAGED ); - - set_managed_state( window, STATE_NORMAL ); - xcb_map_window( c, window->w ); - xcb_map_window( c, window->u.managed.frame->w ); -} - extern void generic_expose( struct gwm_window *window, xcb_expose_event_t *ev ) { @@ -2143,37 +2119,8 @@ static void handle_client_message( xcb_client_message_event_t *ev ) { if( ( window = lookup_window( ev->window ) ) && window->type == WINDOW_MANAGED && window->u.managed.state == STATE_NORMAL && - ev->data.data32[ 0 ] == STATE_ICONIC ) { - uint32_t n; - - set_managed_state( window, STATE_ICONIC ); - /* We need to unmap our child without invoking the normal - UnmapNotify handler response. Unfortunately it's very - difficult to communicate to the handler the distinction - between the resultant UnmapNotify from an unmap here - and an unrelated event. Checking the request sequence - is not robust, because asynchronous events might not be - assigned unique sequence numbers. Instead, we grab - the server and temporarily change our event mask, which - seems a heavyweight approach but does guarantee that - only this event will be ignored. */ - xcb_grab_server( c ); - - n = XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE; - xcb_change_window_attributes( c, window->w, XCB_CW_EVENT_MASK, &n ); - - xcb_unmap_window( c, window->w ); - - n = XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_COLOR_MAP_CHANGE; - xcb_change_window_attributes( c, window->w, XCB_CW_EVENT_MASK, &n ); - - xcb_ungrab_server( c ); - - xcb_unmap_window( c, window->u.managed.frame->w ); - } + ev->data.data32[ 0 ] == STATE_ICONIC ) + normal_to_iconic( window ); } else if( ev->type == atoms[ ATOM_WM_COLORMAP_NOTIFY ] ) { struct gwm_window *window; @@ -345,8 +345,6 @@ extern void install_window_colormap( int screen, struct gwm_window *window, extern void generic_expose( struct gwm_window *window, xcb_expose_event_t *ev ); -extern void iconic_to_normal( struct gwm_window *window ); - extern void manage_window( xcb_window_t w, int map_request ); extern void unmanage_window( struct gwm_window *window ); @@ -66,11 +66,13 @@ xcb_keysym_t keyboard_map[ 0x100 ][ 4 ]; /* Map of modifiers, indexed by xcb_map_index_t. */ xcb_keycode_t *modifier_map[ 8 ]; -const struct key_action key_actions[ NUM_KEY_ACTIONS ] = { +const struct key_action key_actions[] = { /* FIXME This table should be configurable, of course. */ { KEYSYM_TAB, XCB_MOD_MASK_1, action_raise_lowest }, + { KEYSYM_F1, XCB_MOD_MASK_1, action_iconify_window }, { KEYSYM_F5, XCB_MOD_MASK_1, action_stack_opposite } }; +const int num_key_actions = sizeof key_actions / sizeof *key_actions; static void establish_grabs( void ) { @@ -103,7 +105,7 @@ static void establish_grabs( void ) { xcb_ungrab_key( c, XCB_GRAB_ANY, screens[ screen ]->root, XCB_GRAB_ANY ); - for( i = 0; i < NUM_KEY_ACTIONS; i++ ) { + for( i = 0; i < num_key_actions; i++ ) { for( j = 0; j < 0x100 && keyboard_map[ j ][ 0 ] != key_actions[ i ].keysym; j++ ) ; @@ -6,14 +6,13 @@ extern xcb_keysym_t keyboard_map[ 0x100 ][ 4 ]; /* Map of modifiers, indexed by xcb_map_index_t. */ extern xcb_keycode_t *modifier_map[ 8 ]; -#define NUM_KEY_ACTIONS 2 - extern const struct key_action { xcb_keysym_t keysym; xcb_mod_mask_t modifiers; void ( *handler )( struct gwm_window *window, xcb_generic_event_t *ev, union callback_param cp ); -} key_actions[ NUM_KEY_ACTIONS ]; +} key_actions[]; +extern const int num_key_actions; extern void get_keyboard_mapping( int first, int count ); extern void get_modifier_mapping( void ); @@ -38,6 +38,63 @@ #include "utf8.h" #include "window-table.h" +extern void set_managed_state( struct gwm_window *window, int state ) { + + uint32_t values[ 2 ]; + + assert( window->type == WINDOW_MANAGED ); + + /* Place a WM_STATE property on the client window (ICCCM 2.0, section + 4.1.3.1). */ + values[ 0 ] = window->u.managed.state = state; + values[ 1 ] = XCB_NONE; + xcb_change_property( c, XCB_PROP_MODE_REPLACE, window->w, + atoms[ ATOM_WM_STATE ], atoms[ ATOM_WM_STATE ], + 32, 2, values ); +} + +extern void iconic_to_normal( struct gwm_window *window ) { + + assert( window->type == WINDOW_MANAGED ); + + set_managed_state( window, STATE_NORMAL ); + xcb_map_window( c, window->w ); + xcb_map_window( c, window->u.managed.frame->w ); +} + +extern void normal_to_iconic( struct gwm_window *window ) { + + uint32_t n; + + assert( window->type == WINDOW_MANAGED ); + + set_managed_state( window, STATE_ICONIC ); + + /* We need to unmap our child without invoking the normal + UnmapNotify handler response. Unfortunately it's very + difficult to communicate to the handler the distinction between + the resultant UnmapNotify from an unmap here and an unrelated + event. Checking the request sequence is not robust, because + asynchronous events might not be assigned unique sequence + numbers. Instead, we grab the server and temporarily change + our event mask, which seems a heavyweight approach but does + guarantee that only this event will be ignored. */ + xcb_grab_server( c ); + + n = XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_COLOR_MAP_CHANGE; + xcb_change_window_attributes( c, window->w, XCB_CW_EVENT_MASK, &n ); + + xcb_unmap_window( c, window->w ); + + n = XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE | + XCB_EVENT_MASK_COLOR_MAP_CHANGE; + xcb_change_window_attributes( c, window->w, XCB_CW_EVENT_MASK, &n ); + + xcb_ungrab_server( c ); + + xcb_unmap_window( c, window->u.managed.frame->w ); +} + static void managed_destroy_notify( struct gwm_window *window, xcb_destroy_notify_event_t *ev ) { @@ -1,6 +1,11 @@ #ifndef MANAGED_H #define MANAGED_H +extern void iconic_to_normal( struct gwm_window *window ); +extern void normal_to_iconic( struct gwm_window *window ); + +extern void set_managed_state( struct gwm_window *window, int state ); + #if USE_SHAPE extern void match_managed_shape( struct gwm_window *window ); #endif @@ -39,7 +39,7 @@ static void root_key_press( struct gwm_window *window, int i; - for( i = 0; i < NUM_KEY_ACTIONS; i++ ) + for( i = 0; i < num_key_actions; i++ ) if( keyboard_map[ ev->detail ][ 0 ] == key_actions[ i ].keysym && ( ev->state & 0xFF & key_actions[ i ].modifiers ) == key_actions[ i ].modifiers ) { |