diff --git a/client/src/neko/events.ts b/client/src/neko/events.ts index b61476a9..725e675e 100644 --- a/client/src/neko/events.ts +++ b/client/src/neko/events.ts @@ -27,6 +27,7 @@ export const EVENT = { REQUESTING: 'control/requesting', CLIPBOARD: 'control/clipboard', GIVE: 'control/give', + KEYBOARD: 'control/keyboard' }, CHAT: { MESSAGE: 'chat/message', @@ -67,6 +68,7 @@ export type ControlEvents = | typeof EVENT.CONTROL.REQUEST | typeof EVENT.CONTROL.GIVE | typeof EVENT.CONTROL.CLIPBOARD + | typeof EVENT.CONTROL.KEYBOARD export type SystemEvents = typeof EVENT.SYSTEM.DISCONNECT export type MemberEvents = typeof EVENT.MEMBER.LIST | typeof EVENT.MEMBER.CONNECTED | typeof EVENT.MEMBER.DISCONNECTED diff --git a/client/src/neko/messages.ts b/client/src/neko/messages.ts index b1b93807..67138c53 100644 --- a/client/src/neko/messages.ts +++ b/client/src/neko/messages.ts @@ -31,6 +31,7 @@ export type WebSocketPayloads = | ControlPayload | ControlRequestPayload | ControlClipboardPayload + | ControlKeyboardPayload | ChatPayload | ChatSendPayload | EmojiSendPayload @@ -125,6 +126,10 @@ export interface ControlClipboardPayload { text: string } +export interface ControlKeyboardPayload { + layout: string +} + /* CHAT PAYLOADS */ diff --git a/client/src/store/remote.ts b/client/src/store/remote.ts index 03081cf5..95d5165c 100644 --- a/client/src/store/remote.ts +++ b/client/src/store/remote.ts @@ -133,5 +133,13 @@ export const actions = actionTree( $client.sendMessage(EVENT.ADMIN.GIVE, { id: member.id }) }, + + changeKeyboard({ getters }) { + if (!accessor.connected || !getters.hosting) { + return + } + + $client.sendMessage(EVENT.CONTROL.KEYBOARD, { layout: accessor.settings.keyboard_layout }) + } }, ) diff --git a/server/internal/types/event/events.go b/server/internal/types/event/events.go index 1ee171ea..7b9d31ba 100644 --- a/server/internal/types/event/events.go +++ b/server/internal/types/event/events.go @@ -22,6 +22,7 @@ const ( CONTROL_REQUESTING = "control/requesting" CONTROL_GIVE = "control/give" CONTROL_CLIPBOARD = "control/clipboard" + CONTROL_KEYBOARD = "control/keyboard" ) const ( diff --git a/server/internal/types/message/messages.go b/server/internal/types/message/messages.go index e0365054..d3287b36 100644 --- a/server/internal/types/message/messages.go +++ b/server/internal/types/message/messages.go @@ -46,6 +46,11 @@ type Clipboard struct { Text string `json:"text"` } +type Keyboard struct { + Event string `json:"event"` + Layout string `json:"layout"` +} + type Control struct { Event string `json:"event"` ID string `json:"id"` diff --git a/server/internal/websocket/control.go b/server/internal/websocket/control.go index d3b419fc..8b96bd9d 100644 --- a/server/internal/websocket/control.go +++ b/server/internal/websocket/control.go @@ -119,3 +119,14 @@ func (h *MessageHandler) controlClipboard(id string, session types.Session, payl h.remote.WriteClipboard(payload.Text) return nil } + +func (h *MessageHandler) controlKeyboard(id string, session types.Session, payload *message.Keyboard) error { + // check if session is host + if !h.sessions.IsHost(id) { + h.logger.Debug().Str("id", id).Msg("is not the host") + return nil + } + + h.remote.SetKeyboard(payload.Layout) + return nil +} diff --git a/server/internal/websocket/handler.go b/server/internal/websocket/handler.go index 5753dd7b..25b043e5 100644 --- a/server/internal/websocket/handler.go +++ b/server/internal/websocket/handler.go @@ -93,6 +93,13 @@ func (h *MessageHandler) Message(id string, raw []byte) error { utils.Unmarshal(payload, raw, func() error { return h.controlClipboard(id, session, payload) }), "%s failed", header.Event) + case event.CONTROL_KEYBOARD: + payload := &message.Keyboard{} + return errors.Wrapf( + utils.Unmarshal(payload, raw, func() error { + return h.controlKeyboard(id, session, payload) + }), "%s failed", header.Event) + // Chat Events case event.CHAT_MESSAGE: