Handle mouse clicks when displaying focus window overlay

This commit is contained in:
Kovid Goyal 2021-10-15 09:55:15 +05:30
parent 3c2e521dd7
commit a16ffcdde2
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 75 additions and 9 deletions

View File

@ -31,14 +31,14 @@ from .fast_data_types import (
GLFW_MOD_SUPER, IMPERATIVE_CLOSE_REQUESTED, NO_CLOSE_REQUESTED,
ChildMonitor, KeyEvent, add_timer, apply_options_update,
background_opacity_of, change_background_opacity, change_os_window_state,
cocoa_set_menubar_title, create_os_window,
cocoa_set_menubar_title, create_os_window, GLFW_PRESS, GLFW_MOUSE_BUTTON_LEFT,
current_application_quit_request, current_os_window, destroy_global_data,
focus_os_window, get_clipboard_string, get_options, get_os_window_size,
global_font_size, mark_os_window_for_close, os_window_font_size,
patch_global_colors, ring_bell, safe_pipe, set_application_quit_request,
set_background_image, set_boss, set_clipboard_string, set_in_sequence_mode,
set_options, set_os_window_size, thread_write, toggle_fullscreen,
toggle_maximized
patch_global_colors, redirect_mouse_handling, ring_bell, safe_pipe,
set_application_quit_request, set_background_image, set_boss,
set_clipboard_string, set_in_sequence_mode, set_options,
set_os_window_size, thread_write, toggle_fullscreen, toggle_maximized
)
from .key_encoding import get_name_to_functional_number_map
from .keys import get_shortcut, shortcut_matches
@ -52,7 +52,7 @@ from .session import Session, create_sessions, get_os_window_sizing_data
from .tabs import (
SpecialWindow, SpecialWindowInstance, Tab, TabDict, TabManager
)
from .types import _T, SingleKey, ac
from .types import _T, SingleKey, WindowSystemMouseEvent, ac
from .typing import PopenType, TypedDict
from .utils import (
func_name, get_editor, get_new_os_window_size, get_primary_selection,
@ -183,6 +183,7 @@ class Boss:
self.args = args
self.global_shortcuts_map = {v: KeyAction(k) for k, v in global_shortcuts.items()}
self.global_shortcuts = global_shortcuts
self.mouse_handler: Optional[Callable[[WindowSystemMouseEvent], None]] = None
self.update_keymap()
if is_macos:
from .fast_data_types import (
@ -779,6 +780,10 @@ class Boss:
elif isinstance(key_action, KeyAction):
return self.dispatch_action(key_action)
def clear_pending_sequences(self) -> None:
self.pending_sequences = self.default_pending_action = None
set_in_sequence_mode(False)
def process_sequence(self, ev: KeyEvent) -> None:
if not self.pending_sequences:
set_in_sequence_mode(False)
@ -798,8 +803,7 @@ class Boss:
self.pending_sequences = remaining
else:
matched_action = matched_action or self.default_pending_action
self.pending_sequences = self.default_pending_action = None
set_in_sequence_mode(False)
self.clear_pending_sequences()
if matched_action is not None:
self.dispatch_action(matched_action)
@ -825,6 +829,8 @@ class Boss:
pending_sequences[(SingleKey(mods=mods, key=fmap[f'KP_{idx+1}']),)] = ac
if count > 1:
self.set_pending_sequences(pending_sequences, default_pending_action=KeyAction('focus_visible_window_trigger'))
redirect_mouse_handling(True)
self.mouse_handler = self.focus_visible_window_mouse_handler
else:
self.focus_visible_window_trigger()
if get_options().enable_audio_bell:
@ -832,12 +838,34 @@ class Boss:
def focus_visible_window_trigger(self, idx: int = -1) -> None:
tab = self.active_tab
redirect_mouse_handling(False)
if tab is not None:
for window in tab:
window.screen.set_window_number()
if idx > -1:
tab.nth_window(idx)
def focus_visible_window_mouse_handler(self, ev: WindowSystemMouseEvent) -> None:
if ev.button == GLFW_MOUSE_BUTTON_LEFT and ev.action == GLFW_PRESS and ev.window_id:
w = self.window_id_map.get(ev.window_id)
tab = self.active_tab
if w is not None and tab is not None and w in tab:
tab.set_active_window(w)
self.clear_pending_sequences()
self.focus_visible_window_trigger()
return
if ev.button > -1:
self.clear_pending_sequences()
self.focus_visible_window_trigger()
def mouse_event(
self, in_tab_bar: bool, window_id: int, action: int, modifiers: int, button: int,
currently_pressed_button: int, x: float, y: float
) -> None:
if self.mouse_handler is not None:
ev = WindowSystemMouseEvent(in_tab_bar, window_id, action, modifiers, button, currently_pressed_button, x, y)
self.mouse_handler(ev)
@ac('win', 'Interactively select a window in the current tab')
def select_window_in_tab(self) -> None:
tab = self.active_tab

View File

@ -1246,3 +1246,7 @@ def get_all_processes() -> Tuple[int, ...]:
def num_users() -> int:
pass
def redirect_mouse_handling(yes: bool) -> None:
pass

View File

@ -669,6 +669,16 @@ mouse_event(const int button, int modifiers, int action) {
unsigned int window_idx = 0;
Window *w = NULL;
debug("%s mouse_button: %d %s", action == GLFW_RELEASE ? "\x1b[32mRelease\x1b[m" : (button < 0 ? "\x1b[36mMove\x1b[m" : "\x1b[31mPress\x1b[m"), button, format_mods(modifiers));
if (global_state.redirect_mouse_handling) {
w = window_for_event(&window_idx, &in_tab_bar);
call_boss(mouse_event, "OK iiii dd",
(in_tab_bar ? Py_True : Py_False), (w ? w->id : 0),
action, modifiers, button, currently_pressed_button(),
global_state.callback_os_window->mouse_x, global_state.callback_os_window->mouse_y
);
debug("mouse handling redirected\n");
return;
}
if (global_state.active_drag_in_window) {
if (button == -1) { // drag move
w = window_for_id(global_state.active_drag_in_window);

View File

@ -1055,7 +1055,18 @@ PYWRAP1(click_mouse_url) {
if (click_mouse_url(a, b, c)) { Py_RETURN_TRUE; }
Py_RETURN_FALSE;
}
PYWRAP1(move_cursor_to_mouse_if_in_prompt) { id_type a, b, c; PA("KKK", &a, &b, &c); if (move_cursor_to_mouse_if_in_prompt(a, b, c)) Py_RETURN_TRUE; Py_RETURN_FALSE; }
PYWRAP1(move_cursor_to_mouse_if_in_prompt) {
id_type a, b, c; PA("KKK", &a, &b, &c);
if (move_cursor_to_mouse_if_in_prompt(a, b, c)) Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
PYWRAP1(redirect_mouse_handling) {
global_state.redirect_mouse_handling = PyObject_IsTrue(args) ? true : false;
Py_RETURN_NONE;
}
THREE_ID_OBJ(update_window_title)
THREE_ID(remove_window)
THREE_ID(detach_window)
@ -1080,6 +1091,7 @@ static PyMethodDef module_methods[] = {
MW(get_options, METH_NOARGS),
MW(click_mouse_url, METH_VARARGS),
MW(move_cursor_to_mouse_if_in_prompt, METH_VARARGS),
MW(redirect_mouse_handling, METH_O),
MW(mouse_selection, METH_VARARGS),
MW(set_in_sequence_mode, METH_O),
MW(resolve_key_mods, METH_VARARGS),

View File

@ -217,6 +217,7 @@ typedef struct {
id_type active_drag_in_window, tracked_drag_in_window;
int active_drag_button;
CloseRequest quit_request;
bool redirect_mouse_handling;
} GlobalState;
extern GlobalState global_state;

View File

@ -61,6 +61,17 @@ class MouseEvent(NamedTuple):
grabbed: bool = False
class WindowSystemMouseEvent(NamedTuple):
in_tab_bar: bool
window_id: int
action: int
modifiers: int
button: int
currently_pressed_button: int
x: float
y: float
ConvertibleToNumbers = Union[str, bytes, int, float]