Skip to content

Commit

Permalink
Add Move relative to virtual screen option.
Browse files Browse the repository at this point in the history
  A new Move prefix 'v' was added, which allows coordinates to be
  specified relative to the virtual screen with (0,0) the top left
  corner. This is best used with the 'p' suffix, so you can state
  the exact location to move in the virtual screen vs relative
  to a specific monitor. This is mostly meant to be used from
  FvwmPager.

  Update FvwmPager to use the new 'v' prefix when Moving windows.
  This makes it so no longer does FvwmPager need to worry about
  which monitor the move command is relative too. This fixes
  moving windows around the pager on different desks.
  • Loading branch information
somiaj committed Mar 25, 2024
1 parent a6a6f79 commit 0026c11
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 65 deletions.
9 changes: 6 additions & 3 deletions doc/fvwm3_manpage_source.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3927,7 +3927,7 @@ Move shuffle Up Left
*Move* can be used to moved a window to a specified position:
+

> *Move* [screen _S_] \[w | m]_x_[p | w] \[w | m]_y_[p | w] [Warp] [ewmhiwa]
> *Move* [screen _S_] \[w | m | v]_x_[p | w] \[w | m | v]_y_[p | w] [Warp] [ewmhiwa]

+
This will move the window to the _x_ and _y_ position (see below).
Expand All @@ -3950,8 +3950,11 @@ while a trailing '_w_' means percent of the window width/height. To move the
window relative to its current position, add the '_w_' (for "window") prefix
before the _x_ and/or _y_ value. To move the window to a position relative to
the current location of the pointer, add the '_m_' (for "mouse") prefix. To
leave either coordinate unchanged, "_keep_" can be specified in place of
_x_ or _y_.
move the window relative to the virtual screen coordinates, add the '_v_'
(for "virtual screen") prefix. This is mostly for internal use with FvwmPager,
but can be used to give exact coordinates on the virtual screen and is best
used with the '_p_' suffix. To leave either coordinate unchanged, "_keep_"
can be specified in place of _x_ or _y_.
+
For advanced uses, the arguments _x_ and _y_ can be used multiple
times, but without the prefix '_m_' or '_w_'. (See complex examples
Expand Down
59 changes: 47 additions & 12 deletions fvwm/move_resize.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ static int GetOnePositionArgument(
{
int final_pos;
int pos_change = 0;
int return_val = 1;
float wfactor;

if (s1 == 0 || *s1 == 0)
Expand All @@ -571,6 +572,12 @@ static int GetOnePositionArgument(
final_pos = window_pos;
s1++;
break;
case 'v':
case 'V':
final_pos = 0;
return_val = 2;
s1++;
break;
case 'm':
case 'M':
{
Expand Down Expand Up @@ -677,7 +684,7 @@ static int GetOnePositionArgument(
}
*pFinalPos = final_pos;

return 1;
return return_val;
}

/* GetMoveArguments is used for Move & AnimatedMove
Expand All @@ -688,6 +695,8 @@ static int GetOnePositionArgument(
* 10p -0p Absolute pixel position, from bottom
* w+5 w-10p Relative position, right 5%, up ten pixels
* m+5 m-10p Pointer relative position, right 5%, up ten pixels
* v+5p v+10p Virtual screen absolute position, place at position
* (5p,10p) in the virtual screen, with (0p,0p) top left.
* Returns 2 when x & y have parsed without error, 0 otherwise
*/
int GetMoveArguments(FvwmWindow *fw,
Expand All @@ -704,6 +713,7 @@ int GetMoveArguments(FvwmWindow *fw,
int scr_h = monitor_get_all_heights();
Bool use_working_area = True;
Bool global_flag_parsed = False;
int use_virt_scr = 0;
int retval = 0;

if (!paction)
Expand Down Expand Up @@ -786,34 +796,59 @@ int GetMoveArguments(FvwmWindow *fw,

if (s1 != NULL && s2 != NULL)
{
int n;
retval = 0;
if (fKeep == True && StrEquals(s1, "keep"))
{
retval++;
}
else if (
GetOnePositionArgument(
s1, pFinal->x, s.width, &(pFinal->x),
(float)scr_w / 100, scr_w, scr_pos.x, True))
else
{
retval++;
n = GetOnePositionArgument(
s1, pFinal->x, s.width, &(pFinal->x),
(float)scr_w / 100, scr_w, scr_pos.x, True);
if (n > 0)
{
retval++;
if (n == 2)
{
use_virt_scr++;
}
}
}
if (fKeep == True && StrEquals(s2, "keep"))
{
retval++;
}
else if (
GetOnePositionArgument(
s2, pFinal->y, s.height, &(pFinal->y),
(float)scr_h / 100, scr_h, scr_pos.y, False))
else
{
retval++;
n = GetOnePositionArgument(
s2, pFinal->y, s.height, &(pFinal->y),
(float)scr_h / 100, scr_h, scr_pos.y, False);
if (n > 0)
{
retval++;
if (n == 2)
{
use_virt_scr += 2;
}
}
}
if (retval == 0)
if (retval < 2)
{
/* make sure warping is off for interactive moves */
*fWarp = False;
}
else
{
/* Adjust based on use_virtual_screen
* 0: none, 1: x only, 2: y only, 3: both
*/
struct monitor *m = FindScreenOfXY(
pFinal->x, pFinal->y);
pFinal->x -= (use_virt_scr % 2) * m->virtual_scr.Vx;
pFinal->y -= (use_virt_scr / 2) * m->virtual_scr.Vy;
}
}
else
{
Expand Down
93 changes: 43 additions & 50 deletions modules/FvwmPager/x_pager.c
Original file line number Diff line number Diff line change
Expand Up @@ -2758,58 +2758,49 @@ void MoveWindow(XEvent *Event)
NewDesk = ndesks - 1;
}

/* FIXME: This math can loose sync of window locations. */
XTranslateCoordinates(dpy, Scr.Pager_w, Desks[NewDesk].w,
x - rec.x, y - rec.y, &rec.x, &rec.y, &dumwin);
x - rec.x, y - rec.y, &rec.x, &rec.y,
&dumwin);

fp = fpmonitor_from_xy(rec.x * fp->virtual_scr.VWidth / desk_w,
rec.y * fp->virtual_scr.VHeight / desk_h, false);
rec.y * fp->virtual_scr.VHeight / desk_h, false);
pagerrec_to_fvwm(&rec, false, fp);
rec.x = rec.x - fp->virtual_scr.Vx;
rec.y = rec.y - fp->virtual_scr.Vy;
t->m = fp->m;

if (NewDesk + desk1 != t->desk) {
if ((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_DESKS(t))
|| (IS_STICKY_ACROSS_DESKS(t))) {
NewDesk = fp->m->virtual_scr.CurrentDesk - desk1;
if (t->desk != fp->m->virtual_scr.CurrentDesk)
ChangeDeskForWindow(t,fp->m->virtual_scr.CurrentDesk);
}
else if (NewDesk + desk1 != fp->m->virtual_scr.CurrentDesk) {
snprintf(command, sizeof(command), "Silent MoveToDesk 0 %d",
NewDesk + desk1);
SendText(fd, command, t->w);
t->desk = NewDesk + desk1;
} else {
do_switch_desk_later = 1;
}
}

if (NewDesk >= 0 && NewDesk < ndesks)
if (NewDesk + desk1 != t->desk &&
((IS_ICONIFIED(t) && IS_ICON_STICKY_ACROSS_DESKS(t))
|| (IS_STICKY_ACROSS_DESKS(t))))
{
XReparentWindow(dpy, t->PagerView,
Desks[NewDesk].w, rec.x, rec.y);
t->desk = NewDesk;
XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True);
if (moved) {
char buf[64];
/* XXX: Note the use of ewmhiwa to disable
* clipping the coordinates to the wrong area!
*/
snprintf(buf, sizeof(buf), "Silent Move +%dp +%dp ewmhiwa",
rec.x, rec.y);
SendText(fd, buf, t->w);
XSync(dpy,0);
} else {
MoveResizePagerView(t, True);
}
SendText(fd, "Silent Raise", t->w);
NewDesk = fp->m->virtual_scr.CurrentDesk - desk1;
if (t->desk != fp->m->virtual_scr.CurrentDesk)
ChangeDeskForWindow(t,
fp->m->virtual_scr.CurrentDesk);
} else {
do_switch_desk_later = 1;
}

XReparentWindow(dpy, t->PagerView,
Desks[NewDesk].w, rec.x, rec.y);
XClearArea(dpy, t->PagerView, 0, 0, 0, 0, True);
if (moved) {
char buf[64];
/* XXX: Note the use of ewmhiwa to disable
* clipping the coordinates to the wrong area!
*/
snprintf(buf, sizeof(buf),
"Silent Move v+%dp v+%dp ewmhiwa",
rec.x, rec.y);
SendText(fd, buf, t->w);
XSync(dpy,0);
t->m = fp->m;
} else {
MoveResizePagerView(t, True);
}
SendText(fd, "Silent Raise", t->w);

if (do_switch_desk_later) {
snprintf(command, sizeof(command), "Silent MoveToDesk 0 %d", NewDesk +
desk1);
snprintf(command, sizeof(command),
"Silent MoveToDesk 0 %d",
NewDesk + desk1);
SendText(fd, command, t->w);
t->desk = NewDesk + desk1;
}
Expand Down Expand Up @@ -3167,16 +3158,18 @@ void IconMoveWindow(XEvent *Event, PagerWindow *t)
} else {
rec.x = x - rec.x;
rec.y = y - rec.y;
fp = fpmonitor_from_xy(rec.x * fp->virtual_scr.VWidth / icon.width,
rec.y * fp->virtual_scr.VHeight / icon.height, false);
pagerrec_to_fvwm(&rec, true, fp);
rec.x = rec.x - fp->virtual_scr.Vx;
rec.y = rec.y - fp->virtual_scr.Vy;

if (moved) {
char buf[64];
snprintf(buf, sizeof(buf), "Silent Move +%dp +%dp ewmhiwa",
rec.x, rec.y);
fp = fpmonitor_from_xy(
rec.x * fp->virtual_scr.VWidth / icon.width,
rec.y * fp->virtual_scr.VHeight / icon.height,
false);
pagerrec_to_fvwm(&rec, true, fp);
t->m = fp->m;
snprintf(buf, sizeof(buf),
"Silent Move v+%dp v+%dp ewmhiwa",
rec.x, rec.y);
SendText(fd, buf, t->w);
XSync(dpy, 0);
} else {
Expand Down

0 comments on commit 0026c11

Please sign in to comment.