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

Middle mouse click to close the tab #4151

Closed
page-down opened this issue Oct 23, 2021 · 13 comments
Closed

Middle mouse click to close the tab #4151

page-down opened this issue Oct 23, 2021 · 13 comments

Comments

@page-down
Copy link
Contributor

Is your feature request related to a problem? Please describe.
Currently, you can easily double-click to create a new Tab and click to switch Tabs, but you cannot close Tabs with the mouse.

Describe the solution you'd like
Close the tab by clicking the middle mouse button.

Describe alternatives you've considered
n/a

Additional context
Here is my attempt to implement it. However I don't know any better way to disable the middle click event on the tab bar, which by default will paste the clipboard text.

diff --git a/kitty/boss.py b/kitty/boss.py
index 6e56288e..f8398fa8 100755
--- a/kitty/boss.py
+++ b/kitty/boss.py
@@ -591,10 +591,10 @@ def start(self, first_os_window_id: int) -> None:
             run_update_check(get_options().update_check_interval * 60 * 60)
             self.update_check_started = True
 
-    def activate_tab_at(self, os_window_id: int, x: int, is_double: bool = False) -> int:
+    def activate_tab_at(self, os_window_id: int, x: int, is_double: bool = False, is_middle: bool = False) -> int:
         tm = self.os_window_map.get(os_window_id)
         if tm is not None:
-            tm.activate_tab_at(x, is_double)
+            tm.activate_tab_at(x, is_double, is_middle)
 
     def on_window_resize(self, os_window_id: int, w: int, h: int, dpi_changed: bool) -> None:
         if dpi_changed:
diff --git a/kitty/mouse.c b/kitty/mouse.c
index b8ea84e4..426ae12f 100644
--- a/kitty/mouse.c
+++ b/kitty/mouse.c
@@ -517,11 +517,22 @@ HANDLER(handle_event) {
 static void
 handle_tab_bar_mouse(int button, int UNUSED modifiers) {
     static monotonic_t last_click_at = 0;
-    if (button != GLFW_MOUSE_BUTTON_LEFT || !global_state.callback_os_window->mouse_button_pressed[button]) return;
+    bool is_middle = false;
+    switch (button) {
+        case GLFW_MOUSE_BUTTON_MIDDLE:
+            is_middle = true;
+        case GLFW_MOUSE_BUTTON_LEFT:
+            if (!global_state.callback_os_window->mouse_button_pressed[button]) return;
+            break;
+        default:
+            return;
+    }
     monotonic_t now = monotonic();
     bool is_double = now - last_click_at <= OPT(click_interval);
     last_click_at = is_double ? 0 : now;
-    call_boss(activate_tab_at, "KdO", global_state.callback_os_window->id, global_state.callback_os_window->mouse_x, is_double ? Py_True : Py_False);
+    call_boss(activate_tab_at, "KdOO", global_state.callback_os_window->id, global_state.callback_os_window->mouse_x, is_double ? Py_True : Py_False, is_middle ? Py_True : Py_False);
+    // hack: disable middle click event on tab bar
+    if (is_middle) global_state.callback_os_window->mouse_button_pressed[button] = false;
 }
 
 static bool
diff --git a/kitty/tabs.py b/kitty/tabs.py
index cbef1aed..2551e4f1 100644
--- a/kitty/tabs.py
+++ b/kitty/tabs.py
@@ -965,13 +965,17 @@ def tab_bar_data(self) -> List[TabBarData]:
             ))
         return ans
 
-    def activate_tab_at(self, x: int, is_double: bool = False) -> None:
+    def activate_tab_at(self, x: int, is_double: bool = False, is_middle: bool = False) -> None:
         i = self.tab_bar.tab_at(x)
         if i is None:
             if is_double:
                 self.new_tab()
         else:
             self.set_active_tab_idx(i)
+            if is_middle:
+                tab = self.active_tab
+                if tab is not None:
+                    get_boss().confirm_tab_close(tab)
 
     @property
     def tab_bar_rects(self) -> Tuple[Border, ...]:
@kovidgoyal
Copy link
Owner

I am not a fan of this. It's not at all discoverable and has a very big
downside for an accidental click -- you lose the entire tab if you accidentally
middle click on it.

@page-down
Copy link
Contributor Author

I think clicking the middle mouse button on the tab to close is a pretty common pattern for most mouse users.

There is no close button on the Tab, which I think it is a feature that prevents closing by mistake. I really like it. However, I think it is worthwhile to at least provide a way to close the tab with the mouse as a complement to the functionality of the tab with the mouse. And there is already confirm_os_window_close to prevent accidental closing of the tab.

Clicking the middle mouse button is not fundamentally different from pressing ctrl+shift+q to close the tab by mistake, and this feature does not affect keyboard-heavy users.

It is absolutely right not to spend time on features you don't like. Please feel free to take a look at the heartfelt suggestions of all sides and make a decision that will benefit the project and the majority of users.

@kovidgoyal
Copy link
Owner

Well, I have to say I was not aware that middle click on a tab is an existing convention. In that case, it might be worth re-considering.

@page-down
Copy link
Contributor Author

page-down commented Oct 24, 2021

Thank you for your reconsideration.

In kitty/glfw.c, get_click_interval needs to be moved out of #ifdef __APPLE__ #else #endif, otherwise it fails to compile under macOS.

It is recommended to switch to the tab first and then close it, otherwise the close confirmation prompt will not be focused when confirm_os_window_close is enabled.

A better way is to switch the tab when it needs confirmation to be closed. If it doesn't need to be confirmed, it can be closed without causing the current tab to be switched. However this requires some additional checking.

