Track window ids on border rects
More robust. Splits layout still needs work.
This commit is contained in:
parent
9c0d7b83b1
commit
6b54c201e5
11 changed files with 184 additions and 120 deletions
|
|
@ -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 @@ def __call__(
|
|||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
class BorderLine(NamedTuple):
|
||||
edges: Edges = Edges()
|
||||
color: BorderColor = BorderColor.inactive
|
||||
window_id: int = 0
|
||||
|
||||
|
||||
class LayoutOpts:
|
||||
|
|
@ -441,8 +442,7 @@ def get_minimal_borders(self, windows: WindowList) -> Generator[BorderLine, None
|
|||
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
|
||||
|
|
|
|||
|
|
@ -251,13 +251,12 @@ def borders_for_window(gid: int) -> Generator[Edges, None, None]:
|
|||
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
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
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 .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 @@ def __init__(self, horizontal: bool = True):
|
|||
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 @@ def layout_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 @@ def layout_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 @@ def layout_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 @@ def layout_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 @@ def modify_size_of_child(self, which: int, increment: float, is_horizontal: bool
|
|||
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 @@ def minimal_borders(self, all_windows: WindowList) -> Generator[BorderLine, None
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -366,9 +366,10 @@ def minimal_borders(self, all_windows: WindowList) -> Generator[BorderLine, None
|
|||
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(
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -948,7 +948,8 @@ def refresh(self, reload_all_gpu_data: bool = False) -> None:
|
|||
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -350,6 +350,12 @@ def group_for_window(self, x: WindowOrId) -> WindowGroup | None:
|
|||
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):
|
||||
|
|
|
|||
Loading…
Reference in a new issue