mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 02:00:06 +02:00
Arrange the desktop's outputs the way the screens are around you
KWin's output positions now follow where the Frametop screens are in the room instead of their numbers: a screen you see to the left of another is to its left in Plasma, so the pointer and dragged windows cross straight to it. Screens one above the other stack, and wrist-pinned screens go last. ft-layout scale works this out from ft-screens' head pose and screen poses, and runs after arranging, capturing, or pinning; ft-screens runs it half a second after a screen is let go. With no head pose (headset off) KWin's order is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c43418085d
commit
e84ac22313
3 files changed
+104
-10
No files matched your search
@@ -41,7 +41,12 @@
|
||||
|
||||
#include <openvr.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <linux/input-event-codes.h>
|
||||
#include <limits.h>
|
||||
#include <spawn.h>
|
||||
|
||||
extern char **environ; // for posix_spawn
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
@@ -854,6 +859,33 @@ void EndDrag(Screen &s) {
|
||||
ApplyAlpha(s);
|
||||
}
|
||||
|
||||
// KWin's outputs follow where the screens are, so the pointer and dragged windows cross
|
||||
// to the screen you see next to this one: `ft-layout scale` runs once a move has settled.
|
||||
long g_arrangeAt = -1; // g_tick to run it at, -1 = not pending
|
||||
|
||||
void ArrangeDesktopSoon() { g_arrangeAt = g_tick + 45; } // about half a second
|
||||
|
||||
void UpdateArrange() {
|
||||
if (g_arrangeAt < 0 || g_tick < g_arrangeAt) return;
|
||||
g_arrangeAt = -1;
|
||||
char exe[PATH_MAX];
|
||||
if (!realpath("/proc/self/exe", exe)) return;
|
||||
std::string layout(exe); // <repo>/screens/build/ft-screens -> <repo>/layout/ft-layout
|
||||
for (int up = 0; up < 3 && layout.rfind('/') != std::string::npos; ++up) layout.resize(layout.rfind('/'));
|
||||
layout += "/layout/ft-layout";
|
||||
posix_spawn_file_actions_t io;
|
||||
posix_spawn_file_actions_init(&io);
|
||||
posix_spawn_file_actions_addopen(&io, 0, "/dev/null", O_RDONLY, 0);
|
||||
posix_spawn_file_actions_addopen(&io, 1, "/tmp/frametop-layout.log", O_WRONLY | O_CREAT | O_APPEND, 0644);
|
||||
posix_spawn_file_actions_adddup2(&io, 1, 2);
|
||||
char scale[] = "scale";
|
||||
char *argv[] = {layout.data(), scale, nullptr};
|
||||
pid_t pid; // reaped by the compositor's SIGCHLD handler
|
||||
if (posix_spawn(&pid, layout.c_str(), &io, nullptr, argv, environ) != 0)
|
||||
std::printf("can't run %s\n", layout.c_str());
|
||||
posix_spawn_file_actions_destroy(&io);
|
||||
}
|
||||
|
||||
// Let go: pin to the armed wrist, as the screen is now.
|
||||
void FinishDrag(Screen &s, int index) {
|
||||
const bool moved = s.drag == Drag::Move;
|
||||
@@ -861,6 +893,7 @@ void FinishDrag(Screen &s, int index) {
|
||||
EndDrag(s);
|
||||
Mat c, p;
|
||||
if (!moved) return;
|
||||
ArrangeDesktopSoon();
|
||||
if (target != kNone && DevicePose(target, &c) && ScreenPose(s, &p)) {
|
||||
Pin(s, target, Mul(Inverse(c), p));
|
||||
std::printf("screen %d: pinned to the %s controller\n", index + 1, HandName(target));
|
||||
@@ -1228,6 +1261,7 @@ void ft_vr_poll(void (*handle)(const struct ft_event *, void *), void *data) {
|
||||
}
|
||||
++g_tick;
|
||||
UpdateGame();
|
||||
UpdateArrange();
|
||||
UpdateVisibility();
|
||||
UpdateLasers();
|
||||
UpdateControls();
|
||||
|
||||
Reference in new issue
Block a user