@page-down
Copy link
Contributor Author

page-down commented Oct 25, 2021

I pulled the latest update and it compiles fine under macOS. However I found the same problem I encountered before, where the middle mouse button clicking on the tab bar also triggers the default action.

Open two tabs, make sure there is text in the clipboard, then middle mouse click to close one, you can see the text is pasted inside the shell of the last tab (window).

kitty --config=NONE -o confirm_os_window_close=-1

@kovidgoyal
Copy link
Owner

Doesn't happen for me on Linux, with default config, is this macOS specific?

@kovidgoyal
Copy link
Owner

This should take care of it, in any case: 3769211

@page-down
Copy link
Contributor Author

Yes, I was reproducing it before under macOS. This commit solves the issue.

Thank you for your refinement of mouse-related features.

@page-down
Copy link
Contributor Author

I think the reason for triggering the release event before is that:
When only the last tab is left, the tab bar disappears, causing the mouse to be in range of the last window when it is released.

I found a new issue.
You need to release the mouse within the click_interval time frame, otherwise the tab will not close.
You can reproduce the problem with the following command, tab will not close after middle mouse button click.

kitty --config=NONE -o click_interval=0

Also I have a question about the reporting of mouse movement events.

dont report motion events, as they are expensive and useless

Under macOS, moving the mouse outside the window also results in reporting of movement events.

Move mouse_button: -1 mods: none handled by tab bar
...

Perhaps leading to wasted energy (on battery) and so on. Is there a possibility to optimize this? I can help troubleshoot where the problem is if needed.

Confirmed that there is no such problem under Linux X11, mouse movements outside the window do not generate any events.

@kovidgoyal
Copy link
Owner

kovidgoyal commented Oct 25, 2021 via email

@page-down
Copy link
Contributor Author

I found that double-clicking on the tab bar does not create a new tab.

It seems to be related to the following:

diff --git a/kitty/tabs.py b/kitty/tabs.py
index 5c9ea1ae..0d9449f6 100644
--- a/kitty/tabs.py
+++ b/kitty/tabs.py
@@ -992,7 +992,7 @@ def handle_click_on_tab(self, x: int, button: int, modifiers: int, action: int)
                 prev, prev2 = self.recent_mouse_events[-1], self.recent_mouse_events[-2]
                 if (
                     prev.button == button and prev2.button == button and
-                    prev.action == GLFW_RELEASE and prev2.action == GLFW_PRESS and
+                    prev.action == GLFW_PRESS and prev2.action == GLFW_RELEASE and
                     prev.tab_idx is None and prev2.tab_idx is None and
                     now - prev.at <= ci and now - prev2.at <= 2 * ci
                 ):  # double click

@chapmanjacobd
Copy link

chapmanjacobd commented Aug 3, 2022

not at all discoverable and has a very big downside for an accidental click -- you lose the entire tab if you accidentally

that just happened to me. didn't know this was even possible

Is there a way to disable this? I don't have a need of creating or deleting tabs with the mouse, although I sometimes use the mouse to go to a specific tab.

I don't care if there is an option to disable creating new tabs via double click. The only thing is that my middle and left click button on my mouse are very close so I probably have accidentally closed a single-window tab before and wondered where my tab went but I didn't realize what happened until this time

edit: nevermind I'll just use confirm_os_window_close -1 instead of confirm_os_window_close 2

@wmullaney
Copy link

GNOME used to be so wonderful. It's the little things that count. Why are the scroll bars so thin?? Middle mouse button!? Users have been complaining about the middle mouse button since 2013!!! I actually lost this comment the first time I tried to post it because of the middle mouse button. Why aren't the dev teams listening to the users?? The usual response is "well you can edit the config files yourself" I think I have actually heard/read this about a thousand times. Yes we can but just like with this middle mouse button behavior...if I edit my config file and unbind the middle mouse button guess what? The driver auto assigns a device id which changes when your reboot. This means I have to open terminal and manually unbind the mouse button every time I reboot. Updates? Well, config file edits are gone! This is why "just edit the config files" comment is infuriating. It's not an "adult" response to a legitimate concern. Most linux users are IT professionals. It's not like we're ol' Mac Donald on his friggin farm complaining that he can't find the "any key." Having the middle mouse button close anything is absurd. Having it paste is arguably more absurd. Most middle mouse buttons are on the scroll wheel which means they are prone to accidental clicks. On laptops with a touchpad, there are no "middle buttons" so half of the time you click on the touchpad it registers as a middle button click. Can't tell you how many times I have been in VSCode/IDE and found a syntax error from something that was pasted via the middle mouse button. It has absolutely no use, get rid of it, be rid of it. It was and always will be a terrible idea. It reminds me of Steve Jobs...when the 1st iPhone came out he demanded the developers remove the ability to copy/paste from the OS. He even became angry and spiteful over this. Needless to say they removed the copy/paste functionality and guess what happened? On launch day the first and most numerous complaint was "Where is the copy/paste function?!" The development team eventually added back the copy/paste functionality but from personal accounts Jobs fought it all the way. Whoever is fighting to keep the middle mouse button behavior is much more than just stubborn, they are ignoring millions of users for almost a decade. I hope every morning this person steps on a lego or stumps their toe. I hope they spill their soda or coffee in their car between the seats where you can't reach it or get a towel in there. Better yet, force them to use GNOME like we do for work everyday, make them lose work, waste time and rethink life choices. If you have been annoyed with the middle mouse button, lost work and time because of it, you are not alone. It sucks and we know it.

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

No branches or pull requests

4 participants