From a2ca3727fe2ba816d1880365540bcfa3033a481b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Mon, 11 Jan 2021 15:30:53 +0100 Subject: [PATCH] xevent to update clipboard. --- internal/desktop/xevent.go | 4 +++ internal/desktop/xevent/xevent.c | 13 +++++++ internal/desktop/xevent/xevent.go | 11 ++++++ internal/desktop/xevent/xevent.h | 2 ++ internal/types/desktop.go | 1 + internal/websocket/manager.go | 57 ++++++++----------------------- 6 files changed, 46 insertions(+), 42 deletions(-) diff --git a/internal/desktop/xevent.go b/internal/desktop/xevent.go index 1bea6213..972c4e43 100644 --- a/internal/desktop/xevent.go +++ b/internal/desktop/xevent.go @@ -8,6 +8,10 @@ func (manager *DesktopManagerCtx) OnCursorChanged(listener func(serial uint64)) xevent.OnCursorChanged(listener) } +func (manager *DesktopManagerCtx) OnClipboardUpdated(listener func()) { + xevent.OnClipboardUpdated(listener) +} + func (manager *DesktopManagerCtx) OnEventError(listener func(error_code uint8, message string, request_code uint8, minor_code uint8)) { xevent.OnEventError(listener) } diff --git a/internal/desktop/xevent/xevent.c b/internal/desktop/xevent/xevent.c index d7dfe5f1..31216026 100644 --- a/internal/desktop/xevent/xevent.c +++ b/internal/desktop/xevent/xevent.c @@ -23,7 +23,11 @@ void XEventLoop(char *name) { return; } + Atom XA_CLIPBOARD; + XA_CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0); + XFixesSelectSelectionInput(display, root, XA_CLIPBOARD, XFixesSetSelectionOwnerNotifyMask); XFixesSelectCursorInput(display, root, XFixesDisplayCursorNotifyMask); + XSync(display, 0); XSetErrorHandler(XEventError); @@ -39,6 +43,15 @@ void XEventLoop(char *name) { continue; } } + + // XFixesSelectionNotifyEvent + if (event.type == xfixes_event_base + XFixesSelectionNotify) { + XFixesSelectionNotifyEvent notifyEvent = *((XFixesSelectionNotifyEvent *) &event); + if (notifyEvent.subtype == XFixesSetSelectionOwnerNotify && notifyEvent.selection == XA_CLIPBOARD) { + goXEventClipboardUpdated(); + continue; + } + } } XCloseDisplay(display); diff --git a/internal/desktop/xevent/xevent.go b/internal/desktop/xevent/xevent.go index 6a6fb4c0..9f8d6343 100644 --- a/internal/desktop/xevent/xevent.go +++ b/internal/desktop/xevent/xevent.go @@ -33,6 +33,12 @@ func OnCursorChanged(listener func(serial uint64)) { }) } +func OnClipboardUpdated(listener func()) { + emmiter.On("clipboard-updated", func(payload ...interface{}) { + listener() + }) +} + func OnEventError(listener func(error_code uint8, message string, request_code uint8, minor_code uint8)) { emmiter.On("event-error", func(payload ...interface{}) { listener(payload[0].(uint8), payload[1].(string), payload[2].(uint8), payload[3].(uint8)) @@ -44,6 +50,11 @@ func goXEventCursorChanged(event C.XFixesCursorNotifyEvent) { emmiter.Emit("cursor-changed", uint64(event.cursor_serial)) } +//export goXEventClipboardUpdated +func goXEventClipboardUpdated() { + emmiter.Emit("clipboard-updated") +} + //export goXEventError func goXEventError(event *C.XErrorEvent, message *C.char) { emmiter.Emit("event-error", uint8(event.error_code), C.GoString(message), uint8(event.request_code), uint8(event.minor_code)) diff --git a/internal/desktop/xevent/xevent.h b/internal/desktop/xevent/xevent.h index 24949f45..e735c0c4 100644 --- a/internal/desktop/xevent/xevent.h +++ b/internal/desktop/xevent/xevent.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -7,6 +8,7 @@ #include extern void goXEventCursorChanged(XFixesCursorNotifyEvent event); +extern void goXEventClipboardUpdated(); extern void goXEventError(XErrorEvent *event, char *message); extern int goXEventActive(); diff --git a/internal/types/desktop.go b/internal/types/desktop.go index bb694be4..60a18403 100644 --- a/internal/types/desktop.go +++ b/internal/types/desktop.go @@ -44,6 +44,7 @@ type DesktopManager interface { // xevent OnCursorChanged(listener func(serial uint64)) + OnClipboardUpdated(listener func()) OnEventError(listener func(error_code uint8, message string, request_code uint8, minor_code uint8)) // clipboard diff --git a/internal/websocket/manager.go b/internal/websocket/manager.go index 6892a3c9..9f4df2dc 100644 --- a/internal/websocket/manager.go +++ b/internal/websocket/manager.go @@ -47,7 +47,6 @@ type WebSocketManagerCtx struct { desktop types.DesktopManager handler *handler.MessageHandlerCtx handlers []types.HandlerFunction - shutdown chan bool } func (ws *WebSocketManagerCtx) Start() { @@ -118,51 +117,25 @@ func (ws *WebSocketManagerCtx) Start() { }, nil) }) - go func() { - ws.logger.Info().Msg("clipboard loop started") - - defer func() { - ws.logger.Info().Msg("clipboard loop stopped") - }() - - current := ws.desktop.ReadClipboard() - - for { - select { - case <-ws.shutdown: - return - default: - session := ws.sessions.GetHost() - if session == nil { - break - } - - text := ws.desktop.ReadClipboard() - if text == current { - break - } - - current = text - if !session.CanAccessClipboard() { - break - } - - if err := session.Send( - message.ClipboardData{ - Event: event.CLIPBOARD_UPDATED, - Text: text, - }); err != nil { - ws.logger.Warn().Err(err).Msg("could not sync clipboard") - } - } - - time.Sleep(100 * time.Millisecond) + ws.desktop.OnClipboardUpdated(func() { + session := ws.sessions.GetHost() + if session == nil || !session.CanAccessClipboard() { + return } - }() + + text := ws.desktop.ReadClipboard() + err := session.Send(message.ClipboardData{ + Event: event.CLIPBOARD_UPDATED, + Text: text, + }) + + if err != nil { + ws.logger.Warn().Err(err).Msg("could not sync clipboard") + } + }) } func (ws *WebSocketManagerCtx) Shutdown() error { - ws.shutdown <- true return nil }