More refactoring

This commit is contained in:
Kovid Goyal
2016-12-05 20:52:08 +05:30
parent 69defd3fe4
commit de2c1deb97
7 changed files with 57 additions and 35 deletions

View File

@@ -8,14 +8,13 @@ import select
import signal import signal
import struct import struct
import inspect import inspect
from collections import deque
from functools import wraps from functools import wraps
from threading import Thread, current_thread from threading import Thread, current_thread
from time import monotonic from time import monotonic
from queue import Queue, Empty from queue import Queue, Empty
from .constants import ( from .constants import (
viewport_size, set_tab_manager, wakeup, cell_size, MODIFIER_KEYS, viewport_size, set_boss, wakeup, cell_size, MODIFIER_KEYS,
main_thread, mouse_button_pressed, mouse_cursor_pos main_thread, mouse_button_pressed, mouse_cursor_pos
) )
from .fast_data_types import ( from .fast_data_types import (
@@ -29,7 +28,7 @@ from .char_grid import cursor_shader, cell_shader
from .constants import is_key_pressed 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 .shaders import Sprites, ShaderProgram from .shaders import Sprites, ShaderProgram
from .tabs import Tab from .tabs import TabManager
from .timers import Timers from .timers import Timers
from .utils import handle_unix_signals from .utils import handle_unix_signals
@@ -82,7 +81,7 @@ class Boss(Thread):
self.ui_timers = Timers() self.ui_timers = Timers()
self.pending_ui_thread_calls = Queue() self.pending_ui_thread_calls = Queue()
self.write_dispatch_map = {} self.write_dispatch_map = {}
set_tab_manager(self) set_boss(self)
cell_size.width, cell_size.height = set_font_family(opts.font_family, opts.font_size) cell_size.width, cell_size.height = set_font_family(opts.font_family, opts.font_size)
self.opts, self.args = opts, args self.opts, self.args = opts, args
self.glfw_window = glfw_window self.glfw_window = glfw_window
@@ -93,8 +92,7 @@ class Boss(Thread):
glfw_window.scroll_callback = self.on_mouse_scroll glfw_window.scroll_callback = self.on_mouse_scroll
glfw_window.cursor_pos_callback = self.on_mouse_move glfw_window.cursor_pos_callback = self.on_mouse_move
glfw_window.window_focus_callback = self.on_focus glfw_window.window_focus_callback = self.on_focus
self.tabs = deque() self.tab_manager = TabManager(opts, args)
self.tabs.append(Tab(opts, args))
self.sprites = Sprites() self.sprites = Sprites()
self.cell_program = ShaderProgram(*cell_shader) self.cell_program = ShaderProgram(*cell_shader)
self.cursor_program = ShaderProgram(*cursor_shader) self.cursor_program = ShaderProgram(*cursor_shader)
@@ -119,7 +117,7 @@ class Boss(Thread):
glfw_post_empty_event() glfw_post_empty_event()
def __iter__(self): def __iter__(self):
yield from iter(self.tabs) return iter(self.tab_manager)
def iterwindows(self): def iterwindows(self):
for t in self: for t in self:
@@ -218,7 +216,7 @@ class Boss(Thread):
def apply_pending_resize(self, w, h): def apply_pending_resize(self, w, h):
viewport_size.width, viewport_size.height = w, h viewport_size.width, viewport_size.height = w, h
for tab in self.tabs: for tab in self.tab_manager:
tab.relayout() tab.relayout()
self.resize_gl_viewport = True self.resize_gl_viewport = True
self.pending_resize = False self.pending_resize = False
@@ -226,7 +224,7 @@ class Boss(Thread):
@property @property
def active_tab(self): def active_tab(self):
return self.tabs[0] if self.tabs else None return self.tab_manager.active_tab
def is_tab_visible(self, tab): def is_tab_visible(self, tab):
return self.active_tab is tab return self.active_tab is tab
@@ -387,16 +385,16 @@ class Boss(Thread):
if window.char_grid.buffer_id is not None: if window.char_grid.buffer_id is not None:
self.sprites.destroy_sprite_map(window.char_grid.buffer_id) self.sprites.destroy_sprite_map(window.char_grid.buffer_id)
window.char_grid.buffer_id = None window.char_grid.buffer_id = None
for tab in self.tabs: for tab in self.tab_manager:
if window in tab: if window in tab:
break break
else: else:
return return
tab.remove_window(window) tab.remove_window(window)
if len(tab) == 0: if len(tab) == 0:
self.tabs.remove(tab) self.tab_manager.remove(tab)
tab.destroy() tab.destroy()
if len(self.tabs) == 0: if len(self.tab_manager) == 0:
if not self.shutting_down: if not self.shutting_down:
self.glfw_window.set_should_close(True) self.glfw_window.set_should_close(True)
glfw_post_empty_event() glfw_post_empty_event()
@@ -408,9 +406,9 @@ class Boss(Thread):
self.shutting_down = True self.shutting_down = True
wakeup() wakeup()
self.join() self.join()
for t in self.tabs: for t in self.tab_manager:
t.destroy() t.destroy()
del self.tabs del self.tab_manager
self.sprites.destroy() self.sprites.destroy()
del self.sprites del self.sprites
del self.glfw_window del self.glfw_window

View File

@@ -8,7 +8,7 @@ from ctypes import addressof, memmove, sizeof
from threading import Lock from threading import Lock
from .config import build_ansi_color_table from .config import build_ansi_color_table
from .constants import tab_manager, viewport_size, cell_size, ScreenGeometry, GLuint from .constants import get_boss, viewport_size, cell_size, ScreenGeometry, GLuint
from .utils import get_logical_dpi, to_color, set_primary_selection, open_url from .utils import get_logical_dpi, to_color, set_primary_selection, open_url
from .fast_data_types import ( from .fast_data_types import (
glUniform2ui, glUniform4f, glUniform1i, glUniform2f, glDrawArraysInstanced, glUniform2ui, glUniform4f, glUniform1i, glUniform2f, glDrawArraysInstanced,
@@ -281,7 +281,7 @@ class CharGrid:
self.update_cell_data() self.update_cell_data()
def update_cell_data(self, force_full_refresh=False): def update_cell_data(self, force_full_refresh=False):
sprites = tab_manager().sprites sprites = get_boss().sprites
is_dirty = self.screen.is_dirty() is_dirty = self.screen.is_dirty()
with sprites.lock: with sprites.lock:
cursor_changed, history_line_added_count = self.screen.update_cell_data( cursor_changed, history_line_added_count = self.screen.update_cell_data(

View File

@@ -62,6 +62,8 @@ named_keys = {"'": 'APOSTROPHE', ',': 'COMMA', '-': 'MINUS', '.': 'PERIOD',
def parse_key(val, keymap): def parse_key(val, keymap):
sc, action = val.partition(' ')[::2] sc, action = val.partition(' ')[::2]
action = action.strip()
sc = sc.strip()
if not sc or not action: if not sc or not action:
return return
parts = sc.split('+') parts = sc.split('+')

View File

@@ -49,20 +49,20 @@ class ViewportSize:
return '(width={}, height={})'.format(self.width, self.height) return '(width={}, height={})'.format(self.width, self.height)
def tab_manager(): def get_boss():
return tab_manager.manager return get_boss.boss
def set_tab_manager(m): def set_boss(m):
tab_manager.manager = m get_boss.boss = m
def wakeup(): def wakeup():
os.write(tab_manager.manager.write_wakeup_fd, b'1') os.write(get_boss.boss.write_wakeup_fd, b'1')
def queue_action(func, *args): def queue_action(func, *args):
tab_manager.manager.queue_action(func, *args) get_boss.boss.queue_action(func, *args)
is_key_pressed = defaultdict(lambda: False) is_key_pressed = defaultdict(lambda: False)

View File

@@ -4,11 +4,11 @@
from itertools import islice from itertools import islice
from .constants import WindowGeometry, viewport_size, cell_size, tab_manager from .constants import WindowGeometry, viewport_size, cell_size, get_boss
def available_height(): def available_height():
return viewport_size.height - tab_manager().current_tab_bar_height return viewport_size.height - get_boss().current_tab_bar_height
def layout_dimension(length, cell_length, number_of_windows=1, border_length=0, left_align=False): def layout_dimension(length, cell_length, number_of_windows=1, border_length=0, left_align=False):

View File

@@ -5,7 +5,7 @@
from collections import deque from collections import deque
from .child import Child from .child import Child
from .constants import tab_manager, appname, shell_path from .constants import get_boss, appname, shell_path
from .fast_data_types import glfw_post_empty_event from .fast_data_types import glfw_post_empty_event
from .layout import all_layouts from .layout import all_layouts
from .borders import Borders from .borders import Borders
@@ -30,7 +30,7 @@ class Tab:
@property @property
def is_visible(self): def is_visible(self):
return tab_manager().is_tab_visible(self) return get_boss().is_tab_visible(self)
@property @property
def active_window(self): def active_window(self):
@@ -71,7 +71,7 @@ class Tab:
def new_window(self, use_shell=True): def new_window(self, use_shell=True):
child = self.launch_child(use_shell=use_shell) child = self.launch_child(use_shell=use_shell)
window = Window(self, child, self.opts, self.args) window = Window(self, child, self.opts, self.args)
tab_manager().add_child_fd(child.child_fd, window.read_ready, window.write_ready) get_boss().add_child_fd(child.child_fd, window.read_ready, window.write_ready)
self.active_window_idx = self.current_layout.add_window(self.windows, window, self.active_window_idx) self.active_window_idx = self.current_layout.add_window(self.windows, window, self.active_window_idx)
self.borders(self.windows, self.active_window, self.current_layout.needs_window_borders and len(self.windows) > 1) self.borders(self.windows, self.active_window, self.current_layout.needs_window_borders and len(self.windows) > 1)
glfw_post_empty_event() glfw_post_empty_event()
@@ -123,4 +123,26 @@ class Tab:
del self.windows del self.windows
def render(self): def render(self):
self.borders.render(tab_manager().borders_program) self.borders.render(get_boss().borders_program)
class TabManager:
def __init__(self, opts, args):
self.opts, self.args = opts, args
self.tabs = [Tab(opts, args)]
def __iter__(self):
return iter(self.tabs)
def __len__(self):
return len(self.tabs)
@property
def active_tab(self):
return self.tabs[0] if self.tabs else None
def remove(self, tab):
' Must be called in the GUI thread '
self.tabs.remove(tab)
tab.destroy()

View File

@@ -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, is_key_pressed, mouse_button_pressed, cell_size from .constants import wakeup, get_boss, appname, WindowGeometry, is_key_pressed, mouse_button_pressed, cell_size
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,
@@ -73,7 +73,7 @@ class Window:
return g.left <= x <= g.right and g.top <= y <= g.bottom return g.left <= x <= g.right and g.top <= y <= g.bottom
def close(self): def close(self):
tab_manager().close_window(self) get_boss().close_window(self)
def destroy(self): def destroy(self):
self.destroyed = True self.destroyed = True
@@ -201,8 +201,8 @@ class Window:
is_key_pressed[GLFW_KEY_LEFT_SHIFT] or 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 self.last_mouse_cursor_pos = x, y
tm = tab_manager() tm = get_boss()
tm.queue_ui_action(tab_manager().change_mouse_cursor, self.char_grid.has_url_at(x, y)) tm.queue_ui_action(get_boss().change_mouse_cursor, self.char_grid.has_url_at(x, y))
if send_event: if send_event:
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:
@@ -215,11 +215,11 @@ class Window:
self.char_grid.update_drag(None, x, y) self.char_grid.update_drag(None, x, y)
margin = cell_size.height // 2 margin = cell_size.height // 2
if y <= margin or y >= self.geometry.bottom - margin: if y <= margin or y >= self.geometry.bottom - margin:
tab_manager().timers.add(0.02, self.drag_scroll) get_boss().timers.add(0.02, self.drag_scroll)
def drag_scroll(self): def drag_scroll(self):
x, y = self.last_mouse_cursor_pos x, y = self.last_mouse_cursor_pos
tm = tab_manager() tm = get_boss()
margin = cell_size.height // 2 margin = cell_size.height // 2
if y <= margin or y >= self.geometry.bottom - margin: if y <= margin or y >= self.geometry.bottom - margin:
self.scroll_line_up() if y < 50 else self.scroll_line_down() self.scroll_line_up() if y < 50 else self.scroll_line_down()
@@ -272,7 +272,7 @@ class Window:
def copy_to_clipboard(self): def copy_to_clipboard(self):
text = self.char_grid.text_for_selection() text = self.char_grid.text_for_selection()
if text: if text:
tm = tab_manager() tm = get_boss()
tm.queue_ui_action(tm.glfw_window.set_clipboard_string, text) tm.queue_ui_action(tm.glfw_window.set_clipboard_string, text)
def scroll_line_up(self): def scroll_line_up(self):