diff --git a/kitty/borders.py b/kitty/borders.py index 521d7bf30..a917ddfc9 100644 --- a/kitty/borders.py +++ b/kitty/borders.py @@ -27,14 +27,14 @@ class Border(NamedTuple): border_type: int = 0 -def vertical_edge(rects: list[Border], color: BorderColor, width: int, top: int, bottom: int, left: int, is_left: bool) -> None: +def vertical_edge(rects: list[Border], color: BorderColor, width: int, top: int, bottom: int, left: int, border_type: int) -> None: if width > 0: - rects.append(Border(left, top, left + width, bottom, color, -1 if is_left else 1)) + rects.append(Border(left, top, left + width, bottom, color, border_type)) -def horizontal_edge(rects: list[Border], color: BorderColor, height: int, left: int, right: int, top: int, is_top: bool) -> None: +def horizontal_edge(rects: list[Border], color: BorderColor, height: int, left: int, right: int, top: int, border_type: int) -> None: if height > 0: - rects.append(Border(left, top, right, top + height, color, -1 if is_top else 1)) + rects.append(Border(left, top, right, top + height, color, border_type)) def add_borders(rects: list[Border], color: BorderColor, wg: WindowGroup) -> None: @@ -59,10 +59,11 @@ def add_borders(rects: list[Border], color: BorderColor, wg: WindowGroup) -> Non right += width bottom += width pl = pr = pb = pt = width - h(pt, left, right, top, True) - h(pb, left, right, bt, False) - v(pl, top, bottom, left, True) - v(pr, top, bottom, lr, False) + wid = wg.active_window_id + h(pt, left, right, top, -wid) + h(pb, left, right, bt, wid) + v(pl, top, bottom, left, -wid) + v(pr, top, bottom, lr, wid) def load_borders_program() -> None: @@ -125,5 +126,5 @@ class Borders: if draw_minimal_borders: for border_line in current_layout.get_minimal_borders(all_windows): - rects.append(Border(*border_line.edges, border_line.color, True)) + rects.append(Border(*border_line.edges, border_line.color, border_line.window_id)) set_borders_rects(self.os_window_id, self.tab_id, rects) diff --git a/kitty/layout/base.py b/kitty/layout/base.py index 1aef90806..62d0098dd 100644 --- a/kitty/layout/base.py +++ b/kitty/layout/base.py @@ -17,6 +17,7 @@ from kitty.window_list import WindowGroup, WindowList class BorderLine(NamedTuple): edges: Edges = Edges() color: BorderColor = BorderColor.inactive + window_id: int = 0 class LayoutOpts: @@ -441,8 +442,7 @@ class Layout: yield from self.minimal_borders(windows) def minimal_borders(self, windows: WindowList) -> Generator[BorderLine, None, None]: - return - yield BorderLine() # type: ignore + yield from () def layout_action(self, action_name: str, args: Sequence[str], all_windows: WindowList) -> bool | None: pass diff --git a/kitty/layout/grid.py b/kitty/layout/grid.py index 75abd6e36..22a56bda6 100644 --- a/kitty/layout/grid.py +++ b/kitty/layout/grid.py @@ -251,13 +251,12 @@ class Grid(Layout): yield Edges(right - bw, top, right, bottom) for wg in all_groups_in_order: - for edges in borders_for_window(wg.id): - yield BorderLine(edges) - for wg in all_groups_in_order: + color = BorderColor.inactive if needs_borders_map.get(wg.id): color = BorderColor.active if wg is active_group else BorderColor.bell - for edges in borders_for_window(wg.id): - yield BorderLine(edges, color) + wid = wg.active_window_id + for edges in borders_for_window(wg.id): + yield BorderLine(edges, color, wid) def neighbors_for_window(self, window: WindowType, all_windows: WindowList) -> NeighborsMap: n = all_windows.num_groups diff --git a/kitty/layout/splits.py b/kitty/layout/splits.py index 758b90b4c..3e582df06 100644 --- a/kitty/layout/splits.py +++ b/kitty/layout/splits.py @@ -1,11 +1,11 @@ #!/usr/bin/env python # License: GPLv3 Copyright: 2020, Kovid Goyal -from collections.abc import Collection, Generator, Sequence -from typing import Any, NamedTuple, Optional, TypedDict, Union +from collections.abc import Collection, Generator, Iterator, Sequence +from typing import Any, Optional, TypedDict, Union from kitty.borders import BorderColor -from kitty.fast_data_types import BOTTOM_EDGE, RIGHT_EDGE +from kitty.fast_data_types import BOTTOM_EDGE, LEFT_EDGE, RIGHT_EDGE, TOP_EDGE from kitty.types import Edges, NeighborsMap, WindowGeometry, WindowMapper, WindowResizeDragData from kitty.typing_compat import EdgeLiteral, WindowType from kitty.window_list import WindowGroup, WindowList @@ -13,11 +13,6 @@ from kitty.window_list import WindowGroup, WindowList from .base import BorderLine, Layout, LayoutOpts, blank_rects_for_window, lgd, window_geometry_from_layouts -class Extent(NamedTuple): - start: int = 0 - end: int = 0 - - class SerializedPair(TypedDict, total=False): horizontal: bool # default to True if absent bias: float # default to 0.5 if absent @@ -33,8 +28,9 @@ class Pair: self.two: Pair | int | None = None self.bias = 0.5 self.top = self.left = self.width = self.height = 0 - self.between_borders: list[Edges] = [] - self.first_extent = self.second_extent = Extent() + self.between_borders: tuple[Sequence[BorderLine], Sequence[BorderLine]] | None = None + self.first_extent = self.second_extent = Edges() # not including between_borders + self.border_width: int = 0 def serialize(self) -> SerializedPair: ans: SerializedPair = {} @@ -242,12 +238,12 @@ class Pair: id_window_map: dict[int, WindowGroup], layout_object: Layout ) -> None: - self.between_borders = [] + self.between_borders = None self.left, self.top, self.width, self.height = left, top, width, height - bw = self.effective_border(id_window_map) if lgd.draw_minimal_borders else 0 + self.first_extent = self.second_extent = Edges(left, top, left + width, top + height) + self.border_width = bw = self.effective_border(id_window_map) if lgd.draw_minimal_borders else 0 border_mult = 0 if lgd.draw_minimal_borders else 1 bw2 = bw * 2 - self.first_extent = self.second_extent = Extent() if self.one is None or self.two is None: q = self.one or self.two if isinstance(q, Pair): @@ -258,9 +254,11 @@ class Pair: xl = next(layout_object.xlayout(iter((wg,)), start=left, size=width, border_mult=border_mult)) yl = next(layout_object.ylayout(iter((wg,)), start=top, size=height, border_mult=border_mult)) geom = window_geometry_from_layouts(xl, yl) - self.first_extent = Extent(left, left + width) self.apply_window_geometry(q, geom, id_window_map, layout_object) return + one: list[BorderLine] = [] + two: list[BorderLine] = [] + self.between_borders = one, two if self.horizontal: min_w1 = self.one.minimum_width(id_window_map) if isinstance(self.one, Pair) else lgd.cell_width min_w2 = self.two.minimum_width(id_window_map) if isinstance(self.two, Pair) else lgd.cell_width @@ -269,26 +267,33 @@ class Pair: if w2 < min_w2 and w1 >= min_w1 + bw2: w2 = min_w2 w1 = width - w2 - self.first_extent = Extent(max(0, left - bw), left + w1 + bw) - self.second_extent = Extent(left + w1 + bw, left + width + bw) + bleft = left + w1 + self.first_extent = Edges(left, top, left + w1, top + height) if isinstance(self.one, Pair): self.one.layout_pair(left, top, w1, height, id_window_map, layout_object) + if bw: + for top, bottom, window_id in self.one.edge_border(RIGHT_EDGE, id_window_map): + one.append(BorderLine(Edges(bleft, top, bleft + bw, bottom), window_id=window_id)) else: wg = id_window_map[self.one] yl = next(layout_object.ylayout(iter((wg,)), start=top, size=height, border_mult=border_mult)) xl = next(layout_object.xlayout(iter((wg,)), start=left, size=w1, border_mult=border_mult)) geom = window_geometry_from_layouts(xl, yl) self.apply_window_geometry(self.one, geom, id_window_map, layout_object) - self.between_borders = [ - Edges(left + w1, top, left + w1 + bw, top + height), - Edges(left + w1 + bw, top, left + w1 + bw2, top + height), - ] - left += bw2 + if bw: + one.append(BorderLine(Edges(bleft, top, bleft + bw, top + height), window_id=wg.active_window_id)) + left += w1 + bw2 + self.second_extent = Edges(left, top, left + w2, top + height) if isinstance(self.two, Pair): - self.two.layout_pair(left + w1, top, w2, height, id_window_map, layout_object) + self.two.layout_pair(left, top, w2, height, id_window_map, layout_object) + if bw: + for top, bottom, window_id in self.two.edge_border(LEFT_EDGE, id_window_map): + two.append(BorderLine(Edges(left - bw, top, left, bottom), window_id=window_id)) else: wg = id_window_map[self.two] - xl = next(layout_object.xlayout(iter((wg,)), start=left + w1, size=w2, border_mult=border_mult)) + if bw: + two.append(BorderLine(Edges(left - bw, top, left, top + height), window_id=-wg.active_window_id)) + xl = next(layout_object.xlayout(iter((wg,)), start=left, size=w2, border_mult=border_mult)) yl = next(layout_object.ylayout(iter((wg,)), start=top, size=height, border_mult=border_mult)) geom = window_geometry_from_layouts(xl, yl) self.apply_window_geometry(self.two, geom, id_window_map, layout_object) @@ -300,30 +305,118 @@ class Pair: if h2 < min_h2 and h1 >= min_h1 + bw2: h2 = min_h2 h1 = height - h2 - self.first_extent = Extent(max(0, top - bw), top + h1 + bw) - self.second_extent = Extent(top + h1 + bw, top + height + bw) + btop = top + h1 + self.first_extent = Edges(left, top, left + width, top + h1) if isinstance(self.one, Pair): self.one.layout_pair(left, top, width, h1, id_window_map, layout_object) + if bw: + for left, right, window_id in self.one.edge_border(BOTTOM_EDGE, id_window_map): + one.append(BorderLine(Edges(left, btop, right, btop + bw), window_id=window_id)) else: wg = id_window_map[self.one] xl = next(layout_object.xlayout(iter((wg,)), start=left, size=width, border_mult=border_mult)) yl = next(layout_object.ylayout(iter((wg,)), start=top, size=h1, border_mult=border_mult)) geom = window_geometry_from_layouts(xl, yl) self.apply_window_geometry(self.one, geom, id_window_map, layout_object) - self.between_borders = [ - Edges(left, top + h1, left + width, top + h1 + bw), - Edges(left, top + h1 + bw, left + width, top + h1 + bw2), - ] - top += bw2 + if bw: + one.append(BorderLine(Edges(left, btop, left + width, btop + bw), window_id=wg.active_window_id)) + top += bw2 + h1 + self.second_extent = Edges(left, top, left + width, top + h2) if isinstance(self.two, Pair): - self.two.layout_pair(left, top + h1, width, h2, id_window_map, layout_object) + self.two.layout_pair(left, top, width, h2, id_window_map, layout_object) + if bw: + for left, right, window_id in self.two.edge_border(TOP_EDGE, id_window_map): + two.append(BorderLine(Edges(left, top - bw, right, top), window_id=window_id)) else: wg = id_window_map[self.two] + if bw: + two.append(BorderLine(Edges(left, top - bw, left + width, top), window_id=-wg.active_window_id)) xl = next(layout_object.xlayout(iter((wg,)), start=left, size=width, border_mult=border_mult)) - yl = next(layout_object.ylayout(iter((wg,)), start=top + h1, size=h2, border_mult=border_mult)) + yl = next(layout_object.ylayout(iter((wg,)), start=top, size=h2, border_mult=border_mult)) geom = window_geometry_from_layouts(xl, yl) self.apply_window_geometry(self.two, geom, id_window_map, layout_object) + def edge_border(self, which: int, id_group_map: dict[int, WindowGroup]) -> Iterator[tuple[int, int, int]]: + mult = 1 if which & (RIGHT_EDGE | BOTTOM_EDGE) else -1 + + def edge(x: int, p: Pair) -> tuple[int, int, int]: + wid = id_group_map[x].active_window_id * mult + if which & (LEFT_EDGE | RIGHT_EDGE): + return p.top, p.top + p.height, wid + return p.left, p.left + p.width, wid + + def edges(x: int | Pair, parent: Pair) -> Iterator[tuple[int, int, int]]: + if isinstance(x, int): + yield edge(x, parent) + else: + yield from x.edge_border(which, id_group_map) + + if self.two is None or self.one is None: + x = self.one or self.two + if x is not None: + yield from edges(x, self) + return + + needs_vertical_edges = which in (LEFT_EDGE, RIGHT_EDGE) + if self.horizontal == needs_vertical_edges: + yield from edges(self.one if which in (LEFT_EDGE, TOP_EDGE) else self.two, self) + else: + g1, g2 = self.pair_geometry(id_group_map) + if g1 is not None and g2 is not None: + yield from edges(self.one, g1) + first_id = second_id = 0 + if isinstance(self.one, int): + first_id = id_group_map[self.one].active_window_id + if isinstance(self.two, int): + second_id = id_group_map[self.two].active_window_id + if self.horizontal: + start = g1.left + g1.width + if isinstance(self.one, Pair): + first_id = id_group_map[self.one.corner_group_id(which | RIGHT_EDGE)].active_window_id + if isinstance(self.two, Pair): + second_id = id_group_map[self.two.corner_group_id(which | LEFT_EDGE)].active_window_id + else: + start = g1.top + g1.height + if isinstance(self.one, Pair): + first_id = id_group_map[self.one.corner_group_id(which | BOTTOM_EDGE)].active_window_id + if isinstance(self.two, Pair): + second_id = id_group_map[self.two.corner_group_id(which | TOP_EDGE)].active_window_id + yield start, start + self.border_width, first_id * mult + yield start + self.border_width, start + 2*self.border_width, second_id * mult + yield from edges(self.two, g2) + + def corner_group_id(self, which: int) -> int: + if self.is_redundant: + q = self.one or self.two + elif self.horizontal: + q = self.one if which & LEFT_EDGE else self.two + else: + q = self.one if which & TOP_EDGE else self.two + if q is None: + return 0 + return q if isinstance(q, int) else q.corner_group_id(which) + + def pair_geometry(self, id_group_map: dict[int, WindowGroup]) -> 'tuple[Pair | None, Pair | None]': + g1: Pair | None = None + g2 = g1 + if self.one is not None: + if isinstance(self.one, int): + g1 = Pair() + g1.one = self.one + e = self.first_extent + g1.left, g1.top, g1.width, g1.height = e.left, e.top, e.right - e.left, e.bottom - e.top + else: + g1 = self.one + if self.two is not None: + if isinstance(self.two, int): + g2 = Pair() + g2.one = self.two + g = self.second_extent + g2.left, g2.top, g2.width, g2.height = g.left, g.top, g.right - g.left, g.bottom - g.top + else: + g2 = self.two + return g1, g2 + def set_bias(self, window_id: int, bias: int) -> None: b = max(0, min(bias, 100)) / 100 self.bias = b if window_id == self.one else (1. - b) @@ -343,55 +436,6 @@ class Pair: return parent.modify_size_of_child(which, increment, is_horizontal, layout_object) return False - def borders_for_window(self, layout_object: 'Splits', window_id: int) -> Generator[Edges, None, None]: - is_first = self.one == window_id - if self.between_borders: - yield self.between_borders[0 if is_first else 1] - q = self - found_same_direction = found_transverse1 = found_transverse2 = False - while not (found_same_direction and found_transverse1 and found_transverse2): - parent = q.parent(layout_object.pairs_root) - if parent is None: - break - q = parent - if not q.between_borders: - continue - if q.horizontal == self.horizontal: - if not found_same_direction: - if self.horizontal: - is_before = q.between_borders[0].left <= self.left - else: - is_before = q.between_borders[0].top <= self.top - if is_before == is_first: - found_same_direction = True - edges = q.between_borders[1 if is_before else 0] - if self.horizontal: - yield edges._replace(top=self.top, bottom=self.top + self.height) - else: - yield edges._replace(left=self.left, right=self.left + self.width) - else: - if self.horizontal: - is_before = q.between_borders[0].top <= self.top - else: - is_before = q.between_borders[0].left <= self.left - extent = self.first_extent if is_first else self.second_extent - if is_before: - if not found_transverse1: - found_transverse1 = True - edges = q.between_borders[1] - if self.horizontal: - yield edges._replace(left=extent.start, right=extent.end) - else: - yield edges._replace(top=extent.start, bottom=extent.end) - else: - if not found_transverse2: - found_transverse2 = True - edges = q.between_borders[0] - if self.horizontal: - yield edges._replace(left=extent.start, right=extent.end) - else: - yield edges._replace(top=extent.start, bottom=extent.end) - def neighbors_for_window(self, window_id: int, ans: NeighborsMap, layout_object: 'Splits', all_windows: WindowList) -> None: def quadrant(is_horizontal: bool, is_first: bool) -> tuple[EdgeLiteral, EdgeLiteral]: @@ -602,19 +646,23 @@ class Splits(Layout): window_count = len(groups) if not lgd.draw_minimal_borders or window_count < 2: return - for pair in self.pairs_root.self_and_descendants(): - for edges in pair.between_borders: - yield BorderLine(edges) needs_borders_map = all_windows.compute_needs_borders_map(lgd.draw_active_borders) ag = all_windows.active_group active_group_id = -1 if ag is None else ag.id + + border_color_map = {} for grp_id, needs_borders in needs_borders_map.items(): if needs_borders: - qpair = self.pairs_root.pair_for_window(grp_id) - if qpair is not None: + wid = g.active_window_id if (g := all_windows.group_for_id(grp_id)) else 0 + if wid: color = BorderColor.active if grp_id is active_group_id else BorderColor.bell - for edges in qpair.borders_for_window(self, grp_id): - yield BorderLine(edges, color) + border_color_map[wid] = color + + for pair in self.pairs_root.self_and_descendants(): + if pair.between_borders: + for which in pair.between_borders: + for bb in which: + yield bb._replace(color=border_color_map.get(abs(bb.window_id), BorderColor.inactive)) def neighbors_for_window(self, window: WindowType, all_windows: WindowList) -> NeighborsMap: wg = all_windows.group_for_window(window) diff --git a/kitty/layout/tall.py b/kitty/layout/tall.py index f60b5445c..7a738749c 100644 --- a/kitty/layout/tall.py +++ b/kitty/layout/tall.py @@ -366,9 +366,10 @@ class Tall(Layout): xl.content_pos + xl.content_size + xl.space_after, yl.content_pos + ((yl.content_size + yl.space_after) if mirrored else (bw - yl.space_before)), ) - perp_borders.append(BorderLine(e1, color)) - perp_borders.append(BorderLine(e2, color)) - perp_borders.append(BorderLine(e3, color)) + wid = wg.active_window_id + perp_borders.append(BorderLine(e1, color, wid)) + perp_borders.append(BorderLine(e2, color, wid)) + perp_borders.append(BorderLine(e3, color, wid)) mirrored = self.layout_opts.mirrored yield from borders( diff --git a/kitty/layout/vertical.py b/kitty/layout/vertical.py index c4fdeb416..bcc3045fe 100644 --- a/kitty/layout/vertical.py +++ b/kitty/layout/vertical.py @@ -50,8 +50,8 @@ def borders( color = BorderColor.inactive if needs_borders_map.get(wg.id): color = BorderColor.active if wg is active_group else BorderColor.bell - borders.append(BorderLine(e1, color)) - borders.append(BorderLine(e2, color)) + borders.append(BorderLine(e1, color, wg.active_window_id)) + borders.append(BorderLine(e2, color, wg.active_window_id)) last_idx = len(borders) - 1 - end_offset for i, x in enumerate(borders): diff --git a/kitty/mouse.c b/kitty/mouse.c index b732c8bdc..130e930b3 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -260,8 +260,8 @@ border_contains_mouse(BorderRect *br, double tolerance, Edge *edges) { if ((int)br->px.left - tolerance <= x && x < (int)br->px.right + tolerance && (int)br->px.top - tolerance <= y && y < (int)br->px.bottom + tolerance) { ans = true; if (br->px.right - br->px.left < br->px.bottom - br->px.top) - *edges |= br->border_type < 1 ? LEFT_EDGE : RIGHT_EDGE; - else *edges |= br->border_type < 1 ? TOP_EDGE : BOTTOM_EDGE; + *edges |= br->border_type < 0 ? LEFT_EDGE : RIGHT_EDGE; + else *edges |= br->border_type < 0 ? TOP_EDGE : BOTTOM_EDGE; } return ans; } @@ -922,6 +922,7 @@ window_for_event(unsigned int *window_idx, bool *in_tab_bar, Edge *window_border Tab *t = global_state.callback_os_window->tabs + global_state.callback_os_window->active_tab; if (window_border && num_visible_windows(t) > 1) { *window_border = 0; + id_type window_id = 0; double dpi = (w->fonts_data->logical_dpi_x + w->fonts_data->logical_dpi_y) / 2.; double tolerance = ((long)round((OPT(window_drag_tolerance) * (dpi / 72.0)))); BorderRect *closest_vert = NULL, *closest_horiz = NULL; @@ -934,6 +935,7 @@ window_for_event(unsigned int *window_idx, bool *in_tab_bar, Edge *window_border *window_border |= edges; if (edges & (LEFT_EDGE | RIGHT_EDGE)) { closest_vert_dist = -1; closest_vert = NULL; } else { closest_horiz_dist = -1; closest_horiz = NULL; } + window_id = br->border_type < 0 ? -br->border_type : br->border_type; } else if (border_contains_mouse(br, tolerance, &edges)) { unsigned width = br->px.right - br->px.left, height = br->px.bottom - br->px.top; if (width < height) { @@ -945,8 +947,16 @@ window_for_event(unsigned int *window_idx, bool *in_tab_bar, Edge *window_border } } } - if (closest_vert) border_contains_mouse(closest_vert, tolerance, window_border); - if (closest_horiz) border_contains_mouse(closest_horiz, tolerance, window_border); + if (closest_vert && border_contains_mouse(closest_vert, tolerance, window_border) && !window_id) + window_id = closest_vert->border_type < 0 ? -closest_vert->border_type : closest_vert->border_type; + if (closest_horiz && border_contains_mouse(closest_horiz, tolerance, window_border) && !window_id) + window_id = closest_horiz->border_type < 0 ? -closest_horiz->border_type : closest_horiz->border_type; + if (*window_border) { + if (!window_id) return NULL; + for (unsigned int i = 0; i < t->num_windows; i++) + if (t->windows[i].id == window_id) return t->windows + i; + return NULL; + } } for (unsigned int i = 0; i < t->num_windows; i++) { if (contains_mouse(t->windows + i) && t->windows[i].render_data.screen) { @@ -1204,9 +1214,7 @@ mouse_event(const int button, int modifiers, int action) { handle_tab_bar_mouse(button, modifiers, action); debug("handled by tab bar\n"); } else if (window_border) { - debug("window border: %d\n", window_border); - w = window_for_event(&window_idx, &in_tab_bar, NULL); - if (!w) w = closest_window_for_event(&window_idx); + debug("window border: %d window id: %llu\n", window_border, w ? w->id : 0); if (window_border & LEFT_EDGE) { if (window_border & TOP_EDGE) mouse_cursor_shape = NWSE_RESIZE_POINTER; else if (window_border & BOTTOM_EDGE) mouse_cursor_shape = NESW_RESIZE_POINTER; diff --git a/kitty/state.c b/kitty/state.c index fe2836398..e0e5fc0cb 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -612,10 +612,10 @@ pyset_borders_rects(PyObject *self UNUSED, PyObject *args) { ensure_space_for(br, rect_buf, BorderRect, br->num_border_rects + 1, capacity, 32, false); for (unsigned i = 0; i < br->num_border_rects; i++) { PyObject *pr = PyList_GET_ITEM(rects, i); - unsigned long color; int border_type; + unsigned long color; long long border_type; BorderRect *r = br->rect_buf + i; if (!PyArg_ParseTuple( - pr, "IIIIki", &r->px.left, &r->px.top, &r->px.right, &r->px.bottom, &color, &border_type + pr, "IIIIkL", &r->px.left, &r->px.top, &r->px.right, &r->px.bottom, &color, &border_type )) return NULL; r->left = gl_pos_x(r->px.left, osw->viewport_width); r->top = gl_pos_y(r->px.top, osw->viewport_height); diff --git a/kitty/state.h b/kitty/state.h index fcf1aa7ae..38c8a3cc9 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -240,7 +240,7 @@ typedef struct BorderRect { float left, top, right, bottom; struct { unsigned left, top, right, bottom; } px; uint32_t color; - int border_type; + long long border_type; } BorderRect; typedef struct BorderRects { diff --git a/kitty/window.py b/kitty/window.py index 0a204b811..d1ba36eb3 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -948,7 +948,8 @@ class Window: def pause_resize_notifications_to_child(self, pause: bool = True) -> None: if pause: - self._pause_resize_notifications_to_child = -1, -1, -1, -1 + if self._pause_resize_notifications_to_child is None: + self._pause_resize_notifications_to_child = -1, -1, -1, -1 else: p, self._pause_resize_notifications_to_child = self._pause_resize_notifications_to_child, None if p and p[0] > 0: diff --git a/kitty/window_list.py b/kitty/window_list.py index 5f7544505..bcc8b834f 100644 --- a/kitty/window_list.py +++ b/kitty/window_list.py @@ -350,6 +350,12 @@ class WindowList: return g return None + def group_for_id(self, gid: int) -> WindowGroup | None: + for g in self.groups: + if g.id == gid: + return g + return None + def group_idx_for_window(self, x: WindowOrId) -> int | None: q = self.id_map[x] if isinstance(x, int) else x for i, g in enumerate(self.groups):