Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different kinds of clicking #558

Closed
i3bot opened this issue Nov 11, 2011 · 28 comments
Closed

Different kinds of clicking #558

i3bot opened this issue Nov 11, 2011 · 28 comments
Assignees

Comments

@i3bot
Copy link

i3bot commented Nov 11, 2011

[Originally reported by julien]
(Hello Michael,

As discussed on bug #534, different kinds of clicking can be usefull for the user to get different results (focus, resizing tool, etc.).

As we said, they are many possible ideas, like for example :

1°) click (1 sec) on a tab makes the tab to be focused ; click (more than 1sec) on a tab calls the resizing tool ;

2°) click on a tab makes the tab to be focused ; click+Mod1 on a tab calls the resizing tool.

Thanks a lot for i3 !

Best regards,

Julien

@stapelberg
Copy link
Member

This behaviour should be configurable. Another use case (from #570):

It would be great if you could configure the bindings for the mouse (such as $mod+button1 to drag and $mod+button2 to resize floating windows) in a similar way as the bindings for the keyboard.
I know it's probably too complex for the simplicity intended for i3, but I didn't know if asking here for a specific binding would be reasonable (what I actually would need is that $mod+button4/5 over a window switched to the previous/next window in stacked mode, just like button4/5 do over the window decoration, but with $mod and over all the window, not only its title).
So if you prefer to keep out configurable mouse bindings and prefer to hardcode specific bindings (if they fit well), feel free to close this bug report ;)

@stapelberg
Copy link
Member

I agree that we want to have this, but it’s not important, so unsetting version.

@i3bot
Copy link
Author

i3bot commented Oct 22, 2012

[Original comment by p.staszewski@…]

I would like to say that I would very much like this feature too!

My original idea can be best described by sample config entries:
bindmouse button1 focus
bindmouse button2 kill
bindmouse button3 move scratchpad
bindmouse shift+button1 move container to workspace 10
etc.

The bindings defined above should work only for clicks on title bars.

Thank you for your work on i3!

@i3bot
Copy link
Author

i3bot commented Jun 11, 2013

[Original comment by anonymous]

For those with multiple mouse buttons, this would be useful for switching workspaces quickly, for example.

bindmouse button6 workspace next

@i3bot
Copy link
Author

i3bot commented Sep 12, 2013

[Original comment by cyd@…]

A workaround:
$ cat ~/.bindkeysrc

Bind Mousebutton 9

"i3-msg -t command "workspace next""
b:9
$ xbindkeys -f ~/.xbindkeysrc

@stapelberg
Copy link
Member

See also #1104 for what this feature request should cover.

@i3bot
Copy link
Author

i3bot commented Oct 15, 2013

[Original comment by josh]

Replying to comment 6 @…:

See also #1104 for what this feature request should cover.

@….

#1104 is a clean feature request. Maybe (since #1104 has been merged) we can implement #558 in stages.

tldr; myself and others wold really like to see the features requested in #1104 implemented soon.

@stapelberg
Copy link
Member

Replying to comment 7 by josh:

Replying to comment 6 @…:

See also #1104 for what this feature request should cover.

@….

#1104 is a clean feature request. Maybe (since #1104 has been merged) we can implement #558 in stages.

tldr; myself and others wold really like to see the features requested in #1104 implemented soon.
I neither do “we need it soon” nor “so many people want it”. Either we do it cleanly or not at all :).

@i3bot
Copy link
Author

i3bot commented Oct 20, 2013

[Original comment by tony@…]

I can start looking at this, but I'm not sure I have a clear idea how this can be implemented in a way that also implements the features in #1104.

Can someone summarize the consensus on what exactly implementing this would require and provide example config directives that would implement each part of #1104?

@i3bot
Copy link
Author

i3bot commented Nov 11, 2013

[Original comment by anonymous]

Replying to comment 8 @…:

Replying to comment 7 by josh:

Replying to comment 6 @…:

