88 lines
2.6 KiB
Go
88 lines
2.6 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package xorg
|
|
|
|
/*
|
|
#include "commands_native.h"
|
|
*/
|
|
import "C"
|
|
|
|
type steamFocusSample struct {
|
|
window, focus uint64
|
|
pid int
|
|
known, steam bool
|
|
innerFocus bool
|
|
}
|
|
|
|
// The command owner retains one verified Steam browser child. A foreground
|
|
// transition arms at most one repair during the next ten 100ms focus samples.
|
|
// Steam's own restoration wins; we never choose a child from its geometry.
|
|
type steamFocusRepair struct {
|
|
previousWindow, window, target uint64
|
|
pid int
|
|
checksLeft, outerSamples int
|
|
}
|
|
|
|
func (repair *steamFocusRepair) observe(sample steamFocusSample) uint64 {
|
|
if !sample.known {
|
|
return 0
|
|
}
|
|
if sample.window != repair.previousWindow {
|
|
repair.previousWindow = sample.window
|
|
repair.checksLeft, repair.outerSamples = 10, 0
|
|
}
|
|
if !sample.steam {
|
|
repair.checksLeft, repair.outerSamples = 0, 0
|
|
return 0
|
|
}
|
|
if sample.innerFocus {
|
|
repair.window, repair.pid, repair.target = sample.window, sample.pid, sample.focus
|
|
repair.outerSamples = 0
|
|
}
|
|
if repair.checksLeft == 0 {
|
|
return 0
|
|
}
|
|
repair.checksLeft--
|
|
if sample.focus != sample.window {
|
|
repair.outerSamples = 0
|
|
return 0
|
|
}
|
|
repair.outerSamples++
|
|
if repair.outerSamples < 2 || sample.window != repair.window || sample.pid != repair.pid {
|
|
return 0
|
|
}
|
|
return repair.target
|
|
}
|
|
|
|
func read_command_focus(display *C.Display, steamEnabled bool) (int, steamFocusSample) {
|
|
var enabled C.int
|
|
if steamEnabled {
|
|
enabled = 1
|
|
}
|
|
result := C.cthulhu_read_command_focus(display, enabled)
|
|
value := result.steam
|
|
return int(result.xterm), steamFocusSample{window: uint64(value.window), focus: uint64(value.focus), pid: int(value.pid),
|
|
known: value.known != 0, steam: value.steam != 0, innerFocus: value.innerFocus != 0}
|
|
}
|
|
|
|
func restore_steam_focus(display *C.Display, window uint64, pid int, target uint64) bool {
|
|
return C.cthulhu_restore_steam_focus(display, C.Window(window), C.int(pid), C.Window(target)) != 0
|
|
}
|
|
|
|
func (owner *commandOwner) check_steam_focus(sample steamFocusSample) {
|
|
if owner.listener.secure.Load() || owner.workerContext.Err() != nil {
|
|
owner.steamFocus.checksLeft = 0
|
|
return
|
|
}
|
|
target := owner.steamFocus.observe(sample)
|
|
if target == 0 || !owner.commandGrabsAllowed() || len(owner.held) != 0 || owner.device.active != 0 ||
|
|
owner.learnMode || owner.uiSession != 0 || owner.ocrReview || owner.ocrPending {
|
|
return
|
|
}
|
|
if restore_steam_focus(owner.device.display, sample.window, sample.pid, target) {
|
|
owner.steamFocus.checksLeft = 0
|
|
}
|
|
}
|