mirror of
https://github.com/labwc/labwc.git
synced 2026-04-12 08:21:13 -04:00
added functions to find lowest and rightmost point to fix wrapping
This commit is contained in:
parent
29cb807850
commit
f37fecd04d
1 changed files with 75 additions and 40 deletions
115
src/action.c
115
src/action.c
|
|
@ -673,73 +673,108 @@ run_if_action(struct view *view, struct server *server, struct action *action)
|
||||||
return !strcmp(branch, "then");
|
return !strcmp(branch, "then");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rightmost_visible_point(struct server *server, struct view *view)
|
||||||
|
{
|
||||||
|
struct output *output = view->output;
|
||||||
|
struct wlr_box usable = output_usable_area_in_layout_coords(output);
|
||||||
|
struct wlr_box o_usable;
|
||||||
|
struct output *o;
|
||||||
|
int rightmost_point = usable.x + usable.width;
|
||||||
|
int cy = view->current.y + view->current.height/2;
|
||||||
|
wl_list_for_each(o, &server->outputs, link) {
|
||||||
|
if (!output_is_usable(o)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
o_usable = output_usable_area_in_layout_coords(o);
|
||||||
|
if (o_usable.x >= rightmost_point
|
||||||
|
&& o_usable.y <= cy
|
||||||
|
&& o_usable.y + o_usable.height >= cy) {
|
||||||
|
rightmost_point = o_usable.x + o_usable.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rightmost_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
lowest_visible_point(struct server *server, struct view *view)
|
||||||
|
{
|
||||||
|
struct output *output = view->output;
|
||||||
|
struct wlr_box usable = output_usable_area_in_layout_coords(output);
|
||||||
|
struct wlr_box o_usable;
|
||||||
|
struct output *o;
|
||||||
|
int lowest_point = usable.y + usable.height;
|
||||||
|
int cx = view->current.x + view->current.width/2;
|
||||||
|
wl_list_for_each(o, &server->outputs, link) {
|
||||||
|
if (!output_is_usable(o)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
o_usable = output_usable_area_in_layout_coords(o);
|
||||||
|
if (o_usable.y >= lowest_point
|
||||||
|
&& o_usable.x <= cx
|
||||||
|
&& o_usable.x + o_usable.width >= cx) {
|
||||||
|
lowest_point = o_usable.y + o_usable.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lowest_point;
|
||||||
|
}
|
||||||
|
|
||||||
static struct view*
|
static struct view*
|
||||||
directional_target_window(struct view *view, struct server *server,
|
directional_target_window(struct view *view, struct server *server,
|
||||||
enum view_edge direction, bool wrap)
|
enum view_edge direction, bool wrap)
|
||||||
{
|
{
|
||||||
int dx, dy, distance, distance_wrap;
|
assert(view);
|
||||||
struct view *v;
|
struct view *v;
|
||||||
struct output *v_output;
|
|
||||||
struct wlr_box v_usable;
|
|
||||||
struct view *closest_view = NULL;
|
struct view *closest_view = NULL;
|
||||||
struct view *closest_view_wrap = NULL;
|
struct view *closest_view_wrap = NULL;
|
||||||
int min_distance = INT_MAX;
|
|
||||||
int min_distance_wrap = INT_MAX;
|
|
||||||
struct output *output = view->output;
|
struct output *output = view->output;
|
||||||
struct wlr_box usable = output_usable_area_in_layout_coords(output);
|
struct wlr_box usable = output_usable_area_in_layout_coords(output);
|
||||||
int cx = view->current.x + view->current.width / 2;
|
float dx, dy, distance, distance_wrap;
|
||||||
int cy = view->current.y + view->current.height / 2;
|
int min_distance = INT_MAX;
|
||||||
assert(view);
|
int min_distance_wrap = INT_MAX;
|
||||||
for_each_view(v, &server->views,
|
for_each_view(v, &server->views,
|
||||||
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
|
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE) {
|
||||||
if (v->minimized) {
|
if (v->minimized) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
v_output = v->output;
|
distance = INT_MAX;
|
||||||
v_usable = output_usable_area_in_layout_coords(v_output);
|
|
||||||
dx = v->current.x + v->current.width/2 - cx;
|
|
||||||
dy = v->current.y + v->current.height/2 - cy;
|
|
||||||
distance = dx * dx + dy * dy;
|
|
||||||
distance_wrap = INT_MAX;
|
distance_wrap = INT_MAX;
|
||||||
|
dx = v->current.x + v->current.width/2.
|
||||||
|
- view->current.x - view->current.width/2.;
|
||||||
|
dy = v->current.y + v->current.height/2.
|
||||||
|
- view->current.y - view->current.height/2.;
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case VIEW_EDGE_LEFT:
|
case VIEW_EDGE_LEFT:
|
||||||
if (dx == 0) {
|
if (dx < 0 && dy*dy/(dx*dx) < 2) {
|
||||||
continue;
|
distance = (dx*dx + dy*dy) * (1 + dy*dy/(dx*dx));
|
||||||
}
|
} else if (dx > 0 && dy*dy/(dx*dx) < 2) {
|
||||||
if (dx > 0) {
|
dx = rightmost_visible_point(server, v) - dx;
|
||||||
distance = INT_MAX;
|
distance_wrap = (dx*dx + dy*dy) * (1 + dy*dy/(dx*dx));
|
||||||
dx = v_usable.x + v_usable.width - dx;
|
|
||||||
distance_wrap = dx * dx + dy * dy;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VIEW_EDGE_RIGHT:
|
case VIEW_EDGE_RIGHT:
|
||||||
if (dx == 0) {
|
if (dx > 0 && dy*dy/(dx*dx) < 2) {
|
||||||
continue;
|
distance = (dx*dx + dy*dy) * (1 + dy*dy/(dx*dx));
|
||||||
}
|
} else if (dx < 0 && dy*dy/(dx*dx) < 2) {
|
||||||
if (dx < 0) {
|
|
||||||
distance = INT_MAX;
|
|
||||||
dx = usable.x + usable.width + dx;
|
dx = usable.x + usable.width + dx;
|
||||||
distance_wrap = dx * dx + dy * dy;
|
distance_wrap = (dx*dx + dy*dy) * (1 + dy*dy/(dx*dx));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case VIEW_EDGE_UP:
|
case VIEW_EDGE_UP:
|
||||||
if (dy == 0) {
|
if (dy < 0 && dx*dx/(dy*dy) < 2) {
|
||||||
continue;
|
distance = (dx * dx + dy * dy) * (1 + dx*dx/(dy*dy));
|
||||||
}
|
} else if (dy > 0 && dx*dx/(dy*dy) < 2) {
|
||||||
if (dy > 0) {
|
dy = lowest_visible_point(server, v) - dy;
|
||||||
distance = INT_MAX;
|
distance_wrap = (dx*dx + dy*dy) * (1 + dx*dx/(dy*dy));
|
||||||
dy = v_usable.y + v_usable.height - dy;
|
|
||||||
distance_wrap = dx * dx + dy * dy;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case VIEW_EDGE_DOWN:
|
case VIEW_EDGE_DOWN:
|
||||||
if (dy == 0) {
|
if (dy > 0 && dx*dx/(dy*dy) < 2) {
|
||||||
continue;
|
distance = (dx*dx + dy*dy) * (1 + dx*dx/(dy*dy));
|
||||||
}
|
} else if (dy < 0 && dx*dx/(dy*dy) < 2) {
|
||||||
if (dy < 0) {
|
|
||||||
distance = INT_MAX;
|
|
||||||
dy = usable.y + usable.height + dy;
|
dy = usable.y + usable.height + dy;
|
||||||
distance_wrap = dx * dx + dy * dy;
|
distance_wrap = (dx*dx + dy*dy) * (1 + dx*dx/(dy*dy));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -756,7 +791,7 @@ directional_target_window(struct view *view, struct server *server,
|
||||||
if (closest_view) {
|
if (closest_view) {
|
||||||
return closest_view;
|
return closest_view;
|
||||||
}
|
}
|
||||||
if (closest_view_wrap && wrap) {
|
if (wrap && closest_view_wrap) {
|
||||||
return closest_view_wrap;
|
return closest_view_wrap;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue