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

View File

@ -8,7 +8,7 @@ from ctypes import addressof, memmove, sizeof
from threading import Lock
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 .fast_data_types import (
glUniform2ui, glUniform4f, glUniform1i, glUniform2f, glDrawArraysInstanced,
@ -281,7 +281,7 @@ class CharGrid:
self.update_cell_data()
def update_cell_data(self, force_full_refresh=False):
sprites = tab_manager().sprites
sprites = get_boss().sprites
is_dirty = self.screen.is_dirty()
with sprites.lock:
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):
sc, action = val.partition(' ')[::2]
action = action.strip()
sc = sc.strip()
if not sc or not action:
return
parts = sc.split('+')

View File

@ -49,20 +49,20 @@ class ViewportSize:
return '(width={}, height={})'.format(self.width, self.height)
def tab_manager():
return tab_manager.manager
def get_boss():
return get_boss.boss
def set_tab_manager(m):
tab_manager.manager = m
def set_boss(m):
get_boss.boss = m
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):
tab_manager.manager.queue_action(func, *args)
get_boss.boss.queue_action(func, *args)
is_key_pressed = defaultdict(lambda: False)

View File

@ -4,11 +4,11 @@
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():
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):

View File

@ -5,7 +5,7 @@
from collections import deque
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 .layout import all_layouts
from .borders import Borders
@ -30,7 +30,7 @@ class Tab:
@property
def is_visible(self):
return tab_manager().is_tab_visible(self)
return get_boss().is_tab_visible(self)
@property
def active_window(self):
@ -71,7 +71,7 @@ class Tab:
def new_window(self, use_shell=True):
child = self.launch_child(use_shell=use_shell)
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.borders(self.windows, self.active_window, self.current_layout.needs_window_borders and len(self.windows) > 1)
glfw_post_empty_event()
@ -123,4 +123,26 @@ class Tab:
del self.windows
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 .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 (
BRACKETED_PASTE_START, BRACKETED_PASTE_END, Screen, read_bytes_dump,
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
def close(self):
tab_manager().close_window(self)
get_boss().close_window(self)
def destroy(self):
self.destroyed = True
@ -201,8 +201,8 @@ class Window:
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
tm = tab_manager()
tm.queue_ui_action(tab_manager().change_mouse_cursor, self.char_grid.has_url_at(x, y))
tm = get_boss()
tm.queue_ui_action(get_boss().change_mouse_cursor, self.char_grid.has_url_at(x, y))
if send_event:
x, y = self.char_grid.cell_for_pos(x, y)
if x is not None:
@ -215,11 +215,11 @@ class Window:
self.char_grid.update_drag(None, x, y)
margin = cell_size.height // 2
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):
x, y = self.last_mouse_cursor_pos
tm = tab_manager()
tm = get_boss()
margin = cell_size.height // 2
if y <= margin or y >= self.geometry.bottom - margin:
self.scroll_line_up() if y < 50 else self.scroll_line_down()
@ -272,7 +272,7 @@ class Window:
def copy_to_clipboard(self):
text = self.char_grid.text_for_selection()
if text:
tm = tab_manager()
tm = get_boss()
tm.queue_ui_action(tm.glfw_window.set_clipboard_string, text)
def scroll_line_up(self):