See also #1104 for what this feature request should cover.

@….

#1104 is a clean feature request. Maybe (since #1104 has been merged) we can implement #558 in stages.

tldr; myself and others wold really like to see the features requested in #1104 implemented soon.
I neither do “we need it soon” nor “so many people want it”. Either we do it cleanly or not at all :).
I believe the reason that "we need it soon" and "so many people want it" have been mentioned is specifically because #1104 has been merged with #558, which has been open for two years and marked as "trivial". No one is saying not to do it cleanly, we're simply saying that for some of us the issues in #1104 aren't "trivial" and we're concerned on how that issue is being addressed, or not addressed as the case may be.

@i3bot
Copy link
Author

i3bot commented Nov 11, 2013

[Original comment by TonyC]

Replying to comment 10 by anonymous:

This is beginning to go through now.

There is a lot of activity going on with i3bar that is higher priority than this, so I'm going to put off the proper solution for a bit. If you really want something now though, apply this patch which allows you to do something like:

bar {
    i3bar_command /path/to/i3bar --noninteractive
}

and that will disable all clicking on the bar (except tray icons I think).

As for the other feature which was requested in #1104, disabling the scrolling and clicking on tabbed window decorations, I'm doubting right now whether we can do that cleanly because of how specific it is.

On the one hand, disabling mouse interaction with i3 completely is not a feature I think people want because drag resize/move and click to focus are kind of essential. On the other hand, I don't think a config directive like disable-scrolling-and-clicking-on-tabbed-window-decorations yes is going to be in accordance with Michael's idea of doing it "clean".

So if you can think of a rule somewhere in between along with a way to explain it to people in the docs that we can agree on, I will implement it.

@i3bot
Copy link
Author

i3bot commented Jan 4, 2014

[Original comment by TonyC]

I'll summarize the current state of this feature as I see it now.

Replying to comment 3 by p.staszewski@…:

I think this is the best implementation that has been suggested so far. The command will look like this:

bindmouse [ModN[+...]]ButtonM <command>

With the following behavior:

  1. The command will only take effect if a window title bar is clicked.
  2. A command that takes effect will be in the context of the window whose title bar was clicked (i.e., that window is assumed to be focused)
  3. A bindmouse directive will override the default behavior of the click.

