More work on tentacles.
This commit is contained in:
1 parent
573d15d7b4
commit
4cf3335017
29 files changed
+1194
-66
No files matched your search
@@ -6,6 +6,7 @@ package xorg
|
||||
|
||||
/*
|
||||
#cgo pkg-config: xkbcommon
|
||||
#cgo pkg-config: xi
|
||||
#include "commands_native.h"
|
||||
*/
|
||||
import "C"
|
||||
@@ -26,6 +27,7 @@ type uiUpdate struct {
|
||||
ctx context.Context
|
||||
closeSession uint64
|
||||
result chan uiReply
|
||||
localOnly bool
|
||||
}
|
||||
|
||||
func (listener *CommandListener) InternalUISession() uint64 { return listener.uiSession.Load() }
|
||||
@@ -35,7 +37,14 @@ func (listener *CommandListener) InternalUIEchoActive() bool { return listener.u
|
||||
// BeginInternalUI acknowledges exclusive capture without changing X input
|
||||
// focus. EndInternalUI waits for physical releases, and cannot close a newer UI.
|
||||
func (listener *CommandListener) BeginInternalUI(ctx context.Context) (uint64, error) {
|
||||
return listener.update_internal_ui(ctx, 0)
|
||||
return listener.update_internal_ui(ctx, 0, false)
|
||||
}
|
||||
|
||||
// BeginLocalUI admits only device-backed XI2 events and excludes XTEST. This
|
||||
// is a core API, never a Tentacle-controlled form flag. It fails on unsupported
|
||||
// servers; ordinary forms keep their existing input path.
|
||||
func (listener *CommandListener) BeginLocalUI(ctx context.Context) (uint64, error) {
|
||||
return listener.update_internal_ui(ctx, 0, true)
|
||||
}
|
||||
func (listener *CommandListener) EndInternalUI(ctx context.Context, session uint64) error {
|
||||
if session == 0 {
|
||||
@@ -50,17 +59,17 @@ func (listener *CommandListener) EndInternalUI(ctx context.Context, session uint
|
||||
break
|
||||
}
|
||||
}
|
||||
_, err := listener.update_internal_ui(ctx, session)
|
||||
_, err := listener.update_internal_ui(ctx, session, false)
|
||||
return err
|
||||
}
|
||||
func (listener *CommandListener) update_internal_ui(ctx context.Context, closeSession uint64) (uint64, error) {
|
||||
func (listener *CommandListener) update_internal_ui(ctx context.Context, closeSession uint64, localOnly bool) (uint64, error) {
|
||||
listener.mutex.Lock()
|
||||
done := listener.done
|
||||
listener.mutex.Unlock()
|
||||
if done == nil {
|
||||
return 0, errors.New("command listener is not running")
|
||||
}
|
||||
update := uiUpdate{ctx: ctx, closeSession: closeSession, result: make(chan uiReply, 1)}
|
||||
update := uiUpdate{ctx: ctx, closeSession: closeSession, result: make(chan uiReply, 1), localOnly: localOnly}
|
||||
select {
|
||||
case listener.uiUpdates <- update:
|
||||
case <-ctx.Done():
|
||||
@@ -76,7 +85,7 @@ func (listener *CommandListener) update_internal_ui(ctx context.Context, closeSe
|
||||
}
|
||||
}
|
||||
|
||||
func (owner *commandOwner) begin_internal_ui() (uint64, error) {
|
||||
func (owner *commandOwner) begin_internal_ui_mode(localOnly bool) (uint64, error) {
|
||||
if !owner.commandGrabsAllowed() || owner.learnMode || owner.ocrReview || owner.uiSession != 0 {
|
||||
return 0, errors.New("internal UI input unavailable")
|
||||
}
|
||||
@@ -86,7 +95,13 @@ func (owner *commandOwner) begin_internal_ui() (uint64, error) {
|
||||
return 0, errors.New("no focused application")
|
||||
}
|
||||
owner.uiWindow = C.read_foreground(owner.device.display).window
|
||||
if status := C.acquire_internal_keyboard(owner.device); status != 0 {
|
||||
var status C.int
|
||||
if localOnly {
|
||||
status = C.acquire_local_keyboard(owner.device)
|
||||
} else {
|
||||
status = C.acquire_internal_keyboard(owner.device)
|
||||
}
|
||||
if status != 0 {
|
||||
return 0, fmt.Errorf("internal keyboard capture failed: %d", int(status))
|
||||
}
|
||||
owner.uiSession = owner.listener.uiSequence.Add(1)
|
||||
@@ -96,6 +111,10 @@ func (owner *commandOwner) begin_internal_ui() (uint64, error) {
|
||||
return owner.uiSession, nil
|
||||
}
|
||||
|
||||
func (owner *commandOwner) begin_internal_ui() (uint64, error) {
|
||||
return owner.begin_internal_ui_mode(false)
|
||||
}
|
||||
|
||||
func (owner *commandOwner) dismiss_internal_ui() {
|
||||
owner.uiSession = 0
|
||||
owner.listener.uiSession.Store(0)
|
||||
@@ -136,7 +155,7 @@ func (owner *commandOwner) sync_internal_ui() bool {
|
||||
owner.dismiss_internal_ui()
|
||||
}
|
||||
} else {
|
||||
result.session, result.err = owner.begin_internal_ui()
|
||||
result.session, result.err = owner.begin_internal_ui_mode(update.localOnly)
|
||||
}
|
||||
}
|
||||
update.result <- result
|
||||
|
||||
Reference in new issue
Block a user