Dont call glfw functions from the child thread
This commit is contained in:
parent
92401ee4b1
commit
c9af8bc0bc
@ -6,7 +6,7 @@ import os
|
|||||||
import threading
|
import threading
|
||||||
import pwd
|
import pwd
|
||||||
import ctypes
|
import ctypes
|
||||||
from collections import namedtuple
|
from collections import namedtuple, defaultdict
|
||||||
|
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
GLFW_KEY_LEFT_SHIFT, GLFW_KEY_RIGHT_SHIFT, GLFW_KEY_LEFT_ALT,
|
GLFW_KEY_LEFT_SHIFT, GLFW_KEY_RIGHT_SHIFT, GLFW_KEY_LEFT_ALT,
|
||||||
@ -65,6 +65,7 @@ def queue_action(func, *args):
|
|||||||
tab_manager.manager.queue_action(func, *args)
|
tab_manager.manager.queue_action(func, *args)
|
||||||
|
|
||||||
|
|
||||||
|
is_key_pressed = defaultdict(lambda: False)
|
||||||
viewport_size = ViewportSize()
|
viewport_size = ViewportSize()
|
||||||
cell_size = ViewportSize()
|
cell_size = ViewportSize()
|
||||||
terminfo_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'terminfo')
|
terminfo_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'terminfo')
|
||||||
|
|||||||
@ -24,6 +24,7 @@ from .fast_data_types import (
|
|||||||
from .fonts import set_font_family
|
from .fonts import set_font_family
|
||||||
from .borders import Borders, BordersProgram
|
from .borders import Borders, BordersProgram
|
||||||
from .char_grid import cursor_shader, cell_shader
|
from .char_grid import cursor_shader, cell_shader
|
||||||
|
from .constants import is_key_pressed
|
||||||
from .keys import interpret_text_event, interpret_key_event, get_shortcut
|
from .keys import interpret_text_event, interpret_key_event, get_shortcut
|
||||||
from .layout import Stack
|
from .layout import Stack
|
||||||
from .shaders import Sprites, ShaderProgram
|
from .shaders import Sprites, ShaderProgram
|
||||||
@ -301,6 +302,7 @@ class TabManager(Thread):
|
|||||||
|
|
||||||
@callback
|
@callback
|
||||||
def on_key(self, window, key, scancode, action, mods):
|
def on_key(self, window, key, scancode, action, mods):
|
||||||
|
is_key_pressed[key] = action == GLFW_PRESS
|
||||||
self.start_cursor_blink()
|
self.start_cursor_blink()
|
||||||
if action == GLFW_PRESS or action == GLFW_REPEAT:
|
if action == GLFW_PRESS or action == GLFW_REPEAT:
|
||||||
func = get_shortcut(self.opts.keymap, mods, key)
|
func = get_shortcut(self.opts.keymap, mods, key)
|
||||||
@ -357,7 +359,7 @@ class TabManager(Thread):
|
|||||||
if old_focus is not None and not old_focus.destroyed:
|
if old_focus is not None and not old_focus.destroyed:
|
||||||
old_focus.focus_changed(False)
|
old_focus.focus_changed(False)
|
||||||
w.focus_changed(True)
|
w.focus_changed(True)
|
||||||
w.on_mouse_button(window, button, action, mods)
|
w.on_mouse_button(button, action, mods)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def on_mouse_move(self, window, xpos, ypos):
|
def on_mouse_move(self, window, xpos, ypos):
|
||||||
@ -365,7 +367,7 @@ class TabManager(Thread):
|
|||||||
w = self.window_for_pos(*window.get_cursor_pos())
|
w = self.window_for_pos(*window.get_cursor_pos())
|
||||||
if w is not None:
|
if w is not None:
|
||||||
yield w
|
yield w
|
||||||
w.on_mouse_move(window, xpos, ypos)
|
w.on_mouse_move(xpos, ypos)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def on_mouse_scroll(self, window, x, y):
|
def on_mouse_scroll(self, window, x, y):
|
||||||
@ -373,7 +375,7 @@ class TabManager(Thread):
|
|||||||
w = self.window_for_pos(*window.get_cursor_pos())
|
w = self.window_for_pos(*window.get_cursor_pos())
|
||||||
if w is not None:
|
if w is not None:
|
||||||
yield w
|
yield w
|
||||||
w.on_mouse_scroll(window, x, y)
|
w.on_mouse_scroll(x, y)
|
||||||
|
|
||||||
# GUI thread API {{{
|
# GUI thread API {{{
|
||||||
|
|
||||||
@ -458,4 +460,12 @@ class TabManager(Thread):
|
|||||||
self.sprites.destroy()
|
self.sprites.destroy()
|
||||||
del self.sprites
|
del self.sprites
|
||||||
del self.glfw_window
|
del self.glfw_window
|
||||||
|
|
||||||
|
def paste_from_clipboard(self):
|
||||||
|
text = self.glfw_window.get_clipboard_string()
|
||||||
|
if text:
|
||||||
|
w = self.active_window
|
||||||
|
if w is not None:
|
||||||
|
self.queue_action(w.paste, text)
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ from functools import partial
|
|||||||
from time import monotonic
|
from time import monotonic
|
||||||
|
|
||||||
from .char_grid import CharGrid
|
from .char_grid import CharGrid
|
||||||
from .constants import wakeup, tab_manager, appname, WindowGeometry
|
from .constants import wakeup, tab_manager, appname, WindowGeometry, is_key_pressed
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
BRACKETED_PASTE_START, BRACKETED_PASTE_END, Screen, read_bytes_dump,
|
BRACKETED_PASTE_START, BRACKETED_PASTE_END, Screen, read_bytes_dump,
|
||||||
read_bytes, GLFW_MOD_SHIFT, GLFW_MOUSE_BUTTON_1, GLFW_PRESS,
|
read_bytes, GLFW_MOD_SHIFT, GLFW_MOUSE_BUTTON_1, GLFW_PRESS,
|
||||||
@ -28,6 +28,7 @@ class Window:
|
|||||||
def __init__(self, tab, child, opts, args):
|
def __init__(self, tab, child, opts, args):
|
||||||
self.tabref = weakref.ref(tab)
|
self.tabref = weakref.ref(tab)
|
||||||
self.mouse_button_pressed = defaultdict(lambda: False)
|
self.mouse_button_pressed = defaultdict(lambda: False)
|
||||||
|
self.last_mouse_cursor_pos = 0, 0
|
||||||
self.destroyed = False
|
self.destroyed = False
|
||||||
self.click_queue = deque(maxlen=3)
|
self.click_queue = deque(maxlen=3)
|
||||||
self.geometry = WindowGeometry(0, 0, 0, 0, 0, 0)
|
self.geometry = WindowGeometry(0, 0, 0, 0, 0, 0)
|
||||||
@ -152,12 +153,11 @@ class Window:
|
|||||||
self.char_grid.multi_click(2, x, y)
|
self.char_grid.multi_click(2, x, y)
|
||||||
glfw_post_empty_event()
|
glfw_post_empty_event()
|
||||||
|
|
||||||
def on_mouse_button(self, window, button, action, mods):
|
def on_mouse_button(self, button, action, mods):
|
||||||
self.mouse_button_pressed[button] = action == GLFW_PRESS
|
self.mouse_button_pressed[button] = action == GLFW_PRESS
|
||||||
mode = self.screen.mouse_tracking_mode()
|
mode = self.screen.mouse_tracking_mode()
|
||||||
send_event = mods != GLFW_MOD_SHIFT and mode > 0
|
send_event = mods != GLFW_MOD_SHIFT and mode > 0
|
||||||
x, y = window.get_cursor_pos()
|
x, y = self.last_mouse_cursor_pos
|
||||||
x, y = max(0, x - self.geometry.left), max(0, y - self.geometry.top)
|
|
||||||
if not send_event:
|
if not send_event:
|
||||||
if button == GLFW_MOUSE_BUTTON_1:
|
if button == GLFW_MOUSE_BUTTON_1:
|
||||||
self.char_grid.update_drag(action == GLFW_PRESS, x, y)
|
self.char_grid.update_drag(action == GLFW_PRESS, x, y)
|
||||||
@ -179,7 +179,7 @@ class Window:
|
|||||||
if ev:
|
if ev:
|
||||||
self.write_to_child(ev)
|
self.write_to_child(ev)
|
||||||
|
|
||||||
def on_mouse_move(self, window, x, y):
|
def on_mouse_move(self, x, y):
|
||||||
button = None
|
button = None
|
||||||
for b in range(0, GLFW_MOUSE_BUTTON_5 + 1):
|
for b in range(0, GLFW_MOUSE_BUTTON_5 + 1):
|
||||||
if self.mouse_button_pressed[b]:
|
if self.mouse_button_pressed[b]:
|
||||||
@ -188,8 +188,9 @@ class Window:
|
|||||||
action = MOVE if button is None else DRAG
|
action = MOVE if button is None else DRAG
|
||||||
mode = self.screen.mouse_tracking_mode()
|
mode = self.screen.mouse_tracking_mode()
|
||||||
send_event = (mode == ANY_MODE or (mode == MOTION_MODE and button is not None)) and not (
|
send_event = (mode == ANY_MODE or (mode == MOTION_MODE and button is not None)) and not (
|
||||||
window.is_key_pressed(GLFW_KEY_LEFT_SHIFT) or window.is_key_pressed(GLFW_KEY_RIGHT_SHIFT))
|
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)
|
x, y = max(0, x - self.geometry.left), max(0, y - self.geometry.top)
|
||||||
|
self.last_mouse_cursor_pos = x, y
|
||||||
tm = tab_manager()
|
tm = tab_manager()
|
||||||
tm.queue_ui_action(tab_manager().change_mouse_cursor, self.char_grid.has_url_at(x, y))
|
tm.queue_ui_action(tab_manager().change_mouse_cursor, self.char_grid.has_url_at(x, y))
|
||||||
if send_event:
|
if send_event:
|
||||||
@ -203,7 +204,7 @@ class Window:
|
|||||||
if self.char_grid.current_selection.in_progress:
|
if self.char_grid.current_selection.in_progress:
|
||||||
self.char_grid.update_drag(None, x, y)
|
self.char_grid.update_drag(None, x, y)
|
||||||
|
|
||||||
def on_mouse_scroll(self, window, x, y):
|
def on_mouse_scroll(self, x, y):
|
||||||
s = int(round(y * self.opts.wheel_scroll_multiplier))
|
s = int(round(y * self.opts.wheel_scroll_multiplier))
|
||||||
if abs(s) < 0:
|
if abs(s) < 0:
|
||||||
return
|
return
|
||||||
@ -215,8 +216,7 @@ class Window:
|
|||||||
mode = self.screen.mouse_tracking_mode()
|
mode = self.screen.mouse_tracking_mode()
|
||||||
send_event = mode > 0
|
send_event = mode > 0
|
||||||
if send_event:
|
if send_event:
|
||||||
x, y = window.get_cursor_pos()
|
x, y = self.last_mouse_cursor_pos
|
||||||
x, y = max(0, x - self.geometry.left), max(0, y - self.geometry.top)
|
|
||||||
x, y = self.char_grid.cell_for_pos(x, y)
|
x, y = self.char_grid.cell_for_pos(x, y)
|
||||||
if x is not None:
|
if x is not None:
|
||||||
ev = encode_mouse_event(mode, self.screen.mouse_tracking_protocol(),
|
ev = encode_mouse_event(mode, self.screen.mouse_tracking_protocol(),
|
||||||
@ -233,18 +233,13 @@ class Window:
|
|||||||
# actions {{{
|
# actions {{{
|
||||||
|
|
||||||
def paste(self, text):
|
def paste(self, text):
|
||||||
if text:
|
if text and not self.destroyed:
|
||||||
if isinstance(text, str):
|
if isinstance(text, str):
|
||||||
text = text.encode('utf-8')
|
text = text.encode('utf-8')
|
||||||
if self.screen.in_bracketed_paste_mode():
|
if self.screen.in_bracketed_paste_mode():
|
||||||
text = BRACKETED_PASTE_START.encode('ascii') + text + BRACKETED_PASTE_END.encode('ascii')
|
text = BRACKETED_PASTE_START.encode('ascii') + text + BRACKETED_PASTE_END.encode('ascii')
|
||||||
self.write_to_child(text)
|
self.write_to_child(text)
|
||||||
|
|
||||||
def paste_from_clipboard(self):
|
|
||||||
text = tab_manager().glfw_window.get_clipboard_string()
|
|
||||||
if text:
|
|
||||||
self.paste(text)
|
|
||||||
|
|
||||||
def paste_from_selection(self):
|
def paste_from_selection(self):
|
||||||
text = get_primary_selection()
|
text = get_primary_selection()
|
||||||
if text:
|
if text:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user