Skip to content

Commit

Permalink
DesktopConfiguration: shared mode
Browse files Browse the repository at this point in the history
This teaches the DesktopConfiguration command about a new option:
shared.  When in this mode, a shared state means that's there one set of
desktops (defined via the `DesktopName` command), but these desks are
global to all monitors, yet monitors may independently selected which
desktop to show at that time.

If a request to move to a particular desktop matches one already shown
on a different monitors, these two desks are exchanged between those
monitors.

Fixes #260
  • Loading branch information
ThomasAdam committed May 16, 2021
1 parent 08ddbf0 commit 6527cd3
Show file tree
Hide file tree
Showing 13 changed files with 559 additions and 42 deletions.
66 changes: 66 additions & 0 deletions dev-docs/DESKTOPS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
Desktop Thoughts
================

Fvwm3 has two modes for handling desktops:

* `global` -- all connected monitors share the same desktop
* `per-monitor` -- all desktops defined by `DesktopName` are separate from one
another.

A third mode is suggested: `shared`.


Shared would operate much like spectrwm does now:

So for example, let's say you had the following number of desktops:

```
0 1 2 3 4
```

... and let's say that you have two monitors. You might have this:

```
[0] 1 2 <3> 4
```

Where `[]` is monitor1 and `<>` is monitor2.

You could move monitor1 (`[]`) all the way along to desktop 2, without changing where monitor2 (`<>`) is, as in:

```
0 1 [2] <3> 4
```

If you were to then continue to move monitor1 (`[]`) to desktop 3, what would happen is this:

```
0 1 <2> [3] 4
```

So that now, the desktops have switched over from each monitor.

FVWM3 Changes
=============

In order to provide this feature, fvwm3 needs to try and structure things such
that existing `DesktopConfiguration` modes are not broken by this
implementation. Unlike with other modes, this `shared` mode is not a
structure suited to isolation per-monitor, thus this breaks the conceptual
model.

In order for `fvwm3` to sustain all three models, the following should be
true:

* When setting `shared`:

1. Initialise the shared desktop environment.
2. Existing windows per desktop should be migrated to the share env.
3. All monitors should be scanned. They need to be placed on different desktops.
4. On a switch to a new desktop (regardless of page) if a desktop:
* Is mapped:
* Swap the desktop:
* Mark the windows on the current monitor
* Move the windows on the *other* monitor to this monitor's desk
* Switch desktops
* Move the marked windows from this monitor to the other monitor.
101 changes: 101 additions & 0 deletions dev-docs/shareddesks
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
DesktopConfiguration per-monitor
SetEnv RXVT "urxvt -b 5 -bd '#333333'"

ModuleTimeout 1
EdgeResistance 800 1
EdgeThickness 2
IgnoreModifiers L25

DesktopName 0 0
DesktopName 1 1
DesktopName 2 2
DesktopName 3 3
DesktopName 4 4
DesktopName 5 5

DesktopSize 1x1

Key Right A C GotoDesk next
Key Left A C GotoDesk -1 0 0 5

# Window key-bindings
Key i A 4 Iconify

Key Left A 4 Direction West (CurrentDesk, AcceptsFocus, Visible) Focus
Key Right A 4 Direction East (CurrentDesk, AcceptsFocus, Visible) Focus
Key Up A 4 Direction North (CurrentDesk, AcceptsFocus, Visible) Focus
Key Down A 4 Direction South (CurrentDesk, AcceptsFocus, Visible) Focus

Key Return A 4 Exec exec $[RXVT] -ls
Key Return A C Maximize grow grow
Key A W S4 Close
Key Down W M Lower
Key Up W M Raise
Key m W 4 Maximize

Key L A CM Exec exec i3lock -c '#2000FF'
Key S A 4 Stick

Key F12 A 4 Module FvwmConsole
#Key F12 A 4 Exec exec $[RXVT] -bg '#004103' -e FvwmPrompt

Key Up WTSF CM PackUp
Key Down WTSF CM PackDown
Key Left WTSF CM PackLeft
Key Right WTSF CM PackRight

Key p A C4 Exec exec rofi-pass
Key slash A M4 Exec exec rofi \
-levenshtein-sort \
-show window \
-bg '#66ba66' \
-fg black \
-hlbg white \
-hlfg black \
-bc 'blue' \
-bw 4 \
-columns 1 \
-lines 5 \
-fixed-num-lines 1 \
-width 40 \
-terminal xterm \
-hide-scrollbar \
-font "Monospace 12"

Key question A MS Exec exec rofi \
-levenshtein-sort \
-show run \
-bg '#66ba66' \
-fg black \
-hlbg white \
-hlfg black \
-bc 'blue' \
-bw 4 \
-columns 1 \
-lines 5 \
-fixed-num-lines 1 \
-width 40 \
-terminal xterm \
-hide-scrollbar \
-font "Monospace 12"

KillModule FvwmPager FP1
DestroyModuleConfig FP1: *
*FP1: Monitor DP1-8

Style FP1 StartsOnScreen DP1-8, Sticky, CirculateSkip
Module FvwmPager FP1 0 5

KillModule FvwmPager FP2
DestroyModuleConfig FP2: *
*FP2: Monitor DP1-1-8

Style FP2 StartsOnScreen DP1-1-8, Sticky, CirculateSkip
Module FvwmPager FP2 0 5

