2024-08-30 14:53:25 +00:00
|
|
|
/*
|
2024-09-17 19:00:25 +00:00
|
|
|
* Deskflow -- mouse and keyboard sharing utility
|
feat: inputcapture clipboard support
Send the clipboard over the libportal InputCapture portal. Only built
if the installed libportal has clipboard support.
AI disclosure: Claude was used on both sides of this work.
- Peter Hutterer: "The second commit was purely written by Claude
after I stared at this for too long without seeing any hope of
getting started. Turns out Claude wrote something that at least
looks correct and it does work. It needs review but also needs
knowledge of deskflow's internals that I don't have..."
- Nick Bolton: Claude also assisted with the follow-up work listed
below (image copy/paste, session re-request, race fixes, size/mime
validation, and CMake detection).
Server side (Wayland host, Peter Hutterer):
- Initial scaffolding for inputcapture clipboard support, guarded so it
only builds when the portal exposes the clipboard API.
- Integrate clipboard data into the inputcapture session so the host
clipboard can be offered to the remote (the Claude-written commit
referenced above).
Client side (Wayland receiver, KoljaFrahm):
- Receive clipboard data from the server and feed it into the local
clipboard through libportal. Built on the reference code by Peter:
https://github.com/whot/libportal-clipboard-test/tree/main
Build integration and rebase (Chris Rizzitello, sithlord48):
- Add the original CMake check for libportal/clipboard.h to define
HAVE_LIBPORTAL_CLIPBOARD, and guard the libportal clipboard use on
it.
- Update the code style and rebase onto the updated input capture
session persistence: https://github.com/deskflow/deskflow/pull/9415
Image support and reliability fixes (Nick Bolton):
- Support image copy/paste in addition to text, so screenshots and
other image clipboard contents work both ways through inputcapture.
- Re-request the input capture session when it comes up without a
clipboard, so new testers with existing sessions can get clipboard
functionality without needing to clear the session.
- Defer clipboard reads until the input capture session is active,
avoiding races where reads happen before the portal is ready.
- Fix assorted style issues in original commit to match conventions.
- Check the configured clipboard size limit and validate incoming
mime types before forwarding inputcapture clipboard data.
- Switch the CMake clipboard probe to check_symbol_exists so detection
matches what the compiler actually sees in the headers.
Co-authored-by: Nick Bolton <nick@symless.com>
Co-authored-by: KoljaFrahm <GitHub.Kolja@dfgh.net>
Co-authored-by: Chris Rizzitello <sithlord48@gmail.com>
2026-02-05 04:01:33 +00:00
|
|
|
* SPDX-FileCopyrightText: (C) 2024, 2026 Synergy App Ltd
|
|
|
|
|
* SPDX-FileCopyrightText: (C) 2022, 2026 Red Hat, Inc.
|
2025-01-24 00:11:17 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
2024-08-30 14:53:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
2025-06-03 01:28:01 +00:00
|
|
|
#include "deskflow/IScreen.h"
|
2024-09-17 19:00:25 +00:00
|
|
|
#include "deskflow/PlatformScreen.h"
|
2025-09-12 15:22:42 +00:00
|
|
|
#include "platform/XDGPowerManager.h"
|
2024-08-30 14:53:25 +00:00
|
|
|
|
feat: inputcapture clipboard support
Send the clipboard over the libportal InputCapture portal. Only built
if the installed libportal has clipboard support.
AI disclosure: Claude was used on both sides of this work.
- Peter Hutterer: "The second commit was purely written by Claude
after I stared at this for too long without seeing any hope of
getting started. Turns out Claude wrote something that at least
looks correct and it does work. It needs review but also needs
knowledge of deskflow's internals that I don't have..."
- Nick Bolton: Claude also assisted with the follow-up work listed
below (image copy/paste, session re-request, race fixes, size/mime
validation, and CMake detection).
Server side (Wayland host, Peter Hutterer):
- Initial scaffolding for inputcapture clipboard support, guarded so it
only builds when the portal exposes the clipboard API.
- Integrate clipboard data into the inputcapture session so the host
clipboard can be offered to the remote (the Claude-written commit
referenced above).
Client side (Wayland receiver, KoljaFrahm):
- Receive clipboard data from the server and feed it into the local
clipboard through libportal. Built on the reference code by Peter:
https://github.com/whot/libportal-clipboard-test/tree/main
Build integration and rebase (Chris Rizzitello, sithlord48):
- Add the original CMake check for libportal/clipboard.h to define
HAVE_LIBPORTAL_CLIPBOARD, and guard the libportal clipboard use on
it.
- Update the code style and rebase onto the updated input capture
session persistence: https://github.com/deskflow/deskflow/pull/9415
Image support and reliability fixes (Nick Bolton):
- Support image copy/paste in addition to text, so screenshots and
other image clipboard contents work both ways through inputcapture.
- Re-request the input capture session when it comes up without a
clipboard, so new testers with existing sessions can get clipboard
functionality without needing to clear the session.
- Defer clipboard reads until the input capture session is active,
avoiding races where reads happen before the portal is ready.
- Fix assorted style issues in original commit to match conventions.
- Check the configured clipboard size limit and validate incoming
mime types before forwarding inputcapture clipboard data.
- Switch the CMake clipboard probe to check_symbol_exists so detection
matches what the compiler actually sees in the headers.
Co-authored-by: Nick Bolton <nick@symless.com>
Co-authored-by: KoljaFrahm <GitHub.Kolja@dfgh.net>
Co-authored-by: Chris Rizzitello <sithlord48@gmail.com>
2026-02-05 04:01:33 +00:00
|
|
|
#include <climits>
|
2024-08-30 14:53:25 +00:00
|
|
|
#include <libei.h>
|
2025-11-06 23:09:36 +00:00
|
|
|
#include <map>
|
2024-08-30 14:53:25 +00:00
|
|
|
#include <mutex>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
struct ei;
|
|
|
|
|
struct ei_event;
|
|
|
|
|
struct ei_seat;
|
|
|
|
|
struct ei_device;
|
|
|
|
|
|
2026-06-25 03:31:30 +00:00
|
|
|
class EventQueueTimer;
|
|
|
|
|
|
2024-09-17 19:00:25 +00:00
|
|
|
namespace deskflow {
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
class EiKeyState;
|
|
|
|
|
class PortalRemoteDesktop;
|
|
|
|
|
class PortalInputCapture;
|
feat: inputcapture clipboard support
Send the clipboard over the libportal InputCapture portal. Only built
if the installed libportal has clipboard support.
AI disclosure: Claude was used on both sides of this work.
- Peter Hutterer: "The second commit was purely written by Claude
after I stared at this for too long without seeing any hope of
getting started. Turns out Claude wrote something that at least
looks correct and it does work. It needs review but also needs
knowledge of deskflow's internals that I don't have..."
- Nick Bolton: Claude also assisted with the follow-up work listed
below (image copy/paste, session re-request, race fixes, size/mime
validation, and CMake detection).
Server side (Wayland host, Peter Hutterer):
- Initial scaffolding for inputcapture clipboard support, guarded so it
only builds when the portal exposes the clipboard API.
- Integrate clipboard data into the inputcapture session so the host
clipboard can be offered to the remote (the Claude-written commit
referenced above).
Client side (Wayland receiver, KoljaFrahm):
- Receive clipboard data from the server and feed it into the local
clipboard through libportal. Built on the reference code by Peter:
https://github.com/whot/libportal-clipboard-test/tree/main
Build integration and rebase (Chris Rizzitello, sithlord48):
- Add the original CMake check for libportal/clipboard.h to define
HAVE_LIBPORTAL_CLIPBOARD, and guard the libportal clipboard use on
it.
- Update the code style and rebase onto the updated input capture
session persistence: https://github.com/deskflow/deskflow/pull/9415
Image support and reliability fixes (Nick Bolton):
- Support image copy/paste in addition to text, so screenshots and
other image clipboard contents work both ways through inputcapture.
- Re-request the input capture session when it comes up without a
clipboard, so new testers with existing sessions can get clipboard
functionality without needing to clear the session.
- Defer clipboard reads until the input capture session is active,
avoiding races where reads happen before the portal is ready.
- Fix assorted style issues in original commit to match conventions.
- Check the configured clipboard size limit and validate incoming
mime types before forwarding inputcapture clipboard data.
- Switch the CMake clipboard probe to check_symbol_exists so detection
matches what the compiler actually sees in the headers.
Co-authored-by: Nick Bolton <nick@symless.com>
Co-authored-by: KoljaFrahm <GitHub.Kolja@dfgh.net>
Co-authored-by: Chris Rizzitello <sithlord48@gmail.com>
2026-02-05 04:01:33 +00:00
|
|
|
class EiClipboard;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-03 01:28:01 +00:00
|
|
|
using ClipboardInfo = IScreen::ClipboardInfo;
|
|
|
|
|
|
2024-08-30 14:53:25 +00:00
|
|
|
//! Implementation of IPlatformScreen for X11
|
2024-10-17 18:04:35 +00:00
|
|
|
class EiScreen : public PlatformScreen
|
|
|
|
|
{
|
2024-08-30 14:53:25 +00:00
|
|
|
public:
|
2026-02-06 02:30:30 +00:00
|
|
|
EiScreen(bool isPrimary, IEventQueue *events, bool usePortal);
|
2025-04-28 01:27:48 +00:00
|
|
|
~EiScreen() override;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
// IScreen overrides
|
2025-05-23 17:48:39 +00:00
|
|
|
void *getEventTarget() const final;
|
2024-08-30 14:53:25 +00:00
|
|
|
bool getClipboard(ClipboardID id, IClipboard *) const override;
|
2024-10-17 18:04:35 +00:00
|
|
|
void getShape(std::int32_t &x, std::int32_t &y, std::int32_t &width, std::int32_t &height) const override;
|
2024-08-30 14:53:25 +00:00
|
|
|
void getCursorPos(std::int32_t &x, std::int32_t &y) const override;
|
|
|
|
|
|
|
|
|
|
// IPrimaryScreen overrides
|
|
|
|
|
void reconfigure(std::uint32_t activeSides) override;
|
2025-07-13 14:26:11 +00:00
|
|
|
std::uint32_t activeSides() override;
|
2024-08-30 14:53:25 +00:00
|
|
|
void warpCursor(std::int32_t x, std::int32_t y) override;
|
|
|
|
|
std::uint32_t registerHotKey(KeyID key, KeyModifierMask mask) override;
|
|
|
|
|
void unregisterHotKey(std::uint32_t id) override;
|
|
|
|
|
void fakeInputBegin() override;
|
|
|
|
|
void fakeInputEnd() override;
|
|
|
|
|
std::int32_t getJumpZoneSize() const override;
|
|
|
|
|
bool isAnyMouseButtonDown(std::uint32_t &buttonID) const override;
|
|
|
|
|
void getCursorCenter(std::int32_t &x, std::int32_t &y) const override;
|
|
|
|
|
|
|
|
|
|
// ISecondaryScreen overrides
|
|
|
|
|
void fakeMouseButton(ButtonID id, bool press) override;
|
|
|
|
|
void fakeMouseMove(std::int32_t x, std::int32_t y) override;
|
|
|
|
|
void fakeMouseRelativeMove(std::int32_t dx, std::int32_t dy) const override;
|
2026-02-06 14:55:41 +00:00
|
|
|
void fakeMouseWheel(ScrollDelta delta) const override;
|
2025-08-06 23:36:53 +00:00
|
|
|
void fakeKey(std::uint32_t keycode, bool isDown) const;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
// IPlatformScreen overrides
|
|
|
|
|
void enable() override;
|
|
|
|
|
void disable() override;
|
|
|
|
|
void enter() override;
|
2024-09-17 03:19:52 +00:00
|
|
|
bool canLeave() override;
|
|
|
|
|
void leave() override;
|
2024-08-30 14:53:25 +00:00
|
|
|
bool setClipboard(ClipboardID, const IClipboard *) override;
|
|
|
|
|
void checkClipboards() override;
|
|
|
|
|
void openScreensaver(bool notify) override;
|
|
|
|
|
void closeScreensaver() override;
|
|
|
|
|
void screensaver(bool activate) override;
|
|
|
|
|
void resetOptions() override;
|
|
|
|
|
void setOptions(const OptionsList &options) override;
|
|
|
|
|
void setSequenceNumber(std::uint32_t) override;
|
|
|
|
|
bool isPrimary() const override;
|
|
|
|
|
|
feat: inputcapture clipboard support
Send the clipboard over the libportal InputCapture portal. Only built
if the installed libportal has clipboard support.
AI disclosure: Claude was used on both sides of this work.
- Peter Hutterer: "The second commit was purely written by Claude
after I stared at this for too long without seeing any hope of
getting started. Turns out Claude wrote something that at least
looks correct and it does work. It needs review but also needs
knowledge of deskflow's internals that I don't have..."
- Nick Bolton: Claude also assisted with the follow-up work listed
below (image copy/paste, session re-request, race fixes, size/mime
validation, and CMake detection).
Server side (Wayland host, Peter Hutterer):
- Initial scaffolding for inputcapture clipboard support, guarded so it
only builds when the portal exposes the clipboard API.
- Integrate clipboard data into the inputcapture session so the host
clipboard can be offered to the remote (the Claude-written commit
referenced above).
Client side (Wayland receiver, KoljaFrahm):
- Receive clipboard data from the server and feed it into the local
clipboard through libportal. Built on the reference code by Peter:
https://github.com/whot/libportal-clipboard-test/tree/main
Build integration and rebase (Chris Rizzitello, sithlord48):
- Add the original CMake check for libportal/clipboard.h to define
HAVE_LIBPORTAL_CLIPBOARD, and guard the libportal clipboard use on
it.
- Update the code style and rebase onto the updated input capture
session persistence: https://github.com/deskflow/deskflow/pull/9415
Image support and reliability fixes (Nick Bolton):
- Support image copy/paste in addition to text, so screenshots and
other image clipboard contents work both ways through inputcapture.
- Re-request the input capture session when it comes up without a
clipboard, so new testers with existing sessions can get clipboard
functionality without needing to clear the session.
- Defer clipboard reads until the input capture session is active,
avoiding races where reads happen before the portal is ready.
- Fix assorted style issues in original commit to match conventions.
- Check the configured clipboard size limit and validate incoming
mime types before forwarding inputcapture clipboard data.
- Switch the CMake clipboard probe to check_symbol_exists so detection
matches what the compiler actually sees in the headers.
Co-authored-by: Nick Bolton <nick@symless.com>
Co-authored-by: KoljaFrahm <GitHub.Kolja@dfgh.net>
Co-authored-by: Chris Rizzitello <sithlord48@gmail.com>
2026-02-05 04:01:33 +00:00
|
|
|
// Send clipboard event (needed by PortalInputCapture)
|
|
|
|
|
void sendClipboardEvent(EventTypes type, ClipboardID id) const;
|
|
|
|
|
|
2026-05-19 19:01:38 +00:00
|
|
|
// Local clipboard cache (used by PortalRemoteDesktop to land selection reads)
|
|
|
|
|
EiClipboard *getClipboardCache() const
|
|
|
|
|
{
|
|
|
|
|
return m_clipboard;
|
|
|
|
|
}
|
|
|
|
|
|
feat: inputcapture clipboard support
Send the clipboard over the libportal InputCapture portal. Only built
if the installed libportal has clipboard support.
AI disclosure: Claude was used on both sides of this work.
- Peter Hutterer: "The second commit was purely written by Claude
after I stared at this for too long without seeing any hope of
getting started. Turns out Claude wrote something that at least
looks correct and it does work. It needs review but also needs
knowledge of deskflow's internals that I don't have..."
- Nick Bolton: Claude also assisted with the follow-up work listed
below (image copy/paste, session re-request, race fixes, size/mime
validation, and CMake detection).
Server side (Wayland host, Peter Hutterer):
- Initial scaffolding for inputcapture clipboard support, guarded so it
only builds when the portal exposes the clipboard API.
- Integrate clipboard data into the inputcapture session so the host
clipboard can be offered to the remote (the Claude-written commit
referenced above).
Client side (Wayland receiver, KoljaFrahm):
- Receive clipboard data from the server and feed it into the local
clipboard through libportal. Built on the reference code by Peter:
https://github.com/whot/libportal-clipboard-test/tree/main
Build integration and rebase (Chris Rizzitello, sithlord48):
- Add the original CMake check for libportal/clipboard.h to define
HAVE_LIBPORTAL_CLIPBOARD, and guard the libportal clipboard use on
it.
- Update the code style and rebase onto the updated input capture
session persistence: https://github.com/deskflow/deskflow/pull/9415
Image support and reliability fixes (Nick Bolton):
- Support image copy/paste in addition to text, so screenshots and
other image clipboard contents work both ways through inputcapture.
- Re-request the input capture session when it comes up without a
clipboard, so new testers with existing sessions can get clipboard
functionality without needing to clear the session.
- Defer clipboard reads until the input capture session is active,
avoiding races where reads happen before the portal is ready.
- Fix assorted style issues in original commit to match conventions.
- Check the configured clipboard size limit and validate incoming
mime types before forwarding inputcapture clipboard data.
- Switch the CMake clipboard probe to check_symbol_exists so detection
matches what the compiler actually sees in the headers.
Co-authored-by: Nick Bolton <nick@symless.com>
Co-authored-by: KoljaFrahm <GitHub.Kolja@dfgh.net>
Co-authored-by: Chris Rizzitello <sithlord48@gmail.com>
2026-02-05 04:01:33 +00:00
|
|
|
// Maximum clipboard size in KB, configured by the server
|
|
|
|
|
size_t maximumClipboardSize() const
|
|
|
|
|
{
|
|
|
|
|
return m_maximumClipboardSize;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-30 14:53:25 +00:00
|
|
|
protected:
|
|
|
|
|
// IPlatformScreen overrides
|
2025-06-18 04:17:54 +00:00
|
|
|
void handleSystemEvent(const Event &event) override;
|
2024-08-30 14:53:25 +00:00
|
|
|
void updateButtons() override;
|
|
|
|
|
IKeyState *getKeyState() const override;
|
2025-01-06 00:55:07 +00:00
|
|
|
std::string getSecureInputApp() const override;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 00:53:37 +00:00
|
|
|
void updateShape();
|
|
|
|
|
void addDevice(ei_device *device);
|
|
|
|
|
void removeDevice(ei_device *device);
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
private:
|
2025-06-20 00:53:37 +00:00
|
|
|
void initEi();
|
|
|
|
|
void cleanupEi();
|
2025-05-02 01:50:53 +00:00
|
|
|
void sendEvent(EventTypes type, void *data);
|
2025-06-20 00:53:37 +00:00
|
|
|
ButtonID mapButtonFromEvdev(ei_event *event) const;
|
|
|
|
|
void onKeyEvent(ei_event *event);
|
|
|
|
|
void onButtonEvent(ei_event *event);
|
|
|
|
|
void sendWheelEvents(ei_device *device, const int threshold, double dx, double dy, bool is_discrete);
|
|
|
|
|
void onPointerScrollEvent(ei_event *event);
|
|
|
|
|
void onPointerScrollDiscreteEvent(ei_event *event);
|
|
|
|
|
void onMotionEvent(ei_event *event);
|
2025-06-20 02:20:36 +00:00
|
|
|
void onAbsMotionEvent(const ei_event *) const;
|
2025-08-06 23:36:53 +00:00
|
|
|
bool onHotkey(KeyID key, bool isPressed, KeyModifierMask mask);
|
2025-06-20 00:53:37 +00:00
|
|
|
void eiLogEvent(ei_log_priority priority, const char *message) const;
|
|
|
|
|
|
|
|
|
|
void handleConnectedToEisEvent(const Event &event);
|
|
|
|
|
void handlePortalSessionClosed();
|
2026-06-25 03:31:30 +00:00
|
|
|
void ensureEmulating() const;
|
|
|
|
|
void stopEmulating() const;
|
|
|
|
|
void cancelIdleEmulationTimer() const;
|
2025-06-20 00:53:37 +00:00
|
|
|
|
2025-06-20 02:20:36 +00:00
|
|
|
static void handleEiLogEvent(ei *ei, const ei_log_priority priority, const char *message, ei_log_context *)
|
2024-10-17 18:04:35 +00:00
|
|
|
{
|
2025-05-23 18:32:42 +00:00
|
|
|
auto screen = static_cast<EiScreen *>(ei_get_user_data(ei));
|
2025-06-20 00:53:37 +00:00
|
|
|
screen->eiLogEvent(priority, message);
|
2024-08-30 14:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// true if screen is being used as a primary screen, false otherwise
|
2025-06-20 00:53:37 +00:00
|
|
|
bool m_isPrimary = false;
|
|
|
|
|
IEventQueue *m_events = nullptr;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
// keyboard stuff
|
2025-06-20 00:53:37 +00:00
|
|
|
EiKeyState *m_keyState = nullptr;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2026-01-26 17:28:02 +00:00
|
|
|
KeyID m_lastPressed = kKeyNone;
|
|
|
|
|
|
2025-06-03 01:28:01 +00:00
|
|
|
// clipboard stuff
|
feat: inputcapture clipboard support
Send the clipboard over the libportal InputCapture portal. Only built
if the installed libportal has clipboard support.
AI disclosure: Claude was used on both sides of this work.
- Peter Hutterer: "The second commit was purely written by Claude
after I stared at this for too long without seeing any hope of
getting started. Turns out Claude wrote something that at least
looks correct and it does work. It needs review but also needs
knowledge of deskflow's internals that I don't have..."
- Nick Bolton: Claude also assisted with the follow-up work listed
below (image copy/paste, session re-request, race fixes, size/mime
validation, and CMake detection).
Server side (Wayland host, Peter Hutterer):
- Initial scaffolding for inputcapture clipboard support, guarded so it
only builds when the portal exposes the clipboard API.
- Integrate clipboard data into the inputcapture session so the host
clipboard can be offered to the remote (the Claude-written commit
referenced above).
Client side (Wayland receiver, KoljaFrahm):
- Receive clipboard data from the server and feed it into the local
clipboard through libportal. Built on the reference code by Peter:
https://github.com/whot/libportal-clipboard-test/tree/main
Build integration and rebase (Chris Rizzitello, sithlord48):
- Add the original CMake check for libportal/clipboard.h to define
HAVE_LIBPORTAL_CLIPBOARD, and guard the libportal clipboard use on
it.
- Update the code style and rebase onto the updated input capture
session persistence: https://github.com/deskflow/deskflow/pull/9415
Image support and reliability fixes (Nick Bolton):
- Support image copy/paste in addition to text, so screenshots and
other image clipboard contents work both ways through inputcapture.
- Re-request the input capture session when it comes up without a
clipboard, so new testers with existing sessions can get clipboard
functionality without needing to clear the session.
- Defer clipboard reads until the input capture session is active,
avoiding races where reads happen before the portal is ready.
- Fix assorted style issues in original commit to match conventions.
- Check the configured clipboard size limit and validate incoming
mime types before forwarding inputcapture clipboard data.
- Switch the CMake clipboard probe to check_symbol_exists so detection
matches what the compiler actually sees in the headers.
Co-authored-by: Nick Bolton <nick@symless.com>
Co-authored-by: KoljaFrahm <GitHub.Kolja@dfgh.net>
Co-authored-by: Chris Rizzitello <sithlord48@gmail.com>
2026-02-05 04:01:33 +00:00
|
|
|
EiClipboard *m_clipboard = nullptr;
|
|
|
|
|
size_t m_maximumClipboardSize = INT_MAX;
|
2025-06-03 01:28:01 +00:00
|
|
|
|
2025-06-20 00:53:37 +00:00
|
|
|
std::vector<ei_device *> m_eiDevices;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 00:53:37 +00:00
|
|
|
ei *m_ei = nullptr;
|
|
|
|
|
ei_seat *m_eiSeat = nullptr;
|
|
|
|
|
ei_device *m_eiPointer = nullptr;
|
|
|
|
|
ei_device *m_eiKeyboard = nullptr;
|
|
|
|
|
ei_device *m_eiAbs = nullptr;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2026-06-25 03:31:30 +00:00
|
|
|
mutable std::uint32_t m_sequenceNumber = 0;
|
|
|
|
|
|
|
|
|
|
// Lazily-started EIS emulation: only grab while relayed input is actually
|
|
|
|
|
// flowing, and release after a short idle so the compositor can DPMS-sleep
|
|
|
|
|
// this screen even while the deskflow cursor logically sits on it.
|
|
|
|
|
mutable bool m_isEmulating = false;
|
|
|
|
|
mutable EventQueueTimer *m_idleEmulationTimer = nullptr;
|
|
|
|
|
// Chosen empirically on one machine in 2026-06; not derived from any protocol constant.
|
|
|
|
|
static constexpr double s_idleEmulationTimeout = 4.0;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-07-13 14:26:11 +00:00
|
|
|
std::uint32_t m_activeSides = 0;
|
2025-06-20 00:53:37 +00:00
|
|
|
std::uint32_t m_x = 0;
|
|
|
|
|
std::uint32_t m_y = 0;
|
|
|
|
|
std::uint32_t m_w = 0;
|
|
|
|
|
std::uint32_t m_h = 0;
|
2026-07-15 17:09:00 +00:00
|
|
|
bool m_isShapeInitialized = false;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
// true if mouse has entered the screen
|
2025-06-20 00:53:37 +00:00
|
|
|
bool m_isOnScreen;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
// server: last pointer position
|
|
|
|
|
// client: position sent before enter()
|
2025-06-20 00:53:37 +00:00
|
|
|
std::int32_t m_cursorX = 0;
|
|
|
|
|
std::int32_t m_cursorY = 0;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 00:53:37 +00:00
|
|
|
double m_bufferDX = 0;
|
|
|
|
|
double m_bufferDY = 0;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 00:53:37 +00:00
|
|
|
mutable std::mutex m_mutex;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2025-06-20 00:53:37 +00:00
|
|
|
PortalRemoteDesktop *m_portalRemoteDesktop = nullptr;
|
|
|
|
|
PortalInputCapture *m_portalInputCapture = nullptr;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
struct HotKeyItem
|
|
|
|
|
{
|
2024-08-30 14:53:25 +00:00
|
|
|
public:
|
|
|
|
|
HotKeyItem(std::uint32_t mask, std::uint32_t id);
|
2025-10-13 23:17:46 +00:00
|
|
|
auto operator<=>(const HotKeyItem &other) const
|
2024-10-17 18:04:35 +00:00
|
|
|
{
|
2025-10-13 23:17:46 +00:00
|
|
|
return mask <=> other.mask;
|
|
|
|
|
}
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
public:
|
2025-06-20 00:53:37 +00:00
|
|
|
std::uint32_t mask = 0;
|
|
|
|
|
std::uint32_t id = 0; // for registering the hotkey
|
2024-08-30 14:53:25 +00:00
|
|
|
};
|
|
|
|
|
|
2024-10-17 18:04:35 +00:00
|
|
|
class HotKeySet
|
|
|
|
|
{
|
2024-08-30 14:53:25 +00:00
|
|
|
public:
|
2025-05-21 01:09:55 +00:00
|
|
|
explicit HotKeySet(KeyID keyid);
|
2024-10-17 18:04:35 +00:00
|
|
|
KeyID keyid() const
|
|
|
|
|
{
|
2025-06-20 00:53:37 +00:00
|
|
|
return m_id;
|
2025-10-13 23:19:04 +00:00
|
|
|
}
|
2025-06-20 00:53:37 +00:00
|
|
|
bool removeById(std::uint32_t id);
|
|
|
|
|
void addItem(HotKeyItem item);
|
|
|
|
|
std::uint32_t findByMask(std::uint32_t mask) const;
|
2024-08-30 14:53:25 +00:00
|
|
|
|
|
|
|
|
private:
|
2025-06-20 00:53:37 +00:00
|
|
|
KeyID m_id = 0;
|
|
|
|
|
std::vector<HotKeyItem> m_set;
|
2024-08-30 14:53:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
using HotKeyMap = std::map<KeyID, HotKeySet>;
|
|
|
|
|
|
2025-06-20 00:53:37 +00:00
|
|
|
HotKeyMap m_hotkeys;
|
2025-09-24 22:09:28 +00:00
|
|
|
[[no_unique_address]] XDGPowerManager m_powerManager;
|
2024-08-30 14:53:25 +00:00
|
|
|
};
|
|
|
|
|
|
2024-09-17 19:00:25 +00:00
|
|
|
} // namespace deskflow
|