Skip to content

Commit

Permalink
Adjust windows to fit working area after move.
Browse files Browse the repository at this point in the history
When moving windows, it made sense to consider the working area
base struts before the move when the base struts were on the
global view port. Now that the base struts are per monitor this
no longer makes sense, and caused strange behavior when computing
where to move a window.

Instead the window's position should be adjusted to fit inside the
working area after the move is done. This way the position of the
window is always computed relative to the global screen (unless the
'screen RANDR_NAME' option is provided).
  • Loading branch information
somiaj committed Oct 13, 2024
1 parent e660993 commit 601d63f
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 22 deletions.
4 changes: 2 additions & 2 deletions fvwm/ewmh.c
Original file line number Diff line number Diff line change
Expand Up @@ -1116,9 +1116,9 @@ void EWMH_UpdateWorkArea(struct monitor *m)
}

void EWMH_GetWorkAreaIntersection(
FvwmWindow *fw, int *x, int *y, int *w, int *h, int type)
struct monitor *mon, int *x, int *y, int *w, int *h, int type)
{
struct monitor *m = (fw && fw->m) ? fw->m : monitor_get_current();
struct monitor *m = (mon) ? mon : monitor_get_current();

EWMH_UpdateWorkArea(m);

Expand Down
2 changes: 1 addition & 1 deletion fvwm/ewmh.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void EWMH_SetClientList(struct monitor *);
void EWMH_SetClientListStacking(struct monitor *);
void EWMH_UpdateWorkArea(struct monitor *);
void EWMH_GetWorkAreaIntersection(
FvwmWindow *fw, int *x, int *y, int *w, int *h, int type);
struct monitor *mon, int *x, int *y, int *w, int *h, int type);
float EWMH_GetBaseStrutIntersection(struct monitor *m,
int x11, int y11, int x12, int y12, Bool use_percent);
float EWMH_GetStrutIntersection(struct monitor *m,
Expand Down
53 changes: 37 additions & 16 deletions fvwm/move_resize.c
Original file line number Diff line number Diff line change
Expand Up @@ -738,13 +738,6 @@ int GetMoveArguments(FvwmWindow *fw,
token = PeekToken(action, &action);
parg.name = token;

/* When being asked to move a window to coordinates which are
* relative to a given screen, don't assume to use the
* screen's working area, as the coordinates given are not
* relative to that.
*/
use_working_area = False;

FScreenGetScrRect(
&parg, FSCREEN_BY_NAME, &scr_pos.x, &scr_pos.y,
&scr_w, &scr_h);
Expand Down Expand Up @@ -789,13 +782,6 @@ int GetMoveArguments(FvwmWindow *fw,
}
}

if (use_working_area)
{
EWMH_GetWorkAreaIntersection(
NULL, &scr_pos.x, &scr_pos.y, &scr_w, &scr_h,
EWMH_USE_WORKING_AREA);
}

if (s1 != NULL && s2 != NULL)
{
int n;
Expand Down Expand Up @@ -849,6 +835,41 @@ int GetMoveArguments(FvwmWindow *fw,
pFinal->x -= (use_virt_x) ? m->virtual_scr.Vx : 0;
pFinal->y -= (use_virt_y) ? m->virtual_scr.Vy : 0;
}
if (use_working_area)
{
struct monitor *m = FindScreenOfXY(
pFinal->x, pFinal->y);
int dx = monitor_get_all_widths();
int dy = monitor_get_all_heights();
int x = pFinal->x % dx;
int y = pFinal->y % dy;

if (x < 0)
x += dx;
if (y < 0)
y += dy;

dx = dy = 0;
EWMH_GetWorkAreaIntersection(
m, &scr_pos.x, &scr_pos.y, &scr_w, &scr_h,
EWMH_USE_WORKING_AREA);
if (x < scr_pos.x) {
dx = scr_pos.x - x;
} else if (x + s.width > scr_pos.x + scr_w) {
dx = scr_pos.x + scr_w - x - s.width;
if (x + dx < scr_pos.x)
dx = scr_pos.x - x;
}
if (y < scr_pos.y) {
dy = scr_pos.y - y;
} else if (y + s.height > scr_pos.y + scr_h) {
dy = scr_pos.y + scr_h - y - s.height;
if (y + dy < scr_pos.y)
dy = scr_pos.y - y;
}
pFinal->x += dx;
pFinal->y += dy;
}
}
else
{
Expand Down Expand Up @@ -4426,7 +4447,7 @@ static Bool _resize_window(F_CMD_ARGS)
FQueryPointer(
dpy, Scr.Root, &JunkRoot, &JunkChild, &x,
&y, &JunkX, &JunkY, &JunkMask);

fev_make_null_event(&e2, dpy);
e2.type = MotionNotify;
e2.xmotion.time = fev_get_evtime();
Expand Down Expand Up @@ -5239,7 +5260,7 @@ void CMD_Maximize(F_CMD_ARGS)
if (!ignore_working_area)
{
EWMH_GetWorkAreaIntersection(
fw, &scr.x, &scr.y, &scr.width, &scr.height,
fw->m, &scr.x, &scr.y, &scr.width, &scr.height,
EWMH_MAXIMIZE_MODE(fw));
}
#if 0
Expand Down
6 changes: 3 additions & 3 deletions fvwm/placement.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ static pl_penalty_t _pl_position_get_pos_simple(
* options.
*/
EWMH_GetWorkAreaIntersection(
arg->place_fw, (int *)&arg->screen_g.x, (int *)&arg->screen_g.y,
(int *)&arg->screen_g.width,
arg->place_fw->m, (int *)&arg->screen_g.x,
(int *)&arg->screen_g.y, (int *)&arg->screen_g.width,
(int *)&arg->screen_g.height, EWMH_USE_WORKING_AREA);

if (ret_p->x + arg->place_fw->g.frame.width > arg->screen_g.x
Expand Down Expand Up @@ -1812,7 +1812,7 @@ static int _place_window(
* for this placement policy.
*/
EWMH_GetWorkAreaIntersection(
fw, &screen_g.x, &screen_g.y, &screen_g.width,
fw->m, &screen_g.x, &screen_g.y, &screen_g.width,
&screen_g.height,
SEWMH_PLACEMENT_MODE(&pstyle->flags));
reason->screen.was_modified_by_ewmh_workingarea = 1;
Expand Down

0 comments on commit 601d63f

Please sign in to comment.