This should allow the user to no-op any default mouse behavior they do not like (implementing #1104).

It also allows for the user to easily configure the most obvious use for this feature, that is, right/middle click/scroll wheel on the title bars, without interfering with an application's own handling of click events.

A problem I can see with this is that there would be no way to reproduce the default "scroll" mouse wheel feature (perhaps in the opposite direction). Maybe a --no-focus flag should be taken to mean that the command should not focus the window.

How does that sound?

@i3bot
Copy link
Author

i3bot commented Jan 5, 2014

[Original comment by p.staszewski@…]

Replying to comment 12 by TonyC:

  1. The command will only take effect if a window title bar is clicked.
  2. A command that takes effect will be in the context of the window whose title bar was clicked (i.e., that window is assumed to be focused)
  3. A bindmouse directive will override the default behaviour of the click.

Points 1. and 2. - exactly.
Point 3. - why have a hard-coded behaviour? I would leave it as an entirely config file choice. If you don't setup bindmouse the title bars will simply not react to any mouse clicks.

A problem I can see with this is that there would be no way to reproduce the default "scroll" mouse wheel feature (perhaps in the opposite direction). Maybe a --no-focus flag should be taken to mean that the command should not focus the window.

Honestly I did not consider scroll wheel at that time...

I would introduce it as a command though:

focus cycle <left|right>

So that to get the currently default behaviour:

bindmouse Button4 focus cycle left
bindnouse Button5 focus cycle right

I haven't looked at the implementation, but form the user's point-of-view the current mouse scrolling of windows behaves differently from focus <left|right> (i.e. mouse wheel cycles windows only within current container - it won't switch containers).

As for the --no-focus flag - I don't see where I would want to use it.

How does that sound?
Great! :)

Thanks to all for discussion and interest in this feature.

@stapelberg
Copy link
Member

Replying to comment 13 by p.staszewski@…:

Replying to comment 12 by TonyC:

  1. The command will only take effect if a window title bar is clicked.
    I’m not entirely sure if this is a good idea. Using e.g. bindmouse Mod4+Button1 exec my_popup_menu may be a useful thing to have. But then again, we can probably add a flag later, e.g. bindmouse Mod4+Button1 --entire-window exec my_popup_menu
  2. A command that takes effect will be in the context of the window whose title bar was clicked (i.e., that window is assumed to be focused)
    I don’t think you explicitly need to write this, given that clicking first focuses the window anyway due to focus-on-click. Also note that scrolling internally is a click
  3. A bindmouse directive will override the default behaviour of the click.

Points 1. and 2. - exactly.
Point 3. - why have a hard-coded behaviour? I would leave it as an entirely config file choice. If you don't setup bindmouse the title bars will simply not react to any mouse clicks.
Because of backwards compatibility, which is really important for us. We cannot just release a new version where clicking doesn’t work until the user modifies her config file.

A problem I can see with this is that there would be no way to reproduce the default "scroll" mouse wheel feature (perhaps in the opposite direction). Maybe a --no-focus flag should be taken to mean that the command should not focus the window.
Why not, precisely?

@i3bot
Copy link
Author

i3bot commented Jan 5, 2014

[Original comment by p.staszewski@…]

(I'll try to avoid superfluous nesting.)

Replying to comment 14 @…:

I’m not entirely sure if this is a good idea. Using e.g. bindmouse Mod4+Button1 exec my_popup_menu may be a useful thing to have. But then again, we can probably add a flag later, e.g. bindmouse Mod4+Button1 --entire-window exec my_popup_menu

A flag, later on - I'm all for it; but later on.

Disregarding the fact that most apps already have mouse bindings inside their 'space', my idea here was to 'compensate' for the lack of the close/max|min buttons commonly found on most title bars - with the 'twist' that there are no icons, just mouse button bindings, and that they are fully-configurable.

I have probably expressed that on the IRC channel already, but: I personally have two distinct modes of WM interaction: keyboard driven, and mouse driven. While the keyboard gives me (extreme) flexibility the mouse gives me simplicity and one-hand operation.

As of now I can focus any window with the mouse. My main real problem is that I can't close every window with the mouse (only those that have, obviously, a button or a menu option for that).

Given the above I would be satisfied with the simple default binding that right-click on a title bar means kill that window. Given the fact that I do like the flexibility I was looking for a more configurable approach.

I don’t think you explicitly need to write this, given that clicking first focuses the window anyway due to focus-on-click. Also note that scrolling internally is a click

I agree focus (and click context) should be obvious - but then the scroll wheel cycling (as it works now) may make it a little blurry, so I confirmed the approach.

And yes, I do realize that scroll wheel is just a click. Funny thing though is that I didn't think about it that way intuitively when I was first posting my request. I guess the physical acts of clicking and scrolling with a wheel are distinct enough to enforce a mental notion that these are handled differently.

Because of backwards compatibility, which is really important for us. We cannot just release a new version where clicking doesn’t work until the user modifies her config file.

I agree.

I assume the above then necessitates something like a noop command (or off, or disable; I'll leave the language of that to you), in order to override the default mouse key bindings - but that should be trivial.

Why not, precisely?

I believe the answer to that is two-fold.

First - mouse wheel scrolling right now works whenever the mouse pointer is on any title bar - it just cycles from whatever the currently focused window is, in direction appropriate to the scroll direction.

Given the premise 'command is executed for the window the title bar we click' this may seem to break the logic a bit - for mouse wheel cycle we should cycle left|right relative to the currently focused window, i.e. not do 'first focus the window for which the mouse pointer is over the title bar' (hope this makes sense).

The second part is that cycling as it works now is distinct from the focus <left|right>, as it does not cross containers. Hence the suggestion to have a separate command for this exact behaviour.

I hope I've managed to clarify.

@i3bot
Copy link
Author

i3bot commented Jan 6, 2014

[Original comment by TonyC]

I didn't mean to imply that the container would automatically be focused by the activation of a bindmouse command. Let me amend my specification of behavior 2:

  1. A command that takes effect will be in the context of the container whose title bar was clicked (i.e., that container is assumed to be uniquely selected by criteria).

Of course, when I say "a title bar was clicked" I mean a ButtonPress event was detected with pointer coordinates within the bounds of a title bar.

If we were to automatically focus a container, we could not meet the requirements of #1104, because it would not be possible to truly no-op the mouse wheel (or any other button) over title bars.

To illustrate how this works, consider the directive:

bindmouse Button1 floating enable

and suppose the binding is activated with $clicked_con_id holding the con_id of the clicked container. Then the following command would be sent to i3:

[con_id="$clicked_con_id"] floating enable

If some command requires the container to be focused to act on the container (e.g., move <direction>, which ignores the criteria and acts upon the focused container instead), the user may explicitly focus the container first:

bindmouse Button1 focus; move left

which will work as expected. However, these commands should implement criteria matching eventually.

To get the scroll wheel functionality we would need two additional commands which act on the focused container within the parent of the leaf container selected by the criteria:

  1. focus cycle_next - the behavior of wheel down
  2. focus cycle_previous - the behavior of wheel up

Here is a complete example:

# notable default mouse actions
bindmouse Button1 focus
bindmouse Button4 focus cycle_previous
bindmouse Button5 focus cycle_next

# disable scroll wheel on interface
bindmouse Button4 nop
bindmouse Button5 nop

# right click kills window
bindmouse Button3 kill

# middle click sends to scratchpad
bindmouse Button2 move scratchpad

# mod and left click toggle floating
bindmouse $mod+Button1 focus; floating toggle

# mod and middle click moves across outputs
bindmouse $mod+Button2 move container to output right

# mod and scroll wheels move around
bindmouse $mod+Button4 focus; move left
bindmouse $mod+Button5 focus; move right

@stapelberg
Copy link
Member

Replying to comment 16 by TonyC:

I didn't mean to imply that the container would automatically be focused by the activation of a bindmouse command. Let me amend my specification of behavior 2:

  1. A command that takes effect will be in the context of the container whose title bar was clicked (i.e., that container is assumed to be uniquely selected by criteria).

Of course, when I say "a title bar was clicked" I mean a ButtonPress event was detected with pointer coordinates within the bounds of a title bar.

If we were to automatically focus a container, we could not meet the requirements of #1104, because it would not be possible to truly no-op the mouse wheel (or any other button) over title bars.

To illustrate how this works, consider the directive:

bindmouse Button1 floating enable

and suppose the binding is activated with $clicked_con_id holding the con_id of the clicked container. Then the following command would be sent to i3:

[con_id="$clicked_con_id"] floating enable

This makes sense to me.

If some command requires the container to be focused to act on the container (e.g., move <direction>, which ignores the criteria and acts upon the focused container instead), the user may explicitly focus the container first:

bindmouse Button1 focus; move left

which will work as expected. However, these commands should implement criteria matching eventually.
I think you meant ”focus, move left”, right? See the second paragraph of http://i3wm.org/docs/userguide.html#command_criteria

To get the scroll wheel functionality we would need two additional commands which act on the focused container within the parent of the leaf container selected by the criteria:

  1. focus cycle_next - the behavior of wheel down
  2. focus cycle_previous - the behavior of wheel up
    Why not name them “focus wheel_up” and “focus wheel_down”? That makes it more clear what their intention is, I think. Also, if we find a case where the behavior doesn’t make sense (intuitively, given how the scroll wheel works), it is easier to change that command than a more generic “cycle” command.

Here is a complete example:

# notable default mouse actions
bindmouse Button1 focus
bindmouse Button4 focus cycle_previous
bindmouse Button5 focus cycle_next

# disable scroll wheel on interface
bindmouse Button4 nop
bindmouse Button5 nop

# right click kills window
bindmouse Button3 kill

# middle click sends to scratchpad
bindmouse Button2 move scratchpad

# mod and left click toggle floating
bindmouse $mod+Button1 focus; floating toggle

# mod and middle click moves across outputs
bindmouse $mod+Button2 move container to output right

# mod and scroll wheels move around
bindmouse $mod+Button4 focus; move left
bindmouse $mod+Button5 focus; move right

Looks good, apart from the comma versus semicolon thing I noted above.

Also, it would be good if you could add a bindmouse for i3bar in this example — I assume we want to have a very similar concept for i3bar, right?

@i3bot
Copy link
Author

i3bot commented Jan 7, 2014

[Original comment by TonyC]

Replying to comment 17 @…:

Why not name them “focus wheel_up” and “focus wheel_down”? That makes it more clear what their intention is, I think. Also, if we find a case where the behavior doesn’t make sense (intuitively, given how the scroll wheel works), it is easier to change that command than a more generic “cycle” command.

The name could use some work. It's difficult to think of something simple to describe this that doesn't use specialist vocabulary.

Using wheel_up and wheel_down seems opinionated to me and could be confusing. For instance, suppose I bind the button "wheel up" to the command wheel_down. Now what happens when I press the button "wheel up" on tabs? How long did it take you to figure it out?

cycle_next and cycle_previous has the exact same problem because it's not clear which is the first and which is the last container. In a stack, the lowest index is at the top. If you think about it, this is the opposite of how things are ordinarily ordered (such as the standard representation of a Cartesian cross).

Also, it would be good if you could add a bindmouse for i3bar in this example — I assume we want to have a very similar concept for i3bar, right?

Yes, i3bar should have a similar feature. Since it is not a managed window, it will have to be implemented separately. The details of this implementation is still an open issue.

@i3bot
Copy link
Author

i3bot commented Jan 12, 2014

[Original comment by Tony Crisci]

This ticket was fixed in commit http://c.i3wm.org/54012719:

Add `input_type` enum to `Binding` typedef

An input type of B_KEYBOARD will indicated this binding was created with
"bindsym", "bindcode", or "bind" and should only run on key press
events.

An input type of B_MOUSE will indicate this binding was created with
"bindmouse" and should only run on button press events (not yet
implemented).

For more information see #558.

@i3bot
Copy link
Author

i3bot commented Jan 15, 2014

[Original comment by TonyC]

For the i3bar implementation, we could either do this within i3bar or i3 itself. Here are the advantages/disadvantages to each.

If we implemented it in i3 itself, a --dock flag would be added to the bindmouse directive to indicate the mouse binding should execute when the pointer is over (any) dock window.

  • Easier implementation
  • Portable across bars/docks a user may choose
  • Supports modes

However, this may break compatibility unless there is some way to eat the event before i3bar can get it whenever a binding runs.

To implement this is i3bar, the bindmouse would be declared within a bar block and become part of the bar config.

  • Complex implementation (the bar must store bindings and use the ipc to execute commands)
  • Fits user expectations (I think people will naturally assume they can do this)
  • Bars are configured separately (some people may not want commands to execute over any dock client)

@stapelberg
Copy link
Member

Replying to comment 20 by TonyC:

For the i3bar implementation, we could either do this within i3bar or i3 itself. Here are the advantages/disadvantages to each.

If we implemented it in i3 itself, a --dock flag would be added to the bindmouse directive to indicate the mouse binding should execute when the pointer is over (any) dock window.
I don’t think this is a good idea.

  • Portable across bars/docks a user may choose
    I think it’s a feature that different bars are different in terms of what a click/other mouse buttons does, even though your other pros are true.

To implement this is i3bar, the bindmouse would be declared within a bar block and become part of the bar config.

  • Complex implementation (the bar must store bindings and use the ipc to execute commands)
    The bar already uses plenty of IPC, that’s not a concern. It also already reads the config from i3.
  • Fits user expectations (I think people will naturally assume they can do this)
  • Bars are configured separately (some people may not want commands to execute over any dock client)
    Good point, yeah.

@i3bot
Copy link
Author

i3bot commented Apr 5, 2014

[Original comment by jandry]

I think a great deal of complication could be avoided if i3 could simply bind a command to various mousebinds; this would easily allow users to use xdotool to set mouse actions to already existing keybinds:

bindmouse $mod+Button2 command; xdotool key Alt+Shift+q
-or-
bindmouse $mod+Button2 command; sh /home/user/some/xdotool/script.sh

In this way, you wouldnt even have to have a container or titlebar for an app. It could be "context" driven (similar to how Openbox has "desktop" and "frame" context options). That said, I think having configurable mouseactions for titlebar clicks is a unique and very good idea for those that use them.

As for the bar I have no idea...

@i3bot
Copy link
Author

i3bot commented Apr 6, 2014

[Original comment by TonyC]

Replying to comment 22 by jandry:

I think that is an excellent idea feature-wise. I'm working on a more general way to intercept commands for custom scripting in #1210 which I think would pair very well with the new mouse binding feature and let you accomplish what you are after in a cleaner way.

As for the status of this feature itself, most of the refactoring required for implementing the feature is complete and I plan to put most of my i3-development effort into this next week.

@i3bot
Copy link
Author

i3bot commented Jun 17, 2014

[Original comment by TonyC]

Bindmouse is done. It will be merged soon. Here is how it turned out:

=== Mouse bindings

A mouse binding makes i3 execute a command upon pressing a specific mouse
button in the scope of the clicked container (see <<command_criteria>>). You
can configure mouse bindings in a similar way to key bindings.

*Syntax*:
----------------------------------
bindsym [Modifiers+]button[n] command
----------------------------------

If the binding has no modifiers, it will only run when you click on the
titlebar of the window. Otherwise, it will run when any part of the window is
clicked.

*Examples*:
--------------------------------
# The middle button over a titlebar kills the window
bindsym button2 kill

# The middle button and a modifer over any part of the window kills the window
bindsym $mod+button2 kill

# The right button toggles floating
bindsym button3 floating toggle
bindsym $mod+button3 floating toggle

# The side buttons move the window around
bindsym button9 move left
bindsym button8 move right
--------------------------------

I'm not going to do mouse bindings over i3bar because it's too complicated.

@i3bot
Copy link
Author

i3bot commented Jun 19, 2014

[Original comment by Tony Crisci]

This ticket was fixed in commit http://c.i3wm.org/0df172fd:

Feature: implement mouse bindings

A configured mouse binding (for example `bindsym button3 kill`) runs
its command when the mouse button is pressed over parts of a container.

If the binding has no modifer, it will only run when the button is
clicked on the window titlebar.

Otherwise if the binding has a modifier, it will run over the titlebar
or any part of the contained window.

fixes #558

stapelberg pushed a commit that referenced this issue Feb 4, 2015
A configured mouse binding (for example `bindsym button3 kill`) runs
its command when the mouse button is pressed over parts of a container.

If the binding has no modifer, it will only run when the button is
clicked on the window titlebar.

Otherwise if the binding has a modifier, it will run over the titlebar
or any part of the contained window.

fixes #558
@Radivarig
Copy link

Bah. Wanted to catch button event without modifier as well

@Airblader
Copy link
Member

@Radivarig You can. The comments in here aren't up to date.

@rodfersou
Copy link

rodfersou commented Dec 31, 2018

I'm trying to bind the scroll buttons with --whole-window flag and it is ignoring the $mod modifier.. works without the modifier press.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants