From c8aee8c8814cc200c7c9b9d52d00ac4618a04011 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 14 Dec 2017 21:02:21 +0530 Subject: [PATCH] Automatically adjust cell height when DPI changes DPI changes are detected as a change in the ration of the window size to the framebuffer size. I dont know how reliable that is. Possiblly Fix #77 --- kitty/boss.py | 29 +++++++++++++++++++++-------- kitty/glfw.c | 10 ++++++---- kitty/state.c | 10 ++++++++++ kitty/state.h | 1 + 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/kitty/boss.py b/kitty/boss.py index b1eedaed5..d96eeb62d 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -11,8 +11,8 @@ from .constants import appname, set_boss, wakeup from .fast_data_types import ( ChildMonitor, create_os_window, current_os_window, destroy_global_data, destroy_sprite_map, get_clipboard_string, glfw_post_empty_event, - layout_sprite_map, mark_os_window_for_close, show_window, - toggle_fullscreen, viewport_for_window + layout_sprite_map, mark_os_window_for_close, set_dpi_from_os_window, + show_window, toggle_fullscreen, viewport_for_window ) from .fonts.render import prerender, resize_fonts, set_font_family from .keys import get_shortcut @@ -162,10 +162,16 @@ class Boss: if tm is not None: tm.activate_tab_at(x) - def on_window_resize(self, os_window_id, w, h): + def on_window_resize(self, os_window_id, w, h, dpi_changed): tm = self.os_window_map.get(os_window_id) if tm is not None: - tm.resize() + if dpi_changed: + if set_dpi_from_os_window(os_window_id): + self.on_dpi_change(os_window_id) + else: + tm.resize() + else: + tm.resize() def increase_font_size(self): self.change_font_size( @@ -182,10 +188,9 @@ class Boss: def restore_font_size(self): self.change_font_size(self.opts.font_size) - def change_font_size(self, new_size): - if new_size == self.current_font_size: - return - self.current_font_size = new_size + def _change_font_size(self, new_size=None): + if new_size is not None: + self.current_font_size = new_size old_cell_width, old_cell_height = viewport_for_window()[-2:] windows = tuple(filter(None, self.window_id_map.values())) resize_fonts(self.current_font_size) @@ -199,6 +204,14 @@ class Boss: tm.refresh_sprite_positions() glfw_post_empty_event() + def change_font_size(self, new_size): + if new_size == self.current_font_size: + return + self._change_font_size(new_size) + + def on_dpi_change(self, os_window_id): + self._change_font_size() + @property def active_tab_manager(self): os_window_id = current_os_window() diff --git a/kitty/glfw.c b/kitty/glfw.c index fc407c451..c54f58dd7 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -21,12 +21,14 @@ update_os_window_viewport(OSWindow *window, bool notify_boss) { int w, h; glfwGetFramebufferSize(window->handle, &window->viewport_width, &window->viewport_height); glfwGetWindowSize(window->handle, &w, &h); + double xr = window->viewport_x_ratio, yr = window->viewport_y_ratio; window->viewport_x_ratio = (double)window->viewport_width / (double)w; window->viewport_y_ratio = (double)window->viewport_height / (double)h; + bool dpi_changed = (xr != 0.0 && xr != window->viewport_x_ratio) || (yr != 0.0 && yr != window->viewport_y_ratio); window->viewport_size_dirty = true; window->has_pending_resizes = false; if (notify_boss) { - call_boss(on_window_resize, "Kii", window->id, window->viewport_width, window->viewport_height); + call_boss(on_window_resize, "KiiO", window->id, window->viewport_width, window->viewport_height, dpi_changed ? Py_True : Py_False); } window->last_resize_at = monotonic(); } @@ -246,8 +248,8 @@ current_monitor(GLFWwindow *window) { } -static inline void -set_dpi_from_window(OSWindow *w) { +void +set_dpi_from_os_window(OSWindow *w) { GLFWmonitor *monitor = NULL; if (w) { monitor = current_monitor(w->handle); } if (monitor == NULL) monitor = glfwGetPrimaryMonitor(); @@ -315,7 +317,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args) { current_os_window_ctx = glfw_window; glfwSwapInterval(swap_interval); // a value of 1 makes mouse selection laggy if (is_first_window) { - set_dpi_from_window(NULL); + set_dpi_from_os_window(NULL); gl_init(); PyObject *ret = PyObject_CallFunction(load_programs, "i", glfwGetWindowAttrib(glfw_window, GLFW_TRANSPARENT_FRAMEBUFFER)); if (ret == NULL) return NULL; diff --git a/kitty/state.c b/kitty/state.c index a16575eb1..52d272ae6 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -373,6 +373,15 @@ PYWRAP1(viewport_for_window) { return Py_BuildValue("iiII", 400, 400, global_state.cell_width, global_state.cell_height); } +PYWRAP1(set_dpi_from_os_window) { + id_type os_window_id = PyLong_AsUnsignedLongLong(args); + WITH_OS_WINDOW(os_window_id) + set_dpi_from_os_window(os_window); + Py_RETURN_TRUE; + END_WITH_OS_WINDOW + Py_RETURN_FALSE; +} + PYWRAP1(mark_os_window_for_close) { id_type os_window_id; int yes = 1; @@ -476,6 +485,7 @@ static PyMethodDef module_methods[] = { MW(set_logical_dpi, METH_VARARGS), MW(pt_to_px, METH_O), MW(pt_to_px_ceil, METH_O), + MW(set_dpi_from_os_window, METH_O), MW(add_tab, METH_O), MW(add_window, METH_VARARGS), MW(update_window_title, METH_VARARGS), diff --git a/kitty/state.h b/kitty/state.h index 175971f02..d222128ef 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -146,6 +146,7 @@ void mark_os_window_for_close(OSWindow* w, bool yes); void update_os_window_viewport(OSWindow *window, bool); bool should_os_window_close(OSWindow* w); bool should_os_window_be_rendered(OSWindow* w); +void set_dpi_from_os_window(OSWindow *w); void wakeup_main_loop(); void event_loop_wait(double timeout); void swap_window_buffers(OSWindow *w);