KillModule FvwmPager FP3
DestroyModuleConfig FP3: *
*FP3: Monitor HDMI2

Style FP3 StartsOnScreen HDMI2, Sticky, CirculateSkip
Module FvwmPager FP3 0 5
24 changes: 23 additions & 1 deletion doc/fvwm3/fvwm3.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7468,7 +7468,7 @@ Specifying an invalid decor results in all windows being updated.
names starting from desktop 0 are defined, then these names can be
used by any EWMH compliant application (as a pager).

*DesktopConfiguration* global | per-monitor::
*DesktopConfiguration* global | per-monitor | shared::
This command controls the behaviour of how desktops should be managed
by FVWM. By default, for all screens detected by FVWM through RandR
support, the option of global means that all windows on the same desk
Expand All @@ -7478,6 +7478,28 @@ Specifying an invalid decor results in all windows being updated.
With per-monitor , each RandR monitor has a separate copy of desktops,
and hence function independently of one another when switching
desks/pages.
+
When __shared__ is set, the desktops are shared amongst all monitors. So for
example, with the following number of desktops defined with two monitors
(__[]__ is monitor1, and __<>__ is monitor2):
+
....
[0] 1 2 <3> 4
....
+

Moving between desktops would still honor the monitor the desktop is being
requested on. If __monitor1__ wanted to switch to desktop 3, then that
desktop is exchanged with __monitor2__ such that the following showed the
active desktop on both monitors:
+
....
<0> 1 2 [3] 4
....
+
This concept is similar to how spectrwm or xmonad handles desktops.
+
**Note:** these each *DesktopConfiguration* mode can be changed on-the-fly.

*DesktopSize* __Horizontal__x_Vertical_::
Defines the virtual desktop size in units of the physical screen size.
Expand Down
23 changes: 21 additions & 2 deletions fvwm/add_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include "libs/Grab.h"
#include "libs/Strings.h"
#include "libs/XResource.h"
#include "libs/safemalloc.h"
#include "fvwm.h"
#include "externs.h"
#include "cursor.h"
Expand Down Expand Up @@ -89,6 +90,7 @@
#include "functions.h"
#include "virtual.h"
#include "builtins.h"
#include "expand.h"

/* ---------------------------- local definitions -------------------------- */

Expand Down Expand Up @@ -2489,7 +2491,12 @@ FvwmWindow *AddWindow(
{
struct monitor *tm = (fw && fw->m) ? fw->m :
monitor_get_current();
goto_desk(fw->Desk, tm);

char *cmd;

xasprintf(&cmd, "GotoDesk %s 0 %d", tm->si->name, fw->Desk);
execute_function_override_window(NULL, NULL, cmd, 0, fw);
free(cmd);

/* read the requested absolute geometry */
gravity_translate_to_northwest_geometry_no_bw(
Expand Down Expand Up @@ -2630,7 +2637,6 @@ FvwmWindow *AddWindow(
setup_key_and_button_grabs(fw);

/****** inform modules of new window ******/
UPDATE_FVWM_SCREEN(fw);
BroadcastConfig(M_ADD_WINDOW,fw);
BroadcastWindowIconNames(fw, True, False);

Expand Down Expand Up @@ -2808,6 +2814,19 @@ FvwmWindow *AddWindow(
fw = NULL;
}

if (is_tracking_shared && fw != NULL) {
/* If we're in `DesktopConfiguration shared` mode, reposition
* the window, for scenarios involving StartsOn{Screen,Desk}.
* In this cases, the window won't have been placed due to
* XGetGeometry() not knowing about the window.
*
* All other styles will have been applied.
*
* So now just adjust for StartsOn{Screen,Desk}
*/
adjust_for_shared_placement(fw, exc);
}

return fw;
}

Expand Down
8 changes: 7 additions & 1 deletion fvwm/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,14 @@ status_send(void)
m_cur = monitor_get_current();

bson_init(&msg);
BSON_APPEND_INT64(&msg, "version", 1);
BSON_APPEND_INT64(&msg, "version", 2);
BSON_APPEND_UTF8(&msg, "current_screen", m_cur->si->name);
BSON_APPEND_UTF8(&msg, "desktop_mode",
monitor_mode == MONITOR_TRACKING_G && is_tracking_shared ? "shared" :
monitor_mode == MONITOR_TRACKING_G ? "global" :
monitor_mode == MONITOR_TRACKING_M ? "per-monitor" :
"unknown");

BSON_APPEND_DOCUMENT_BEGIN(&msg, "screens", &screens);

d_count = 0;
Expand Down
1 change: 0 additions & 1 deletion fvwm/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -3163,7 +3163,6 @@ void HandleMapRequestKeepRaised(
}
MyXUngrabServer(dpy);

UPDATE_FVWM_SCREEN(fw);
break;

case IconicState:
Expand Down
1 change: 1 addition & 0 deletions fvwm/fvwm3.c
Original file line number Diff line number Diff line change
Expand Up @@ -2442,6 +2442,7 @@ int main(int argc, char **argv)
fvwm_debug(__func__, "Loading window states via %s", state_filename);
LoadWindowStates(state_filename);

is_tracking_shared = false;
TAILQ_FOREACH(m, &monitor_q, entry)
EWMH_Init(m);

Expand Down
Loading

0 comments on commit 6527cd3

Please sign in to comment.