mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-11 14:45:31 +03:00
Implement resizing of individual windows in a layout
See the Layouts section in the README for details. Fixes #362 Note that it is only implemented for the Tall layout currently. Other layouts to follow. The implementation might also be refined in the future.
This commit is contained in:
parent
e429b8484c
commit
e053d1f566
@ -48,6 +48,7 @@
|
|||||||
:sc_seventh_window: pass:quotes[`ctrl+shift+7`]
|
:sc_seventh_window: pass:quotes[`ctrl+shift+7`]
|
||||||
:sc_show_scrollback: pass:quotes[`ctrl+shift+h`]
|
:sc_show_scrollback: pass:quotes[`ctrl+shift+h`]
|
||||||
:sc_sixth_window: pass:quotes[`ctrl+shift+6`]
|
:sc_sixth_window: pass:quotes[`ctrl+shift+6`]
|
||||||
|
:sc_start_resizing_window: pass:quotes[`ctrl+shift+r`]
|
||||||
:sc_tenth_window: pass:quotes[`ctrl+shift+0`]
|
:sc_tenth_window: pass:quotes[`ctrl+shift+0`]
|
||||||
:sc_third_window: pass:quotes[`ctrl+shift+3`]
|
:sc_third_window: pass:quotes[`ctrl+shift+3`]
|
||||||
:sc_toggle_fullscreen: pass:quotes[`ctrl+shift+f11`]
|
:sc_toggle_fullscreen: pass:quotes[`ctrl+shift+f11`]
|
||||||
@ -343,6 +344,15 @@ You can switch between layouts using the {sc_next_layout} key combination. You c
|
|||||||
also create shortcuts to select particular layouts, and choose which layouts
|
also create shortcuts to select particular layouts, and choose which layouts
|
||||||
you want to enable/disable, see link:kitty/kitty.conf[kitty.conf] for examples.
|
you want to enable/disable, see link:kitty/kitty.conf[kitty.conf] for examples.
|
||||||
|
|
||||||
|
You can resize windows inside layouts. Press {sc_start_resizing_window} to
|
||||||
|
enter resizing mode. Then use the `W/N` (Wider/Narrower) and `T/S`
|
||||||
|
(Taller/Shorter) keys to change the window size. Press the `0` key to rest the
|
||||||
|
layout to default sizes. Any other key will exit resize mode. In a given
|
||||||
|
window layout only some operations may be possible for a particular window. For
|
||||||
|
example, in the Tall layout you can make the first window wider/narrower, but
|
||||||
|
not taller/shorter. Note that what you are resizing is actually not a window,
|
||||||
|
but a row/column in the layout, all windows in that row/column will be resized.
|
||||||
|
|
||||||
Some layouts take options to control their behavior. For example, the `fat` and `tall`
|
Some layouts take options to control their behavior. For example, the `fat` and `tall`
|
||||||
layouts accept the `bias` option to control how the available space is split up. To specify the
|
layouts accept the `bias` option to control how the available space is split up. To specify the
|
||||||
option, in kitty.conf use:
|
option, in kitty.conf use:
|
||||||
@ -351,7 +361,7 @@ option, in kitty.conf use:
|
|||||||
enabled_layouts tall:bias=70
|
enabled_layouts tall:bias=70
|
||||||
```
|
```
|
||||||
|
|
||||||
this will make the tall window occupy `70%` of available width. `bias` can be
|
This will make the tall window occupy `70%` of available width. `bias` can be
|
||||||
any number between 10 and 90.
|
any number between 10 and 90.
|
||||||
|
|
||||||
Writing a new layout only requires about fifty lines of code, so if there is
|
Writing a new layout only requires about fifty lines of code, so if there is
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
appname, config_dir, editor, set_boss, supports_primary_selection
|
appname, config_dir, editor, set_boss, supports_primary_selection
|
||||||
)
|
)
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
ChildMonitor, create_os_window, current_os_window, destroy_global_data,
|
GLFW_KEY_0, GLFW_KEY_W, GLFW_KEY_N, GLFW_KEY_S, ChildMonitor,
|
||||||
|
create_os_window, current_os_window, destroy_global_data,
|
||||||
destroy_sprite_map, get_clipboard_string, glfw_post_empty_event,
|
destroy_sprite_map, get_clipboard_string, glfw_post_empty_event,
|
||||||
layout_sprite_map, mark_os_window_for_close, set_clipboard_string,
|
layout_sprite_map, mark_os_window_for_close, set_clipboard_string,
|
||||||
set_dpi_from_os_window, set_in_sequence_mode, show_window,
|
set_dpi_from_os_window, set_in_sequence_mode, show_window,
|
||||||
@ -413,6 +414,22 @@ def process_sequence(self, key, scancode, action, mods):
|
|||||||
if matched_action is not None:
|
if matched_action is not None:
|
||||||
self.dispatch_action(matched_action)
|
self.dispatch_action(matched_action)
|
||||||
|
|
||||||
|
def handle_resize_keypress(self, key, mods, os_window_id, tab_id, window_id):
|
||||||
|
tm = self.os_window_map.get(os_window_id)
|
||||||
|
if tm is None:
|
||||||
|
return
|
||||||
|
tab = tm.tab_for_id(tab_id)
|
||||||
|
if tab is None:
|
||||||
|
return
|
||||||
|
if key == GLFW_KEY_0:
|
||||||
|
tab.reset_window_sizes()
|
||||||
|
return
|
||||||
|
is_horizontal = key in (GLFW_KEY_W, GLFW_KEY_N)
|
||||||
|
increment = 0.05
|
||||||
|
if key in (GLFW_KEY_N, GLFW_KEY_S):
|
||||||
|
increment *= -1
|
||||||
|
tab.resize_window_by(window_id, increment, is_horizontal)
|
||||||
|
|
||||||
def default_bg_changed_for(self, window_id):
|
def default_bg_changed_for(self, window_id):
|
||||||
w = self.window_id_map.get(window_id)
|
w = self.window_id_map.get(window_id)
|
||||||
if w is not None:
|
if w is not None:
|
||||||
|
11
kitty/glfw.c
11
kitty/glfw.c
@ -765,6 +765,16 @@ os_window_swap_buffers(PyObject UNUSED *self, PyObject *args) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
ring_bell(PyObject UNUSED *self, PyObject *args) {
|
||||||
|
id_type os_window_id;
|
||||||
|
if (!PyArg_ParseTuple(args, "K", &os_window_id)) return NULL;
|
||||||
|
OSWindow *w = os_window_for_kitty_window(os_window_id);
|
||||||
|
if (w && w->handle) {
|
||||||
|
glfwWindowBell(w->handle);
|
||||||
|
}
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
// Boilerplate {{{
|
// Boilerplate {{{
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
@ -778,6 +788,7 @@ static PyMethodDef module_methods[] = {
|
|||||||
METHODB(glfw_window_hint, METH_VARARGS),
|
METHODB(glfw_window_hint, METH_VARARGS),
|
||||||
METHODB(os_window_should_close, METH_VARARGS),
|
METHODB(os_window_should_close, METH_VARARGS),
|
||||||
METHODB(os_window_swap_buffers, METH_VARARGS),
|
METHODB(os_window_swap_buffers, METH_VARARGS),
|
||||||
|
METHODB(ring_bell, METH_VARARGS),
|
||||||
METHODB(get_primary_selection, METH_NOARGS),
|
METHODB(get_primary_selection, METH_NOARGS),
|
||||||
METHODB(x11_display, METH_NOARGS),
|
METHODB(x11_display, METH_NOARGS),
|
||||||
METHODB(x11_window_id, METH_O),
|
METHODB(x11_window_id, METH_O),
|
||||||
|
14
kitty/keys.c
14
kitty/keys.c
@ -81,10 +81,24 @@ is_ascii_control_char(char c) {
|
|||||||
return c == 0 || (1 <= c && c <= 31) || c == 127;
|
return c == 0 || (1 <= c && c <= 31) || c == 127;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
handle_resize_key(int key, int action, int mods) {
|
||||||
|
if (action == GLFW_RELEASE) return true;
|
||||||
|
if (key == GLFW_KEY_T || key == GLFW_KEY_S || key == GLFW_KEY_W || key == GLFW_KEY_N || key == GLFW_KEY_0) {
|
||||||
|
call_boss(handle_resize_keypress, "iiKKK", key, mods, global_state.currently_resizing.os_window_id, global_state.currently_resizing.tab_id, global_state.currently_resizing.window_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
on_key_input(int key, int scancode, int action, int mods, const char* text, int state UNUSED) {
|
on_key_input(int key, int scancode, int action, int mods, const char* text, int state UNUSED) {
|
||||||
Window *w = active_window();
|
Window *w = active_window();
|
||||||
if (!w) return;
|
if (!w) return;
|
||||||
|
if (global_state.currently_resizing.os_window_id) {
|
||||||
|
if (handle_resize_key(key, action, mods)) return;
|
||||||
|
terminate_resize_mode();
|
||||||
|
}
|
||||||
if (global_state.in_sequence_mode) {
|
if (global_state.in_sequence_mode) {
|
||||||
if (
|
if (
|
||||||
action != GLFW_RELEASE &&
|
action != GLFW_RELEASE &&
|
||||||
|
@ -395,6 +395,8 @@ map kitty_mod+[ previous_window
|
|||||||
map kitty_mod+f move_window_forward
|
map kitty_mod+f move_window_forward
|
||||||
map kitty_mod+b move_window_backward
|
map kitty_mod+b move_window_backward
|
||||||
map kitty_mod+` move_window_to_top
|
map kitty_mod+` move_window_to_top
|
||||||
|
map kitty_mod+r start_resizing_window
|
||||||
|
# Switching to a particular window
|
||||||
map kitty_mod+1 first_window
|
map kitty_mod+1 first_window
|
||||||
map kitty_mod+2 second_window
|
map kitty_mod+2 second_window
|
||||||
map kitty_mod+3 third_window
|
map kitty_mod+3 third_window
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from itertools import islice
|
from itertools import islice, repeat
|
||||||
|
|
||||||
from .constants import WindowGeometry
|
from .constants import WindowGeometry
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
@ -42,8 +42,15 @@ def calc_window_length(cells_in_window):
|
|||||||
inner_length = cells_in_window * cell_length
|
inner_length = cells_in_window * cell_length
|
||||||
return 2 * (border_length + margin_length) + inner_length
|
return 2 * (border_length + margin_length) + inner_length
|
||||||
|
|
||||||
if bias is not None and number_of_windows > 1 and len(bias) == number_of_windows:
|
if bias is not None and number_of_windows > 1 and len(bias) == number_of_windows and cells_per_window > 5:
|
||||||
cells_map = [int(b * number_of_cells) for b in bias]
|
cells_map = [int(b * number_of_cells) for b in bias]
|
||||||
|
while min(cells_map) < 5:
|
||||||
|
maxi, mini = map(cells_map.index, (max(cells_map), min(cells_map)))
|
||||||
|
if maxi == mini:
|
||||||
|
break
|
||||||
|
cells_map[mini] += 1
|
||||||
|
cells_map[maxi] -= 1
|
||||||
|
|
||||||
extra = number_of_cells - sum(cells_map)
|
extra = number_of_cells - sum(cells_map)
|
||||||
if extra:
|
if extra:
|
||||||
cells_map[-1] += extra
|
cells_map[-1] += extra
|
||||||
@ -90,6 +97,28 @@ def __init__(self, os_window_id, tab_id, margin_width, padding_width, border_wid
|
|||||||
self.blank_rects = ()
|
self.blank_rects = ()
|
||||||
self.layout_opts = self.parse_layout_opts(layout_opts)
|
self.layout_opts = self.parse_layout_opts(layout_opts)
|
||||||
self.full_name = self.name + ((':' + layout_opts) if layout_opts else '')
|
self.full_name = self.name + ((':' + layout_opts) if layout_opts else '')
|
||||||
|
self.initialize_sub_class()
|
||||||
|
|
||||||
|
def initialize_sub_class(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def apply_bias(self, idx, increment, num_windows, is_horizontal):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def remove_all_biases(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def modify_size_of_window(self, all_windows, window_id, increment, is_horizontal=True):
|
||||||
|
idx = idx_for_id(window_id, all_windows)
|
||||||
|
if idx is None:
|
||||||
|
return
|
||||||
|
w = all_windows[idx]
|
||||||
|
windows = process_overlaid_windows(all_windows)[1]
|
||||||
|
idx = idx_for_id(w.id, windows)
|
||||||
|
if idx is None:
|
||||||
|
idx = idx_for_id(w.overlay_window_id, windows)
|
||||||
|
if idx is not None:
|
||||||
|
return self.apply_bias(idx, increment, len(windows), is_horizontal)
|
||||||
|
|
||||||
def parse_layout_opts(self, layout_opts):
|
def parse_layout_opts(self, layout_opts):
|
||||||
if not layout_opts:
|
if not layout_opts:
|
||||||
@ -307,10 +336,59 @@ def do_layout(self, windows, active_window_idx):
|
|||||||
self.blank_rects = blank_rects_for_window(w)
|
self.blank_rects = blank_rects_for_window(w)
|
||||||
|
|
||||||
|
|
||||||
|
def safe_increment_bias(old_val, increment):
|
||||||
|
return max(0.1, min(old_val + increment, 0.9))
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_biases(biases):
|
||||||
|
s = sum(biases)
|
||||||
|
if s == 1:
|
||||||
|
return biases
|
||||||
|
return [x/s for x in biases]
|
||||||
|
|
||||||
|
|
||||||
|
def distribute_indexed_bias(base_bias, index_bias_map):
|
||||||
|
if not index_bias_map:
|
||||||
|
return base_bias
|
||||||
|
ans = list(base_bias)
|
||||||
|
limit = len(ans)
|
||||||
|
for row, increment in index_bias_map.items():
|
||||||
|
if row >= limit or not increment:
|
||||||
|
continue
|
||||||
|
other_increment = -increment / (limit - 1)
|
||||||
|
ans = [safe_increment_bias(b, increment if i == row else other_increment) for i, b in enumerate(ans)]
|
||||||
|
return normalize_biases(ans)
|
||||||
|
|
||||||
|
|
||||||
class Tall(Layout):
|
class Tall(Layout):
|
||||||
|
|
||||||
name = 'tall'
|
name = 'tall'
|
||||||
|
|
||||||
|
def initialize_sub_class(self):
|
||||||
|
self.remove_all_biases()
|
||||||
|
|
||||||
|
def remove_all_biases(self):
|
||||||
|
self.x_bias = list(self.layout_opts['bias'])
|
||||||
|
self.biased_rows = {}
|
||||||
|
return True
|
||||||
|
|
||||||
|
def apply_bias(self, idx, increment, num_windows, is_horizontal):
|
||||||
|
if is_horizontal:
|
||||||
|
before = self.x_bias
|
||||||
|
if idx == 0:
|
||||||
|
self.x_bias = [safe_increment_bias(self.x_bias[0], increment), safe_increment_bias(self.x_bias[1], -increment)]
|
||||||
|
else:
|
||||||
|
self.x_bias = [safe_increment_bias(self.x_bias[0], -increment), safe_increment_bias(self.x_bias[1], increment)]
|
||||||
|
self.x_bias = normalize_biases(self.x_bias)
|
||||||
|
after = self.x_bias
|
||||||
|
else:
|
||||||
|
if idx == 0:
|
||||||
|
return False
|
||||||
|
idx -= 1
|
||||||
|
before = self.biased_rows.get(idx, 0)
|
||||||
|
self.biased_rows[idx] = after = before + increment
|
||||||
|
return before != after
|
||||||
|
|
||||||
def parse_layout_opts(self, layout_opts):
|
def parse_layout_opts(self, layout_opts):
|
||||||
ans = Layout.parse_layout_opts(self, layout_opts)
|
ans = Layout.parse_layout_opts(self, layout_opts)
|
||||||
try:
|
try:
|
||||||
@ -328,12 +406,16 @@ def do_layout(self, windows, active_window_idx):
|
|||||||
windows[0].set_geometry(0, wg)
|
windows[0].set_geometry(0, wg)
|
||||||
self.blank_rects = blank_rects_for_window(windows[0])
|
self.blank_rects = blank_rects_for_window(windows[0])
|
||||||
return
|
return
|
||||||
xlayout = self.xlayout(2, bias=self.layout_opts['bias'])
|
xlayout = self.xlayout(2, bias=self.x_bias)
|
||||||
xstart, xnum = next(xlayout)
|
xstart, xnum = next(xlayout)
|
||||||
ystart, ynum = next(self.ylayout(1))
|
ystart, ynum = next(self.ylayout(1))
|
||||||
windows[0].set_geometry(0, window_geometry(xstart, xnum, ystart, ynum))
|
windows[0].set_geometry(0, window_geometry(xstart, xnum, ystart, ynum))
|
||||||
xstart, xnum = next(xlayout)
|
xstart, xnum = next(xlayout)
|
||||||
ylayout = self.ylayout(len(windows) - 1)
|
if len(windows) > 2:
|
||||||
|
y_bias = distribute_indexed_bias(list(repeat(1/(len(windows) - 1), len(windows) - 1)), self.biased_rows)
|
||||||
|
else:
|
||||||
|
y_bias = None
|
||||||
|
ylayout = self.ylayout(len(windows) - 1, bias=y_bias)
|
||||||
for i, (w, (ystart, ynum)) in enumerate(zip(islice(windows, 1, None), ylayout)):
|
for i, (w, (ystart, ynum)) in enumerate(zip(islice(windows, 1, None), ylayout)):
|
||||||
w.set_geometry(i + 1, window_geometry(xstart, xnum, ystart, ynum))
|
w.set_geometry(i + 1, window_geometry(xstart, xnum, ystart, ynum))
|
||||||
# right bottom blank rect
|
# right bottom blank rect
|
||||||
|
@ -303,6 +303,7 @@ open_url(Window *w) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HANDLER(handle_button_event) {
|
HANDLER(handle_button_event) {
|
||||||
|
if (global_state.currently_resizing.os_window_id) { terminate_resize_mode(); }
|
||||||
Tab *t = global_state.callback_os_window->tabs + global_state.callback_os_window->active_tab;
|
Tab *t = global_state.callback_os_window->tabs + global_state.callback_os_window->active_tab;
|
||||||
bool is_release = !global_state.callback_os_window->mouse_button_pressed[button];
|
bool is_release = !global_state.callback_os_window->mouse_button_pressed[button];
|
||||||
if (window_idx != t->active_window) {
|
if (window_idx != t->active_window) {
|
||||||
|
@ -268,6 +268,14 @@ os_window_regions(OSWindow *os_window, Region *central, Region *tab_bar) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
terminate_resize_mode() {
|
||||||
|
global_state.currently_resizing.os_window_id = 0;
|
||||||
|
global_state.currently_resizing.tab_id = 0;
|
||||||
|
global_state.currently_resizing.window_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Python API {{{
|
// Python API {{{
|
||||||
#define PYWRAP0(name) static PyObject* py##name(PYNOARG)
|
#define PYWRAP0(name) static PyObject* py##name(PYNOARG)
|
||||||
@ -586,6 +594,14 @@ PYWRAP1(set_display_state) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PYWRAP1(enter_resize_mode) {
|
||||||
|
global_state.currently_resizing.os_window_id = 0;
|
||||||
|
global_state.currently_resizing.tab_id = 0;
|
||||||
|
global_state.currently_resizing.window_id = 0;
|
||||||
|
PA("|KKK", &global_state.currently_resizing.os_window_id, &global_state.currently_resizing.tab_id, &global_state.currently_resizing.window_id);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
THREE_ID_OBJ(update_window_title)
|
THREE_ID_OBJ(update_window_title)
|
||||||
THREE_ID(remove_window)
|
THREE_ID(remove_window)
|
||||||
PYWRAP1(resolve_key_mods) { int mods; PA("ii", &kitty_mod, &mods); return PyLong_FromLong(resolve_mods(mods)); }
|
PYWRAP1(resolve_key_mods) { int mods; PA("ii", &kitty_mod, &mods); return PyLong_FromLong(resolve_mods(mods)); }
|
||||||
@ -632,6 +648,7 @@ static PyMethodDef module_methods[] = {
|
|||||||
MW(update_window_visibility, METH_VARARGS),
|
MW(update_window_visibility, METH_VARARGS),
|
||||||
MW(set_boss, METH_O),
|
MW(set_boss, METH_O),
|
||||||
MW(set_display_state, METH_VARARGS),
|
MW(set_display_state, METH_VARARGS),
|
||||||
|
MW(enter_resize_mode, METH_VARARGS),
|
||||||
MW(destroy_global_data, METH_NOARGS),
|
MW(destroy_global_data, METH_NOARGS),
|
||||||
|
|
||||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||||
|
@ -137,6 +137,9 @@ typedef struct {
|
|||||||
bool debug_gl, debug_font_fallback;
|
bool debug_gl, debug_font_fallback;
|
||||||
bool has_pending_resizes;
|
bool has_pending_resizes;
|
||||||
bool in_sequence_mode;
|
bool in_sequence_mode;
|
||||||
|
struct {
|
||||||
|
id_type os_window_id, tab_id, window_id;
|
||||||
|
} currently_resizing;
|
||||||
} GlobalState;
|
} GlobalState;
|
||||||
|
|
||||||
extern GlobalState global_state;
|
extern GlobalState global_state;
|
||||||
@ -183,3 +186,4 @@ void free_texture(uint32_t*);
|
|||||||
void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool);
|
void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool);
|
||||||
void send_sprite_to_gpu(unsigned int, unsigned int, unsigned int, pixel*);
|
void send_sprite_to_gpu(unsigned int, unsigned int, unsigned int, pixel*);
|
||||||
void set_titlebar_color(OSWindow *w, color_type color);
|
void set_titlebar_color(OSWindow *w, color_type color);
|
||||||
|
void terminate_resize_mode();
|
||||||
|
@ -12,8 +12,9 @@
|
|||||||
from .constants import WindowGeometry, appname, get_boss, is_macos, is_wayland
|
from .constants import WindowGeometry, appname, get_boss, is_macos, is_wayland
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
DECAWM, Screen, add_tab, glfw_post_empty_event, mark_tab_bar_dirty,
|
DECAWM, Screen, add_tab, glfw_post_empty_event, mark_tab_bar_dirty,
|
||||||
next_window_id, pt_to_px, remove_tab, remove_window, set_active_tab,
|
next_window_id, pt_to_px, remove_tab, remove_window, ring_bell,
|
||||||
set_tab_bar_render_data, swap_tabs, viewport_for_window, x11_window_id
|
set_active_tab, set_tab_bar_render_data, swap_tabs, viewport_for_window,
|
||||||
|
x11_window_id
|
||||||
)
|
)
|
||||||
from .layout import Rect, create_layout_object_for, evict_cached_layouts
|
from .layout import Rect, create_layout_object_for, evict_cached_layouts
|
||||||
from .session import resolved_shell
|
from .session import resolved_shell
|
||||||
@ -162,6 +163,16 @@ def goto_layout(self, layout_name):
|
|||||||
self.current_layout = self.create_layout_object(layout_name)
|
self.current_layout = self.create_layout_object(layout_name)
|
||||||
self.relayout()
|
self.relayout()
|
||||||
|
|
||||||
|
def resize_window_by(self, window_id, increment, is_horizontal):
|
||||||
|
if self.current_layout.modify_size_of_window(self.windows, window_id, increment, is_horizontal):
|
||||||
|
self.relayout()
|
||||||
|
else:
|
||||||
|
ring_bell(self.os_window_id)
|
||||||
|
|
||||||
|
def reset_window_sizes(self):
|
||||||
|
if self.current_layout.remove_all_biases():
|
||||||
|
self.relayout()
|
||||||
|
|
||||||
def launch_child(self, use_shell=False, cmd=None, stdin=None, cwd_from=None, cwd=None, env=None):
|
def launch_child(self, use_shell=False, cmd=None, stdin=None, cwd_from=None, cwd=None, env=None):
|
||||||
if cmd is None:
|
if cmd is None:
|
||||||
if use_shell:
|
if use_shell:
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM,
|
BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM,
|
||||||
CELL_SPECIAL_PROGRAM, CSI, CURSOR_PROGRAM, DCS, GRAPHICS_PREMULT_PROGRAM,
|
CELL_SPECIAL_PROGRAM, CSI, CURSOR_PROGRAM, DCS, GRAPHICS_PREMULT_PROGRAM,
|
||||||
GRAPHICS_PROGRAM, OSC, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen,
|
GRAPHICS_PROGRAM, OSC, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen,
|
||||||
add_window, compile_program, get_clipboard_string, glfw_post_empty_event,
|
add_window, compile_program, enter_resize_mode, get_clipboard_string,
|
||||||
init_cell_program, init_cursor_program, set_clipboard_string,
|
glfw_post_empty_event, init_cell_program, init_cursor_program,
|
||||||
set_titlebar_color, set_window_render_data, update_window_title,
|
set_clipboard_string, set_titlebar_color, set_window_render_data,
|
||||||
update_window_visibility, viewport_for_window
|
update_window_title, update_window_visibility, viewport_for_window
|
||||||
)
|
)
|
||||||
from .keys import keyboard_mode_name
|
from .keys import keyboard_mode_name
|
||||||
from .rgb import to_color
|
from .rgb import to_color
|
||||||
@ -193,6 +193,9 @@ def send_text(self, *args):
|
|||||||
return True
|
return True
|
||||||
self.write_to_child(text)
|
self.write_to_child(text)
|
||||||
|
|
||||||
|
def start_resizing_window(self):
|
||||||
|
enter_resize_mode(self.os_window_id, self.tab_id, self.id)
|
||||||
|
|
||||||
def write_to_child(self, data):
|
def write_to_child(self, data):
|
||||||
if data:
|
if data:
|
||||||
if get_boss().child_monitor.needs_write(self.id, data) is not True:
|
if get_boss().child_monitor.needs_write(self.id, data) is not True:
|
||||||
|
Loading…
Reference in New Issue
Block a user