Send mouse events to child directly in C

This commit is contained in:
Kovid Goyal 2017-09-14 18:04:12 +05:30
parent ee0a539e01
commit 21accfe114
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 20 additions and 90 deletions

View File

@ -7,21 +7,21 @@ from weakref import WeakValueDictionary
from .config import MINIMUM_FONT_SIZE from .config import MINIMUM_FONT_SIZE
from .constants import ( from .constants import (
MODIFIER_KEYS, cell_size, is_key_pressed, MODIFIER_KEYS, cell_size, is_key_pressed, set_boss, viewport_size, wakeup
set_boss, viewport_size, wakeup
) )
from .fast_data_types import ( from .fast_data_types import (
GLFW_PRESS, GLFW_REPEAT, ChildMonitor, GLFW_KEY_DOWN, GLFW_KEY_UP, GLFW_PRESS, GLFW_REPEAT, ChildMonitor,
destroy_global_data, destroy_sprite_map, glfw_post_empty_event, destroy_global_data, destroy_sprite_map, glfw_post_empty_event,
layout_sprite_map layout_sprite_map
) )
from .fonts.render import render_cell_wrapper, set_font_family from .fonts.render import render_cell_wrapper, set_font_family
from .keys import ( from .keys import (
get_sent_data, get_shortcut, interpret_key_event, interpret_text_event get_key_map, get_sent_data, get_shortcut, interpret_key_event,
interpret_text_event
) )
from .session import create_session from .session import create_session
from .tabs import SpecialWindow, TabManager from .tabs import SpecialWindow, TabManager
from .utils import safe_print, get_primary_selection, set_primary_selection from .utils import get_primary_selection, safe_print, set_primary_selection
from .window import load_shader_programs from .window import load_shader_programs
@ -241,6 +241,12 @@ class Boss:
except AttributeError: except AttributeError:
pass # needs glfw 3.3 pass # needs glfw 3.3
def send_fake_scroll(self, window_idx, amt, upwards):
tab = self.active_tab
w = tab.windows[window_idx]
k = get_key_map(w.screen)[GLFW_KEY_UP if upwards else GLFW_KEY_DOWN]
w.write_to_child(k * amt)
def gui_close_window(self, window): def gui_close_window(self, window):
window.destroy() window.destroy()
for tab in self.tab_manager: for tab in self.tab_manager:

View File

@ -48,7 +48,7 @@ button_map(int button) {
static char mouse_event_buf[64]; static char mouse_event_buf[64];
unsigned int size_t
encode_mouse_event(Window *w, int button, MouseAction action, int mods) { encode_mouse_event(Window *w, int button, MouseAction action, int mods) {
unsigned int x = w->mouse_cell_x + 1, y = w->mouse_cell_y + 1; // 1 based indexing unsigned int x = w->mouse_cell_x + 1, y = w->mouse_cell_y + 1; // 1 based indexing
unsigned int cb = 0; unsigned int cb = 0;
@ -172,7 +172,8 @@ HANDLER(handle_move_event) {
} }
} else { } else {
if (!mouse_cell_changed) return; if (!mouse_cell_changed) return;
// TODO: Implement this size_t sz = encode_mouse_event(w, MAX(0, button), button >=0 ? DRAG : MOVE, 0);
if (sz) schedule_write_to_child(w->id, mouse_event_buf, sz);
} }
} }
@ -246,7 +247,8 @@ HANDLER(handle_button_event) {
break; break;
} }
} else { } else {
// TODO: Implement this size_t sz = encode_mouse_event(w, button, is_release ? RELEASE : PRESS, modifiers);
if (sz) schedule_write_to_child(w->id, mouse_event_buf, sz);
} }
} }
@ -320,9 +322,10 @@ scroll_event(double UNUSED xoffset, double yoffset) {
screen_history_scroll(screen, abs(s), upwards); screen_history_scroll(screen, abs(s), upwards);
} else { } else {
if (screen->modes.mouse_tracking_mode) { if (screen->modes.mouse_tracking_mode) {
// TODO: Implement this size_t sz = encode_mouse_event(w, upwards ? GLFW_MOUSE_BUTTON_4 : GLFW_MOUSE_BUTTON_5, PRESS, 0);
if (sz) schedule_write_to_child(w->id, mouse_event_buf, sz);
} else { } else {
// TODO: Implement this, writing a up arrow or down arrow key event to the child call_boss(send_fake_scroll, "IiO", window_idx, abs(s), upwards ? Py_True : Py_False);
} }
} }
} }

View File

