Track border rect orientation explicitly
This commit is contained in:
parent
db9c4c24a7
commit
ad560715a6
9 changed files with 64 additions and 75 deletions
|
|
@ -25,16 +25,17 @@ class Border(NamedTuple):
|
|||
bottom: int
|
||||
color: BorderColor
|
||||
border_type: int = 0
|
||||
horizontal: bool = False
|
||||
|
||||
|
||||
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, border_type))
|
||||
rects.append(Border(left, top, left + width, bottom, color, border_type, False))
|
||||
|
||||
|
||||
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, border_type))
|
||||
rects.append(Border(left, top, right, top + height, color, border_type, True))
|
||||
|
||||
|
||||
def add_borders(rects: list[Border], color: BorderColor, wg: WindowGroup) -> None:
|
||||
|
|
@ -126,5 +127,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, border_line.window_id))
|
||||
rects.append(Border(*border_line.edges, border_line.color, border_line.window_id, border_line.horizontal))
|
||||
set_borders_rects(self.os_window_id, self.tab_id, rects)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ class BorderLine(NamedTuple):
|
|||
edges: Edges = Edges()
|
||||
color: BorderColor = BorderColor.inactive
|
||||
window_id: int = 0
|
||||
horizontal: bool = False
|
||||
|
||||
|
||||
class LayoutOpts:
|
||||
|
|
@ -437,11 +438,11 @@ def neighbors_for_window(self, window: WindowType, windows: WindowList) -> Neigh
|
|||
def compute_needs_borders_map(self, all_windows: WindowList) -> dict[int, bool]:
|
||||
return all_windows.compute_needs_borders_map(lgd.draw_active_borders)
|
||||
|
||||
def get_minimal_borders(self, windows: WindowList) -> Generator[BorderLine, None, None]:
|
||||
def get_minimal_borders(self, windows: WindowList) -> Iterator[BorderLine]:
|
||||
self._set_dimensions(windows)
|
||||
yield from self.minimal_borders(windows)
|
||||
|
||||
def minimal_borders(self, windows: WindowList) -> Generator[BorderLine, None, None]:
|
||||
def minimal_borders(self, windows: WindowList) -> Iterator[BorderLine]:
|
||||
yield from ()
|
||||
|
||||
def layout_action(self, action_name: str, args: Sequence[str], all_windows: WindowList) -> bool | None:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from collections.abc import Callable, Generator, Sequence
|
||||
from collections.abc import Callable, Generator, Iterator, Sequence
|
||||
from functools import lru_cache
|
||||
from itertools import repeat
|
||||
from math import ceil, floor
|
||||
|
|
@ -192,7 +192,7 @@ def position_window_in_grid_cell(window_idx: int, xl: LayoutData, yl: LayoutData
|
|||
n, nrows, ncols, special_rows, special_col, on_col_done):
|
||||
position_window_in_grid_cell(window_idx, xl, yl)
|
||||
|
||||
def minimal_borders(self, all_windows: WindowList) -> Generator[BorderLine, None, None]:
|
||||
def minimal_borders(self, all_windows: WindowList) -> Iterator[BorderLine]:
|
||||
n = all_windows.num_groups
|
||||
if not lgd.draw_minimal_borders or n < 2:
|
||||
return
|
||||
|
|
@ -231,7 +231,7 @@ def on_col_done(col_windows: list[int]) -> None:
|
|||
def ends(yl: LayoutData) -> tuple[int, int]:
|
||||
return yl.content_pos - yl.space_before, yl.content_pos + yl.content_size + yl.space_after
|
||||
|
||||
def borders_for_window(gid: int, color: BorderColor, wid: int) -> Generator[BorderLine, None, None]:
|
||||
def borders_for_window(gid: int, color: BorderColor, wid: int) -> Iterator[BorderLine]:
|
||||
xl, yl = layout_data_map[gid]
|
||||
left, right = ends(xl)
|
||||
top, bottom = ends(yl)
|
||||
|
|
@ -240,15 +240,15 @@ def borders_for_window(gid: int, color: BorderColor, wid: int) -> Generator[Bord
|
|||
|
||||
# Horizontal
|
||||
if not first_row:
|
||||
yield BorderLine(Edges(left, top, right, top + bw), color, -wid)
|
||||
yield BorderLine(Edges(left, top, right, top + bw), color, -wid, True)
|
||||
if not last_row:
|
||||
yield BorderLine(Edges(left, bottom - bw, right, bottom), color, wid)
|
||||
yield BorderLine(Edges(left, bottom - bw, right, bottom), color, wid, True)
|
||||
|
||||
# Vertical
|
||||
if not first_column:
|
||||
yield BorderLine(Edges(left, top, left + bw, bottom), color, -wid)
|
||||
yield BorderLine(Edges(left, top, left + bw, bottom), color, -wid, False)
|
||||
if not last_column:
|
||||
yield BorderLine(Edges(right - bw, top, right, bottom), color, wid)
|
||||
yield BorderLine(Edges(right - bw, top, right, bottom), color, wid, False)
|
||||
|
||||
for wg in all_groups_in_order:
|
||||
color = BorderColor.inactive
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ def layout_pair(
|
|||
self.one.layout_pair(left, top, w1, height, id_window_map, layout_object)
|
||||
if bw:
|
||||
for etop, ebottom, window_id in self.one.edge_border(RIGHT_EDGE, id_window_map):
|
||||
one.append(BorderLine(Edges(bleft, etop, bleft + bw, ebottom), window_id=window_id))
|
||||
one.append(BorderLine(Edges(bleft, etop, bleft + bw, ebottom), window_id=window_id, horizontal=False))
|
||||
else:
|
||||
wg = id_window_map[self.one]
|
||||
yl = next(layout_object.ylayout(iter((wg,)), start=top, size=height, border_mult=border_mult))
|
||||
|
|
@ -281,18 +281,18 @@ def layout_pair(
|
|||
geom = window_geometry_from_layouts(xl, yl)
|
||||
self.apply_window_geometry(self.one, geom, id_window_map, layout_object)
|
||||
if bw:
|
||||
one.append(BorderLine(Edges(bleft, top, bleft + bw, top + height), window_id=wg.active_window_id))
|
||||
one.append(BorderLine(Edges(bleft, top, bleft + bw, top + height), window_id=wg.active_window_id, horizontal=False))
|
||||
left += w1 + bw2
|
||||
self.second_extent = Edges(left, top, left + w2, top + height)
|
||||
if isinstance(self.two, Pair):
|
||||
self.two.layout_pair(left, top, w2, height, id_window_map, layout_object)
|
||||
if bw:
|
||||
for etop, ebottom, window_id in self.two.edge_border(LEFT_EDGE, id_window_map):
|
||||
two.append(BorderLine(Edges(left - bw, etop, left, ebottom), window_id=window_id))
|
||||
two.append(BorderLine(Edges(left - bw, etop, left, ebottom), window_id=window_id, horizontal=False))
|
||||
else:
|
||||
wg = id_window_map[self.two]
|
||||
if bw:
|
||||
two.append(BorderLine(Edges(left - bw, top, left, top + height), window_id=-wg.active_window_id))
|
||||
two.append(BorderLine(Edges(left - bw, top, left, top + height), window_id=-wg.active_window_id, horizontal=False))
|
||||
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)
|
||||
|
|
@ -311,7 +311,7 @@ def layout_pair(
|
|||
self.one.layout_pair(left, top, width, h1, id_window_map, layout_object)
|
||||
if bw:
|
||||
for eleft, eright, window_id in self.one.edge_border(BOTTOM_EDGE, id_window_map):
|
||||
one.append(BorderLine(Edges(eleft, btop, eright, btop + bw), window_id=window_id))
|
||||
one.append(BorderLine(Edges(eleft, btop, eright, btop + bw), window_id=window_id, horizontal=True))
|
||||
else:
|
||||
wg = id_window_map[self.one]
|
||||
xl = next(layout_object.xlayout(iter((wg,)), start=left, size=width, border_mult=border_mult))
|
||||
|
|
@ -319,18 +319,18 @@ def layout_pair(
|
|||
geom = window_geometry_from_layouts(xl, yl)
|
||||
self.apply_window_geometry(self.one, geom, id_window_map, layout_object)
|
||||
if bw:
|
||||
one.append(BorderLine(Edges(left, btop, left + width, btop + bw), window_id=wg.active_window_id))
|
||||
one.append(BorderLine(Edges(left, btop, left + width, btop + bw), window_id=wg.active_window_id, horizontal=True))
|
||||
top += bw2 + h1
|
||||
self.second_extent = Edges(left, top, left + width, top + h2)
|
||||
if isinstance(self.two, Pair):
|
||||
self.two.layout_pair(left, top, width, h2, id_window_map, layout_object)
|
||||
if bw:
|
||||
for eleft, eright, window_id in self.two.edge_border(TOP_EDGE, id_window_map):
|
||||
two.append(BorderLine(Edges(eleft, top - bw, eright, top), window_id=window_id))
|
||||
two.append(BorderLine(Edges(eleft, top - bw, eright, top), window_id=window_id, horizontal=True))
|
||||
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))
|
||||
two.append(BorderLine(Edges(left, top - bw, left + width, top), window_id=-wg.active_window_id, horizontal=True))
|
||||
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=h2, border_mult=border_mult))
|
||||
geom = window_geometry_from_layouts(xl, yl)
|
||||
|
|
@ -630,7 +630,7 @@ def remove_all_biases(self) -> bool:
|
|||
pair.bias = 0.5
|
||||
return True
|
||||
|
||||
def minimal_borders(self, all_windows: WindowList) -> Generator[BorderLine, None, None]:
|
||||
def minimal_borders(self, all_windows: WindowList) -> Iterator[BorderLine]:
|
||||
groups = tuple(all_windows.iter_all_layoutable_groups())
|
||||
window_count = len(groups)
|
||||
if not lgd.draw_minimal_borders or window_count < 2:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import sys
|
||||
from collections.abc import Generator, Sequence
|
||||
from collections.abc import Generator, Iterator, Sequence
|
||||
from itertools import islice, repeat
|
||||
from typing import Any
|
||||
|
||||
|
|
@ -301,7 +301,7 @@ def layout_action(self, action_name: str, args: Sequence[str], all_windows: Wind
|
|||
return False
|
||||
return None
|
||||
|
||||
def minimal_borders(self, all_windows: WindowList) -> Generator[BorderLine, None, None]:
|
||||
def minimal_borders(self, all_windows: WindowList) -> Iterator[BorderLine]:
|
||||
num = all_windows.num_groups
|
||||
if num < 2 or not lgd.draw_minimal_borders:
|
||||
return
|
||||
|
|
@ -321,6 +321,7 @@ def minimal_borders(self, all_windows: WindowList) -> Generator[BorderLine, None
|
|||
needs_borders_map = all_windows.compute_needs_borders_map(lgd.draw_active_borders)
|
||||
active_group = all_windows.active_group
|
||||
mirrored = self.layout_opts.mirrored
|
||||
print(11111111, self.main_is_horizontal)
|
||||
for wg, xl, yl, is_full_size in layouts:
|
||||
if is_full_size:
|
||||
main_layouts.append((wg, xl, yl))
|
||||
|
|
@ -328,49 +329,30 @@ def minimal_borders(self, all_windows: WindowList) -> Generator[BorderLine, None
|
|||
color = BorderColor.inactive
|
||||
if needs_borders_map.get(wg.id):
|
||||
color = BorderColor.active if wg is active_group else BorderColor.bell
|
||||
if self.main_is_horizontal:
|
||||
e1 = Edges(
|
||||
xl.content_pos - xl.space_before,
|
||||
yl.content_pos - yl.space_before,
|
||||
xl.content_pos + xl.content_size + xl.space_after,
|
||||
yl.content_pos - yl.space_before + bw
|
||||
)
|
||||
e3 = Edges(
|
||||
xl.content_pos - xl.space_before,
|
||||
yl.content_pos + yl.content_size + yl.space_after - bw,
|
||||
xl.content_pos + xl.content_size + xl.space_after,
|
||||
yl.content_pos + yl.content_size + yl.space_after,
|
||||
)
|
||||
e2 = Edges(
|
||||
xl.content_pos + ((xl.content_size + xl.space_after - bw) if mirrored else -xl.space_before),
|
||||
yl.content_pos - yl.space_before,
|
||||
xl.content_pos + ((xl.content_size + xl.space_after) if mirrored else (bw - xl.space_before)),
|
||||
yl.content_pos + yl.content_size + yl.space_after,
|
||||
)
|
||||
else:
|
||||
e1 = Edges(
|
||||
xl.content_pos - xl.space_before,
|
||||
yl.content_pos - yl.space_before,
|
||||
xl.content_pos - xl.space_before + bw,
|
||||
yl.content_pos + yl.content_size + yl.space_after,
|
||||
)
|
||||
e3 = Edges(
|
||||
xl.content_pos + xl.content_size + xl.space_after - bw,
|
||||
yl.content_pos - yl.space_before,
|
||||
xl.content_pos + xl.content_size + xl.space_after,
|
||||
yl.content_pos + yl.content_size + yl.space_after,
|
||||
)
|
||||
e2 = Edges(
|
||||
xl.content_pos - xl.space_before,
|
||||
yl.content_pos + ((yl.content_size + yl.space_after - bw) if mirrored else -yl.space_before),
|
||||
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)),
|
||||
)
|
||||
wid = wg.active_window_id
|
||||
mult = 1 if mirrored else -1
|
||||
perp_borders.append(BorderLine(e1, color, -wid))
|
||||
perp_borders.append(BorderLine(e2, color, mult*wid))
|
||||
perp_borders.append(BorderLine(e3, color, wid))
|
||||
def h(left: int, right: int, top: int, mult: int) -> None:
|
||||
e = Edges(left, top, right, top + bw)
|
||||
perp_borders.append(BorderLine(e, color, mult*wid, True))
|
||||
def v(top: int, bottom: int, left: int, mult: int) -> None:
|
||||
print(f'{left=} {top=} {bottom=} {mult=}')
|
||||
e = Edges(left, top, left + bw, bottom)
|
||||
perp_borders.append(BorderLine(e, color, mult*wid, False))
|
||||
|
||||
if self.main_is_horizontal:
|
||||
h(xl.content_pos - xl.space_before, xl.content_pos + xl.content_size + xl.space_after,
|
||||
yl.content_pos - yl.space_before, -1)
|
||||
v(yl.content_pos - yl.space_before, yl.content_pos + yl.content_size + yl.space_after,
|
||||
xl.content_pos + ((xl.content_size + xl.space_after - bw) if mirrored else -xl.space_before), mult)
|
||||
h(xl.content_pos - xl.space_before, xl.content_pos + xl.content_size + xl.space_after,
|
||||
yl.content_pos + yl.content_size + yl.space_after - bw, 1)
|
||||
else:
|
||||
v(yl.content_pos - yl.space_before, yl.content_pos + yl.content_size + yl.space_after,
|
||||
xl.content_pos - xl.space_before, -1)
|
||||
h(xl.content_pos - xl.space_before, xl.content_pos + xl.content_size + xl.space_after,
|
||||
yl.content_pos + ((yl.content_size + yl.space_after - bw) if mirrored else -yl.space_before), mult)
|
||||
v(yl.content_pos - yl.space_before, yl.content_pos + yl.content_size + yl.space_after,
|
||||
xl.content_pos + xl.content_size + xl.space_after - bw, 1)
|
||||
|
||||
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, -wg.active_window_id))
|
||||
borders.append(BorderLine(e2, color, wg.active_window_id))
|
||||
borders.append(BorderLine(e1, color, -wg.active_window_id, not is_horizontal))
|
||||
borders.append(BorderLine(e2, color, wg.active_window_id, not is_horizontal))
|
||||
|
||||
last_idx = len(borders) - 1 - end_offset
|
||||
for i, x in enumerate(borders):
|
||||
|
|
|
|||
|
|
@ -259,8 +259,7 @@ border_contains_mouse(BorderRect *br, double tolerance, Edge *edges) {
|
|||
double x = global_state.callback_os_window->mouse_x, y = global_state.callback_os_window->mouse_y;
|
||||
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 < 0 ? LEFT_EDGE : RIGHT_EDGE;
|
||||
if (!br->horizontal) *edges |= br->border_type < 0 ? LEFT_EDGE : RIGHT_EDGE;
|
||||
else *edges |= br->border_type < 0 ? TOP_EDGE : BOTTOM_EDGE;
|
||||
}
|
||||
return ans;
|
||||
|
|
@ -927,18 +926,20 @@ window_for_event(unsigned int *window_idx, bool *in_tab_bar, Edge *window_border
|
|||
double tolerance = ((long)round((OPT(window_drag_tolerance) * (dpi / 72.0))));
|
||||
BorderRect *closest_vert = NULL, *closest_horiz = NULL;
|
||||
double closest_vert_dist = (double)UINT_MAX, closest_horiz_dist = (double)UINT_MAX;
|
||||
bool is_within_border_without_tolerance = false;
|
||||
for (unsigned i = 0; i < t->border_rects.num_border_rects; i++) {
|
||||
BorderRect *br = t->border_rects.rect_buf + i;
|
||||
if (!br->border_type) continue;
|
||||
Edge edges = 0;
|
||||
if (border_contains_mouse(br, 0, &edges)) {
|
||||
*window_border |= edges;
|
||||
is_within_border_without_tolerance = true;
|
||||
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) {
|
||||
if (!br->horizontal) {
|
||||
double d = br->px.left + width/2. - w->mouse_x; d = d*d;
|
||||
if (d < closest_vert_dist) { closest_vert_dist = d; closest_vert = br; }
|
||||
} else {
|
||||
|
|
@ -947,10 +948,12 @@ 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) && !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 (!is_within_border_without_tolerance) {
|
||||
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++)
|
||||
|
|
|
|||
|
|
@ -614,14 +614,15 @@ pyset_borders_rects(PyObject *self UNUSED, PyObject *args) {
|
|||
PyObject *pr = PyList_GET_ITEM(rects, i);
|
||||
unsigned long color; long long border_type;
|
||||
BorderRect *r = br->rect_buf + i;
|
||||
int horizontal;
|
||||
if (!PyArg_ParseTuple(
|
||||
pr, "IIIIkL", &r->px.left, &r->px.top, &r->px.right, &r->px.bottom, &color, &border_type
|
||||
pr, "IIIIkLp", &r->px.left, &r->px.top, &r->px.right, &r->px.bottom, &color, &border_type, &horizontal
|
||||
)) return NULL;
|
||||
r->left = gl_pos_x(r->px.left, osw->viewport_width);
|
||||
r->top = gl_pos_y(r->px.top, osw->viewport_height);
|
||||
r->right = r->left + gl_size(r->px.right - r->px.left, osw->viewport_width);
|
||||
r->bottom = r->top - gl_size(r->px.bottom - r->px.top, osw->viewport_height);
|
||||
r->color = color; r->border_type = border_type;
|
||||
r->color = color; r->border_type = border_type; r->horizontal = horizontal;
|
||||
}
|
||||
END_WITH_TAB
|
||||
Py_RETURN_NONE;
|
||||
|
|
|
|||
|
|
@ -241,6 +241,7 @@ typedef struct BorderRect {
|
|||
struct { unsigned left, top, right, bottom; } px;
|
||||
uint32_t color;
|
||||
long long border_type;
|
||||
bool horizontal;
|
||||
} BorderRect;
|
||||
|
||||
typedef struct BorderRects {
|
||||
|
|
|
|||
Loading…
Reference in a new issue