@ -24,6 +24,7 @@ void free_sway_binding(struct sway_binding *binding) {
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						list_free_items_and_destroy ( binding - > keys ) ; 
 
			
		
	
		
			
				
						list_free_items_and_destroy ( binding - > syms ) ; 
 
			
		
	
		
			
				
						free ( binding - > input ) ; 
 
			
		
	
		
			
				
						free ( binding - > command ) ; 
 
			
		
	
		
			
				
						free ( binding ) ; 
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -249,31 +250,41 @@ static struct cmd_results *switch_binding_remove(
 
			
		
	
		
			
				
								switchcombo ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  struct  cmd_results  * binding_add ( struct  sway_binding  * binding ,  
			
		
	
		
			
				
							list_t  * mode_bindings ,  const  char  * bindtype , 
 
			
		
	
		
			
				
							const  char  * keycombo ,  bool  warn )  { 
 
			
		
	
		
			
				
						// overwrite the binding if it already exists
 
 
			
		
	
		
			
				
						bool  overwritten  =  false ; 
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Insert  or  update  the  binding . 
 
			
		
	
		
			
				
					 *  Return  the  binding  which  has  been  replaced  or  NULL . 
 
			
		
	
		
			
				
					 */ 
 
			
		
	
		
			
				
					static  struct  sway_binding  * binding_upsert ( struct  sway_binding  * binding ,  
			
		
	
		
			
				
							list_t  * mode_bindings )  { 
 
			
		
	
		
			
				
						for  ( int  i  =  0 ;  i  <  mode_bindings - > length ;  + + i )  { 
 
			
		
	
		
			
				
							struct  sway_binding  * config_binding  =  mode_bindings - > items [ i ] ; 
 
			
		
	
		
			
				
							if  ( binding_key_compare ( binding ,  config_binding ) )  { 
 
			
		
	
		
			
				
								sway_log ( SWAY_INFO ,  " Overwriting binding '%s' for device '%s'  " 
 
			
		
	
		
			
				
										" to `%s` from `%s` " ,  keycombo ,  binding - > input , 
 
			
		
	
		
			
				
										binding - > command ,  config_binding - > command ) ; 
 
			
		
	
		
			
				
								if  ( warn )  { 
 
			
		
	
		
			
				
									config_add_swaynag_warning ( " Overwriting binding " 
 
			
		
	
		
			
				
											" '%s' for device '%s' to `%s` from `%s` " , 
 
			
		
	
		
			
				
											keycombo ,  binding - > input ,  binding - > command , 
 
			
		
	
		
			
				
											config_binding - > command ) ; 
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
								free_sway_binding ( config_binding ) ; 
 
			
		
	
		
			
				
								mode_bindings - > items [ i ]  =  binding ; 
 
			
		
	
		
			
				
								overwritten  =  true ; 
 
			
		
	
		
			
				
								return  config_binding ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( ! overwritten )  { 
 
			
		
	
		
			
				
							list_add ( mode_bindings ,  binding ) ; 
 
			
		
	
		
			
				
						list_add ( mode_bindings ,  binding ) ; 
 
			
		
	
		
			
				
						return  NULL ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  struct  cmd_results  * binding_add ( struct  sway_binding  * binding ,  
			
		
	
		
			
				
							list_t  * mode_bindings ,  const  char  * bindtype , 
 
			
		
	
		
			
				
							const  char  * keycombo ,  bool  warn )  { 
 
			
		
	
		
			
				
						struct  sway_binding  * config_binding  =  binding_upsert ( binding ,  mode_bindings ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( config_binding )  { 
 
			
		
	
		
			
				
							sway_log ( SWAY_INFO ,  " Overwriting binding '%s' for device '%s'  " 
 
			
		
	
		
			
				
									" to `%s` from `%s` " ,  keycombo ,  binding - > input , 
 
			
		
	
		
			
				
									binding - > command ,  config_binding - > command ) ; 
 
			
		
	
		
			
				
							if  ( warn )  { 
 
			
		
	
		
			
				
								config_add_swaynag_warning ( " Overwriting binding " 
 
			
		
	
		
			
				
										" '%s' for device '%s' to `%s` from `%s` " , 
 
			
		
	
		
			
				
										keycombo ,  binding - > input ,  binding - > command , 
 
			
		
	
		
			
				
										config_binding - > command ) ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
							free_sway_binding ( config_binding ) ; 
 
			
		
	
		
			
				
						}  else  { 
 
			
		
	
		
			
				
							sway_log ( SWAY_DEBUG ,  " %s - Bound %s to command `%s` for device '%s' " , 
 
			
		
	
		
			
				
									bindtype ,  keycombo ,  binding - > command ,  binding - > input ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -329,7 +340,6 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
 
			
		
	
		
			
				
						bool  exclude_titlebar  =  false ; 
 
			
		
	
		
			
				
						bool  warn  =  true ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// Handle --release and --locked
 
 
			
		
	
		
			
				
						while  ( argc  >  0 )  { 
 
			
		
	
		
			
				
							if  ( strcmp ( " --release " ,  argv [ 0 ] )  = =  0 )  { 
 
			
		
	
		
			
				
								binding - > flags  | =  BINDING_RELEASE ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -339,6 +349,10 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
 
			
		
	
		
			
				
								binding - > flags  | =  BINDING_BORDER  |  BINDING_CONTENTS  |  BINDING_TITLEBAR ; 
 
			
		
	
		
			
				
							}  else  if  ( strcmp ( " --border " ,  argv [ 0 ] )  = =  0 )  { 
 
			
		
	
		
			
				
								binding - > flags  | =  BINDING_BORDER ; 
 
			
		
	
		
			
				
							}  else  if  ( strcmp ( " --to-code " ,  argv [ 0 ] )  = =  0 )  { 
 
			
		
	
		
			
				
								if  ( ! bindcode )  { 
 
			
		
	
		
			
				
									binding - > flags  | =  BINDING_CODE ; 
 
			
		
	
		
			
				
								} 
 
			
		
	
		
			
				
							}  else  if  ( strcmp ( " --exclude-titlebar " ,  argv [ 0 ] )  = =  0 )  { 
 
			
		
	
		
			
				
								exclude_titlebar  =  true ; 
 
			
		
	
		
			
				
							}  else  if  ( strncmp ( " --input-device= " ,  argv [ 0 ] , 
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -410,6 +424,12 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
 
			
		
	
		
			
				
						// sort ascending
 
 
			
		
	
		
			
				
						list_qsort ( binding - > keys ,  key_qsort_cmp ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// translate keysyms into keycodes
 
 
			
		
	
		
			
				
						if  ( ! translate_binding ( binding ) )  { 
 
			
		
	
		
			
				
							sway_log ( SWAY_INFO , 
 
			
		
	
		
			
				
									" Unable to translate bindsym into bindcode: %s " ,  argv [ 0 ] ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						list_t  * mode_bindings ; 
 
			
		
	
		
			
				
						if  ( binding - > type  = =  BINDING_KEYCODE )  { 
 
			
		
	
		
			
				
							mode_bindings  =  config - > current_mode - > keycode_bindings ; 
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -566,3 +586,114 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding)
 
			
		
	
		
			
				
							ipc_event_binding ( binding ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  The  last  found  keycode  associated  with  the  keysym 
 
			
		
	
		
			
				
					 *  and  the  total  count  of  matches . 
 
			
		
	
		
			
				
					 */ 
 
			
		
	
		
			
				
					struct  keycode_matches  {  
			
		
	
		
			
				
						xkb_keysym_t  keysym ; 
 
			
		
	
		
			
				
						xkb_keycode_t  keycode ; 
 
			
		
	
		
			
				
						int  count ; 
 
			
		
	
		
			
				
					} ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Iterate  through  keycodes  in  the  keymap  to  find  ones  matching 
 
			
		
	
		
			
				
					 *  the  specified  keysym . 
 
			
		
	
		
			
				
					 */ 
 
			
		
	
		
			
				
					static  void  find_keycode ( struct  xkb_keymap  * keymap ,  
			
		
	
		
			
				
							xkb_keycode_t  keycode ,  void  * data )  { 
 
			
		
	
		
			
				
						xkb_keysym_t  keysym  =  xkb_state_key_get_one_sym ( 
 
			
		
	
		
			
				
								config - > keysym_translation . xkb_state ,  keycode ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( keysym  = =  XKB_KEY_NoSymbol )  { 
 
			
		
	
		
			
				
							return ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  keycode_matches  * matches  =  data ; 
 
			
		
	
		
			
				
						if  ( matches - > keysym  = =  keysym )  { 
 
			
		
	
		
			
				
							matches - > keycode  =  keycode ; 
 
			
		
	
		
			
				
							matches - > count + + ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					/**
  
			
		
	
		
			
				
					 *  Return  the  keycode  for  the  specified  keysym . 
 
			
		
	
		
			
				
					 */ 
 
			
		
	
		
			
				
					static  struct  keycode_matches  get_keycode_for_keysym ( xkb_keysym_t  keysym )  {  
			
		
	
		
			
				
						struct  keycode_matches  matches  =  { 
 
			
		
	
		
			
				
							. keysym  =  keysym , 
 
			
		
	
		
			
				
							. keycode  =  XKB_KEYCODE_INVALID , 
 
			
		
	
		
			
				
							. count  =  0 , 
 
			
		
	
		
			
				
						} ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						xkb_keymap_key_for_each ( config - > keysym_translation . xkb_keymap , 
 
			
		
	
		
			
				
								find_keycode ,  & matches ) ; 
 
			
		
	
		
			
				
						return  matches ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					bool  translate_binding ( struct  sway_binding  * binding )  {  
			
		
	
		
			
				
						if  ( ( binding - > flags  &  BINDING_CODE )  = =  0 )  { 
 
			
		
	
		
			
				
							return  true ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						switch  ( binding - > type )  { 
 
			
		
	
		
			
				
						// a bindsym to translate
 
 
			
		
	
		
			
				
						case  BINDING_KEYSYM : 
 
			
		
	
		
			
				
							binding - > syms  =  binding - > keys ; 
 
			
		
	
		
			
				
							binding - > keys  =  create_list ( ) ; 
 
			
		
	
		
			
				
							break ; 
 
			
		
	
		
			
				
						// a bindsym to re-translate
 
 
			
		
	
		
			
				
						case  BINDING_KEYCODE : 
 
			
		
	
		
			
				
							list_free_items_and_destroy ( binding - > keys ) ; 
 
			
		
	
		
			
				
							binding - > keys  =  create_list ( ) ; 
 
			
		
	
		
			
				
							break ; 
 
			
		
	
		
			
				
						default : 
 
			
		
	
		
			
				
							return  true ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						for  ( int  i  =  0 ;  i  <  binding - > syms - > length ;  + + i )  { 
 
			
		
	
		
			
				
							xkb_keysym_t  * keysym  =  binding - > syms - > items [ i ] ; 
 
			
		
	
		
			
				
							struct  keycode_matches  matches  =  get_keycode_for_keysym ( * keysym ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							if  ( matches . count  ! =  1 )  { 
 
			
		
	
		
			
				
								sway_log ( SWAY_INFO ,  " Unable to convert keysym %d into " 
 
			
		
	
		
			
				
										"  a single keycode (found %d matches) " , 
 
			
		
	
		
			
				
										* keysym ,  matches . count ) ; 
 
			
		
	
		
			
				
								goto  error ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							xkb_keycode_t  * keycode  =  malloc ( sizeof ( xkb_keycode_t ) ) ; 
 
			
		
	
		
			
				
							if  ( ! keycode )  { 
 
			
		
	
		
			
				
								sway_log ( SWAY_ERROR ,  " Unable to allocate memory for a keycode " ) ; 
 
			
		
	
		
			
				
								goto  error ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							* keycode  =  matches . keycode ; 
 
			
		
	
		
			
				
							list_add ( binding - > keys ,  keycode ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						list_qsort ( binding - > keys ,  key_qsort_cmp ) ; 
 
			
		
	
		
			
				
						binding - > type  =  BINDING_KEYCODE ; 
 
			
		
	
		
			
				
						return  true ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					error :  
			
		
	
		
			
				
						list_free_items_and_destroy ( binding - > keys ) ; 
 
			
		
	
		
			
				
						binding - > type  =  BINDING_KEYSYM ; 
 
			
		
	
		
			
				
						binding - > keys  =  binding - > syms ; 
 
			
		
	
		
			
				
						binding - > syms  =  NULL ; 
 
			
		
	
		
			
				
						return  false ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					void  binding_add_translated ( struct  sway_binding  * binding ,  
			
		
	
		
			
				
							list_t  * mode_bindings )  { 
 
			
		
	
		
			
				
						struct  sway_binding  * config_binding  = 
 
			
		
	
		
			
				
							binding_upsert ( binding ,  mode_bindings ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( config_binding )  { 
 
			
		
	
		
			
				
							sway_log ( SWAY_INFO ,  " Overwriting binding for device '%s'  " 
 
			
		
	
		
			
				
									" to `%s` from `%s` " ,  binding - > input , 
 
			
		
	
		
			
				
									binding - > command ,  config_binding - > command ) ; 
 
			
		
	
		
			
				
							free_sway_binding ( config_binding ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					}