@ -8,24 +8,19 @@ import weakref
from collections import deque from collections import deque
from enum import Enum from enum import Enum
from itertools import count from itertools import count
from time import monotonic
from .config import build_ansi_color_table from .config import build_ansi_color_table
from .constants import ( from .constants import (
ScreenGeometry, WindowGeometry, appname, cell_size, get_boss, ScreenGeometry, WindowGeometry, appname, cell_size, get_boss,
is_key_pressed, mouse_button_pressed, viewport_size, wakeup viewport_size, wakeup
) )
from .fast_data_types import ( from .fast_data_types import (
BRACKETED_PASTE_END, BRACKETED_PASTE_START, CELL_PROGRAM, CURSOR_PROGRAM, BRACKETED_PASTE_END, BRACKETED_PASTE_START, CELL_PROGRAM, CURSOR_PROGRAM,
GLFW_KEY_DOWN, GLFW_KEY_LEFT_SHIFT, GLFW_KEY_RIGHT_SHIFT, GLFW_KEY_UP,
GLFW_MOD_SHIFT, GLFW_MOUSE_BUTTON_1, GLFW_MOUSE_BUTTON_4,
GLFW_MOUSE_BUTTON_5, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, GLFW_RELEASE,
SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen, compile_program, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen, compile_program,
create_cell_vao, glfw_post_empty_event, init_cell_program, create_cell_vao, glfw_post_empty_event, init_cell_program,
init_cursor_program, remove_vao, set_window_render_data, init_cursor_program, remove_vao, set_window_render_data,
update_window_title, update_window_visibility update_window_title, update_window_visibility
) )
from .keys import get_key_map
from .rgb import to_color from .rgb import to_color
from .terminfo import get_capabilities from .terminfo import get_capabilities
from .utils import ( from .utils import (
@ -260,80 +255,6 @@ class Window:
if url: if url:
open_url(url, self.opts.open_url_with) open_url(url, self.opts.open_url_with)
def on_mouse_button(self, button, action, mods):
mode = self.screen.mouse_tracking_mode()
handle_event = mods == GLFW_MOD_SHIFT or mode == 0 or button == GLFW_MOUSE_BUTTON_MIDDLE or (
mods == self.opts.open_url_modifiers and button == GLFW_MOUSE_BUTTON_1)
x, y = self.last_mouse_cursor_pos
if handle_event:
if button == GLFW_MOUSE_BUTTON_1:
self.update_drag(action == GLFW_PRESS, x, y)
if action == GLFW_RELEASE:
if mods == self.opts.open_url_modifiers:
self.click_url(x, y)
self.click_queue.append(monotonic())
self.dispatch_multi_click(x, y)
elif button == GLFW_MOUSE_BUTTON_MIDDLE:
if action == GLFW_RELEASE:
self.paste_from_selection()
else:
x, y = self.cell_for_pos(x, y)
if x is not None:
ev = encode_mouse_event(mode, self.screen.mouse_tracking_protocol(),
button, PRESS if action == GLFW_PRESS else RELEASE, mods, x, y)
if ev:
self.write_to_child(ev)
def on_mouse_move(self, x, y):
button = None
for b in range(0, GLFW_MOUSE_BUTTON_5 + 1):
if mouse_button_pressed[b]:
button = b
break
mode = self.screen.mouse_tracking_mode()
ANY_MODE, MOTION_MODE = 3, 2
send_event = (mode == ANY_MODE or (mode == MOTION_MODE and button is not None)) and not (
is_key_pressed[GLFW_KEY_LEFT_SHIFT] or is_key_pressed[GLFW_KEY_RIGHT_SHIFT])
x, y = max(0, x - self.geometry.left), max(0, y - self.geometry.top)
self.last_mouse_cursor_pos = x, y
get_boss().change_mouse_cursor(self.has_url_at(x, y))
if send_event:
action = MOVE if button is None else DRAG
x, y = self.cell_for_pos(x, y)
if x is not None:
ev = encode_mouse_event(mode, self.screen.mouse_tracking_protocol(),
button, action, 0, x, y)
if ev:
self.write_to_child(ev)
else:
if self.screen.is_selection_in_progress():
self.update_drag(None, x, y)
margin = cell_size.height // 2
if y <= margin or y >= self.geometry.bottom - margin:
get_boss().ui_timers.add(0.02, self.drag_scroll)
def on_mouse_scroll(self, x, y):
s = int(round(y * self.opts.wheel_scroll_multiplier))
if abs(s) < 0:
return
upwards = s > 0
if self.screen.is_main_linebuf():
self.screen.scroll(abs(s), upwards)
glfw_post_empty_event()
else:
mode = self.screen.mouse_tracking_mode()
send_event = mode > 0
if send_event:
x, y = self.last_mouse_cursor_pos
x, y = self.cell_for_pos(x, y)
if x is not None:
ev = encode_mouse_event(mode, self.screen.mouse_tracking_protocol(),
GLFW_MOUSE_BUTTON_4 if upwards else GLFW_MOUSE_BUTTON_5, PRESS, 0, x, y)
if ev:
self.write_to_child(ev)
else:
k = get_key_map(self.screen)[GLFW_KEY_UP if upwards else GLFW_KEY_DOWN]
self.write_to_child(k * abs(s))
# }}} # }}}
def destroy(self): def destroy(self):