Introduce --exclude-titlebar flag for mouse bindings. (#2703)
This introduces the flag --exclude-titlebar for mouse bindings which allows bindings like bindsym --whole-window --border --exclude-titlebar button3 focus fixes #2347
This commit is contained in:
parent
1d4e9f5de0
commit
d78fd8d91f
@ -412,9 +412,9 @@ button in the scope of the clicked container (see <<command_criteria>>). You
|
|||||||
can configure mouse bindings in a similar way to key bindings.
|
can configure mouse bindings in a similar way to key bindings.
|
||||||
|
|
||||||
*Syntax*:
|
*Syntax*:
|
||||||
-------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
bindsym [--release] [--border] [--whole-window] [<Modifiers>+]button<n> command
|
bindsym [--release] [--border] [--whole-window] [--exclude-titlebar] [<Modifiers>+]button<n> command
|
||||||
-------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
By default, the binding will only run when you click on the titlebar of the
|
By default, the binding will only run when you click on the titlebar of the
|
||||||
window. If the +--release+ flag is given, it will run when the mouse button
|
window. If the +--release+ flag is given, it will run when the mouse button
|
||||||
@ -424,6 +424,9 @@ If the +--whole-window+ flag is given, the binding will also run when any part
|
|||||||
of the window is clicked, with the exception of the border. To have a bind run
|
of the window is clicked, with the exception of the border. To have a bind run
|
||||||
when the border is clicked, specify the +--border+ flag.
|
when the border is clicked, specify the +--border+ flag.
|
||||||
|
|
||||||
|
If the +--exclude-titlebar+ flag is given, the titlebar will not be considered
|
||||||
|
for the keybinding.
|
||||||
|
|
||||||
*Examples*:
|
*Examples*:
|
||||||
--------------------------------
|
--------------------------------
|
||||||
# The middle button over a titlebar kills the window
|
# The middle button over a titlebar kills the window
|
||||||
|
@ -27,7 +27,8 @@ extern const char *DEFAULT_BINDING_MODE;
|
|||||||
*/
|
*/
|
||||||
Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
|
Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
|
||||||
const char *release, const char *border, const char *whole_window,
|
const char *release, const char *border, const char *whole_window,
|
||||||
const char *command, const char *mode, bool pango_markup);
|
const char *exclude_titlebar, const char *command, const char *mode,
|
||||||
|
bool pango_markup);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Grab the bound keys (tell X to send us keypress events for those keycodes)
|
* Grab the bound keys (tell X to send us keypress events for those keycodes)
|
||||||
|
@ -67,10 +67,10 @@ CFGFUN(color_single, const char *colorclass, const char *color);
|
|||||||
CFGFUN(floating_modifier, const char *modifiers);
|
CFGFUN(floating_modifier, const char *modifiers);
|
||||||
CFGFUN(new_window, const char *windowtype, const char *border, const long width);
|
CFGFUN(new_window, const char *windowtype, const char *border, const long width);
|
||||||
CFGFUN(workspace, const char *workspace, const char *output);
|
CFGFUN(workspace, const char *workspace, const char *output);
|
||||||
CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *command);
|
CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *exclude_titlebar, const char *command);
|
||||||
|
|
||||||
CFGFUN(enter_mode, const char *pango_markup, const char *mode);
|
CFGFUN(enter_mode, const char *pango_markup, const char *mode);
|
||||||
CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *command);
|
CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *exclude_titlebar, const char *command);
|
||||||
|
|
||||||
CFGFUN(bar_font, const char *font);
|
CFGFUN(bar_font, const char *font);
|
||||||
CFGFUN(bar_separator_symbol, const char *separator);
|
CFGFUN(bar_separator_symbol, const char *separator);
|
||||||
|
@ -298,6 +298,10 @@ struct Binding {
|
|||||||
* title bar (default). */
|
* title bar (default). */
|
||||||
bool whole_window;
|
bool whole_window;
|
||||||
|
|
||||||
|
/** If this is true for a mouse binding, the binding should only be
|
||||||
|
* executed if the button press was not on the titlebar. */
|
||||||
|
bool exclude_titlebar;
|
||||||
|
|
||||||
/** Keycode to bind */
|
/** Keycode to bind */
|
||||||
uint32_t keycode;
|
uint32_t keycode;
|
||||||
|
|
||||||
|
@ -321,6 +321,8 @@ state BINDING:
|
|||||||
->
|
->
|
||||||
whole_window = '--whole-window'
|
whole_window = '--whole-window'
|
||||||
->
|
->
|
||||||
|
exclude_titlebar = '--exclude-titlebar'
|
||||||
|
->
|
||||||
modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', 'Group1', 'Group2', 'Group3', 'Group4', '$mod'
|
modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', 'Group1', 'Group2', 'Group3', 'Group4', '$mod'
|
||||||
->
|
->
|
||||||
'+'
|
'+'
|
||||||
@ -335,8 +337,10 @@ state BINDCOMMAND:
|
|||||||
->
|
->
|
||||||
whole_window = '--whole-window'
|
whole_window = '--whole-window'
|
||||||
->
|
->
|
||||||
|
exclude_titlebar = '--exclude-titlebar'
|
||||||
|
->
|
||||||
command = string
|
command = string
|
||||||
-> call cfg_binding($bindtype, $modifiers, $key, $release, $border, $whole_window, $command)
|
-> call cfg_binding($bindtype, $modifiers, $key, $release, $border, $whole_window, $exclude_titlebar, $command)
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Mode configuration
|
# Mode configuration
|
||||||
@ -376,6 +380,8 @@ state MODE_BINDING:
|
|||||||
->
|
->
|
||||||
whole_window = '--whole-window'
|
whole_window = '--whole-window'
|
||||||
->
|
->
|
||||||
|
exclude_titlebar = '--exclude-titlebar'
|
||||||
|
->
|
||||||
modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', 'Group1', 'Group2', 'Group3', 'Group4', '$mod'
|
modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', 'Group1', 'Group2', 'Group3', 'Group4', '$mod'
|
||||||
->
|
->
|
||||||
'+'
|
'+'
|
||||||
@ -390,8 +396,10 @@ state MODE_BINDCOMMAND:
|
|||||||
->
|
->
|
||||||
whole_window = '--whole-window'
|
whole_window = '--whole-window'
|
||||||
->
|
->
|
||||||
|
exclude_titlebar = '--exclude-titlebar'
|
||||||
|
->
|
||||||
command = string
|
command = string
|
||||||
-> call cfg_mode_binding($bindtype, $modifiers, $key, $release, $border, $whole_window, $command); MODE
|
-> call cfg_mode_binding($bindtype, $modifiers, $key, $release, $border, $whole_window, $exclude_titlebar, $command); MODE
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# Bar configuration (i3bar)
|
# Bar configuration (i3bar)
|
||||||
|
@ -56,12 +56,14 @@ static struct Mode *mode_from_name(const char *name, bool pango_markup) {
|
|||||||
*/
|
*/
|
||||||
Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
|
Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
|
||||||
const char *release, const char *border, const char *whole_window,
|
const char *release, const char *border, const char *whole_window,
|
||||||
const char *command, const char *modename, bool pango_markup) {
|
const char *exclude_titlebar, const char *command, const char *modename,
|
||||||
|
bool pango_markup) {
|
||||||
Binding *new_binding = scalloc(1, sizeof(Binding));
|
Binding *new_binding = scalloc(1, sizeof(Binding));
|
||||||
DLOG("Binding %p bindtype %s, modifiers %s, input code %s, release %s\n", new_binding, bindtype, modifiers, input_code, release);
|
DLOG("Binding %p bindtype %s, modifiers %s, input code %s, release %s\n", new_binding, bindtype, modifiers, input_code, release);
|
||||||
new_binding->release = (release != NULL ? B_UPON_KEYRELEASE : B_UPON_KEYPRESS);
|
new_binding->release = (release != NULL ? B_UPON_KEYRELEASE : B_UPON_KEYPRESS);
|
||||||
new_binding->border = (border != NULL);
|
new_binding->border = (border != NULL);
|
||||||
new_binding->whole_window = (whole_window != NULL);
|
new_binding->whole_window = (whole_window != NULL);
|
||||||
|
new_binding->exclude_titlebar = (exclude_titlebar != NULL);
|
||||||
if (strcmp(bindtype, "bindsym") == 0) {
|
if (strcmp(bindtype, "bindsym") == 0) {
|
||||||
new_binding->input_type = (strncasecmp(input_code, "button", (sizeof("button") - 1)) == 0
|
new_binding->input_type = (strncasecmp(input_code, "button", (sizeof("button") - 1)) == 0
|
||||||
? B_MOUSE
|
? B_MOUSE
|
||||||
|
@ -186,7 +186,7 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
|
|||||||
if (dest == CLICK_DECORATION || dest == CLICK_INSIDE || dest == CLICK_BORDER) {
|
if (dest == CLICK_DECORATION || dest == CLICK_INSIDE || dest == CLICK_BORDER) {
|
||||||
Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event);
|
Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event);
|
||||||
|
|
||||||
if (bind != NULL && (dest == CLICK_DECORATION ||
|
if (bind != NULL && ((dest == CLICK_DECORATION && !bind->exclude_titlebar) ||
|
||||||
(dest == CLICK_INSIDE && bind->whole_window) ||
|
(dest == CLICK_INSIDE && bind->whole_window) ||
|
||||||
(dest == CLICK_BORDER && bind->border))) {
|
(dest == CLICK_BORDER && bind->border))) {
|
||||||
CommandResult *result = run_binding(bind, con);
|
CommandResult *result = run_binding(bind, con);
|
||||||
|
@ -106,8 +106,8 @@ CFGFUN(font, const char *font) {
|
|||||||
font_pattern = sstrdup(font);
|
font_pattern = sstrdup(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *command) {
|
CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *exclude_titlebar, const char *command) {
|
||||||
configure_binding(bindtype, modifiers, key, release, border, whole_window, command, DEFAULT_BINDING_MODE, false);
|
configure_binding(bindtype, modifiers, key, release, border, whole_window, exclude_titlebar, command, DEFAULT_BINDING_MODE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -117,8 +117,8 @@ CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, co
|
|||||||
static char *current_mode;
|
static char *current_mode;
|
||||||
static bool current_mode_pango_markup;
|
static bool current_mode_pango_markup;
|
||||||
|
|
||||||
CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *command) {
|
CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *exclude_titlebar, const char *command) {
|
||||||
configure_binding(bindtype, modifiers, key, release, border, whole_window, command, current_mode, current_mode_pango_markup);
|
configure_binding(bindtype, modifiers, key, release, border, whole_window, exclude_titlebar, command, current_mode, current_mode_pango_markup);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGFUN(enter_mode, const char *pango_markup, const char *modename) {
|
CFGFUN(enter_mode, const char *pango_markup, const char *modename) {
|
||||||
|
@ -49,18 +49,22 @@ mode "meh" {
|
|||||||
bindsym --release --whole-window button3 nop
|
bindsym --release --whole-window button3 nop
|
||||||
bindsym --border button3 nop
|
bindsym --border button3 nop
|
||||||
bindsym --release --border button3 nop
|
bindsym --release --border button3 nop
|
||||||
|
bindsym --exclude-titlebar button3 nop
|
||||||
|
bindsym --whole-window --border --exclude-titlebar button3 nop
|
||||||
}
|
}
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
my $expected = <<'EOT';
|
my $expected = <<'EOT';
|
||||||
cfg_enter_mode((null), meh)
|
cfg_enter_mode((null), meh)
|
||||||
cfg_mode_binding(bindsym, Mod1,Shift, x, (null), (null), (null), resize grow)
|
cfg_mode_binding(bindsym, Mod1,Shift, x, (null), (null), (null), (null), resize grow)
|
||||||
cfg_mode_binding(bindcode, Mod1, 44, (null), (null), (null), resize shrink)
|
cfg_mode_binding(bindcode, Mod1, 44, (null), (null), (null), (null), resize shrink)
|
||||||
cfg_mode_binding(bindsym, Mod1, x, --release, (null), (null), exec foo)
|
cfg_mode_binding(bindsym, Mod1, x, --release, (null), (null), (null), exec foo)
|
||||||
cfg_mode_binding(bindsym, (null), button3, (null), (null), --whole-window, nop)
|
cfg_mode_binding(bindsym, (null), button3, (null), (null), --whole-window, (null), nop)
|
||||||
cfg_mode_binding(bindsym, (null), button3, --release, (null), --whole-window, nop)
|
cfg_mode_binding(bindsym, (null), button3, --release, (null), --whole-window, (null), nop)
|
||||||
cfg_mode_binding(bindsym, (null), button3, (null), --border, (null), nop)
|
cfg_mode_binding(bindsym, (null), button3, (null), --border, (null), (null), nop)
|
||||||
cfg_mode_binding(bindsym, (null), button3, --release, --border, (null), nop)
|
cfg_mode_binding(bindsym, (null), button3, --release, --border, (null), (null), nop)
|
||||||
|
cfg_mode_binding(bindsym, (null), button3, (null), (null), (null), --exclude-titlebar, nop)
|
||||||
|
cfg_mode_binding(bindsym, (null), button3, (null), --border, --whole-window, --exclude-titlebar, nop)
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
is(parser_calls($config),
|
is(parser_calls($config),
|
||||||
@ -674,7 +678,7 @@ EOT
|
|||||||
|
|
||||||
$expected = <<'EOT';
|
$expected = <<'EOT';
|
||||||
cfg_enter_mode((null), yo)
|
cfg_enter_mode((null), yo)
|
||||||
cfg_mode_binding(bindsym, (null), x, (null), (null), (null), resize shrink left)
|
cfg_mode_binding(bindsym, (null), x, (null), (null), (null), (null), resize shrink left)
|
||||||
ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'bindsym', 'bindcode', 'bind', '}'
|
ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'bindsym', 'bindcode', 'bind', '}'
|
||||||
ERROR: CONFIG: (in file <stdin>)
|
ERROR: CONFIG: (in file <stdin>)
|
||||||
ERROR: CONFIG: Line 1: mode "yo" {
|
ERROR: CONFIG: Line 1: mode "yo" {
|
||||||
|
Loading…
Reference in New Issue
Block a user