Send mouse events to child directly in C
This commit is contained in:
parent
ee0a539e01
commit
21accfe114
@ -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:
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user