diff --git a/kitty/boss.py b/kitty/boss.py index 7c54b96d3..b9d637a56 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -79,6 +79,11 @@ class Boss: tm = TabManager(os_window_id, self.opts, self.args, startup_session) self.os_window_map[os_window_id] = tm + def new_os_window(self, *args): + sw = self.args_to_special_window(args) if args else None + startup_session = create_session(self.opts, special_window=sw) + self.add_os_window(startup_session) + def add_child(self, window): self.child_monitor.add_child(window.id, window.child.pid, window.child.child_fd, window.screen) self.window_id_map[window.id] = window diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 56f34ea48..06ec4c635 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -555,6 +555,7 @@ render(double now) { for (size_t i = 0; i < global_state.num_os_windows; i++) { OSWindow *w = global_state.os_windows + i; if (!w->num_tabs || !should_os_window_be_rendered(w)) continue; + make_os_window_context_current(w); if (w->viewport_size_dirty) { update_surface_size(w->viewport_width, w->viewport_height); w->viewport_size_dirty = false; diff --git a/kitty/gl.h b/kitty/gl.h index 43d6202b7..2fbc8bee8 100644 --- a/kitty/gl.h +++ b/kitty/gl.h @@ -44,18 +44,23 @@ check_for_gl_error(const char *name, void UNUSED *funcptr, int UNUSED len_args, } } +static bool glad_loaded = false; + void gl_init() { - if (!init_glad((GLADloadproc) glfwGetProcAddress, global_state.debug_gl)) { - fatal("Loading the OpenGL library failed"); - } - glad_set_post_callback(check_for_gl_error); + if (!glad_loaded) { + if (!init_glad((GLADloadproc) glfwGetProcAddress, global_state.debug_gl)) { + fatal("Loading the OpenGL library failed"); + } + glad_set_post_callback(check_for_gl_error); #define ARB_TEST(name) \ - if (!GLAD_GL_ARB_##name) { \ - fatal("The OpenGL driver on this system is missing the required extension: ARB_%s", #name); \ - } - ARB_TEST(texture_storage); + if (!GLAD_GL_ARB_##name) { \ + fatal("The OpenGL driver on this system is missing the required extension: ARB_%s", #name); \ + } + ARB_TEST(texture_storage); #undef ARB_TEST + glad_loaded = true; + } glEnable(GL_BLEND); } diff --git a/kitty/glfw.c b/kitty/glfw.c index 446d1c810..afbdb4851 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -202,6 +202,16 @@ set_default_window_icon(PyObject UNUSED *self, PyObject *args) { Py_RETURN_NONE; } +static GLFWwindow *current_os_window_ctx = NULL; + +void +make_os_window_context_current(OSWindow *w) { + if (w->handle != current_os_window_ctx) { + current_os_window_ctx = w->handle; + glfwMakeContextCurrent(w->handle); + } +} + static PyObject* create_os_window(PyObject UNUSED *self, PyObject *args) { int width, height; @@ -240,10 +250,11 @@ create_os_window(PyObject UNUSED *self, PyObject *args) { glfw_window = glfwCreateWindow(640, 400, title, NULL, global_state.num_os_windows ? global_state.os_windows[0].handle : NULL); } if (glfw_window == NULL) { PyErr_SetString(PyExc_ValueError, "Failed to create GLFWwindow"); return NULL; } + glfwMakeContextCurrent(glfw_window); + current_os_window_ctx = glfw_window; + glfwSwapInterval(0); // a value of 1 makes mouse selection laggy + gl_init(); if (is_first_window) { - glfwMakeContextCurrent(glfw_window); - gl_init(); - glfwSwapInterval(0); // a value of 1 makes mouse selection laggy PyObject *ret = PyObject_CallFunction(load_programs, NULL); if (ret == NULL) return NULL; Py_DECREF(ret); diff --git a/kitty/kitty.conf b/kitty/kitty.conf index b03db6b4e..a8aec53fa 100644 --- a/kitty/kitty.conf +++ b/kitty/kitty.conf @@ -244,7 +244,8 @@ map ctrl+shift+h show_scrollback # Window management map ctrl+shift+enter new_window -map ctrl+shift+w close_window +map ctrl+shift+n new_os_window +map ctrl+shift+m close_window map ctrl+shift+] next_window map ctrl+shift+[ previous_window map ctrl+shift+f move_window_forward diff --git a/kitty/session.py b/kitty/session.py index 96df6254e..aa8249a93 100644 --- a/kitty/session.py +++ b/kitty/session.py @@ -43,6 +43,9 @@ class Session: cmd = None self.tabs[-1].windows.append(cmd) + def add_special_window(self, sw): + self.tabs[-1].windows.append(sw) + def focus(self): self.active_tab_idx = max(0, len(self.tabs) - 1) self.tabs[-1].active_window_idx = max(0, len(self.tabs[-1].windows) - 1) @@ -82,12 +85,12 @@ def parse_session(raw, opts): return ans -def create_session(opts, args): - if args.session: +def create_session(opts, args=None, special_window=None): + if args and args.session: with open(args.session) as f: return parse_session(f.read(), opts) ans = Session() - if args.window_layout: + if args and args.window_layout: if args.window_layout not in opts.enabled_layouts: opts.enabled_layouts.insert(0, args.window_layout) current_layout = args.window_layout @@ -95,6 +98,9 @@ def create_session(opts, args): current_layout = opts.enabled_layouts[0] if opts.enabled_layouts else 'tall' ans.add_tab(opts) ans.tabs[-1].layout = current_layout - cmd = args.args or [shell_path] - ans.add_window(cmd) + if special_window is None: + cmd = args.args if args and args.args else [shell_path] + ans.add_window(cmd) + else: + ans.add_special_window(special_window) return ans diff --git a/kitty/state.h b/kitty/state.h index 7a8aefedb..0b036db0e 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -133,6 +133,7 @@ extern GlobalState global_state; void gl_init(); void remove_vao(ssize_t vao_idx); bool remove_os_window(id_type os_window_id); +void make_os_window_context_current(OSWindow *w); void remove_os_window_reference(OSWindow *w); void mark_os_window_for_close(OSWindow* w, bool yes); void update_os_window_viewport(OSWindow *window, bool); diff --git a/kitty/tabs.py b/kitty/tabs.py index cab29f04e..49efd56b0 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -20,10 +20,11 @@ from .utils import color_as_int from .window import Window, calculate_gl_geometry TabbarData = namedtuple('TabbarData', 'title is_active is_last') +SpecialWindowInstance = namedtuple('SpecialWindow', 'cmd stdin override_title') def SpecialWindow(cmd, stdin=None, override_title=None): - return (cmd, stdin, override_title) + return SpecialWindowInstance(cmd, stdin, override_title) class Tab: # {{{ @@ -58,7 +59,10 @@ class Tab: # {{{ def startup(self, session_tab): for cmd in session_tab.windows: - self.new_window(cmd=cmd) + if isinstance(cmd, (SpecialWindowInstance,)): + self.new_special_window(cmd) + else: + self.new_window(cmd=cmd) self.set_active_window_idx(session_tab.active_window_idx) @property