mirror of
https://github.com/baketnk/frame-yap.git
synced 2026-10-06 03:00:04 +02:00
Explain missing X display when the focus guard refuses Type
This commit is contained in:
1 parent
b3a9d39482
commit
0681d4941a
6 files changed
+22
-3
No files matched your search
@@ -44,3 +44,9 @@ SDL3 and OpenVR SDK sources, builds, tests, stages and packages. The release
|
||||
commit sets `RELEASE_VERSION` in `scripts/install_payload.py` (then
|
||||
`python3 scripts/sync-installer.py`); upload the archive, its `.sha256` and
|
||||
`install.sh` to the GitHub release.
|
||||
|
||||
When starting over SSH, supply the verified Gamescope Xwayland `DISPLAY` as well
|
||||
as `XDG_RUNTIME_DIR` from the user's session. Do not assume `:0` is always the
|
||||
text destination. Without `DISPLAY`, the focus guard refuses Type and preserves
|
||||
the review; the status line reports `Input unavailable: DISPLAY missing`.
|
||||
Launch from Steam/the desktop menu to inherit the normal session environment.
|
||||
+5
-2
@@ -89,7 +89,9 @@ void Controller::delivery_detail(DeliveryResult result, bool submit) {
|
||||
}
|
||||
std::shared_ptr<ControllerFocus> Controller::manual_focus() {
|
||||
auto focus = focus_factory_();
|
||||
if (!focus || !focus->arm()) throw std::runtime_error("Current target not verified; review kept");
|
||||
if (!focus || !focus->arm())
|
||||
throw std::runtime_error(std::string("Current target not verified: ") +
|
||||
(focus ? focus->failure() : "focus unavailable") + "; review kept");
|
||||
return std::shared_ptr<ControllerFocus>(std::move(focus));
|
||||
}
|
||||
void Controller::queue_paced(std::string text, bool enter, bool review,
|
||||
@@ -370,7 +372,8 @@ void Controller::action(UiAction action) {
|
||||
} catch (const std::exception& e) {
|
||||
if (session_.state() == State::Recording || session_.state() == State::Transcribing) {
|
||||
audio_.close(); session_.fail(); armed_focus_.reset(); status_note_.clear();
|
||||
} else status_note_ = "Input unavailable - check destination";
|
||||
} else status_note_ = std::string(e.what()).find("DISPLAY missing") != std::string::npos ?
|
||||
"Input unavailable: DISPLAY missing" : "Input unavailable - check destination";
|
||||
detail_ = e.what();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
virtual ~ControllerFocus() = default;
|
||||
virtual bool arm() = 0;
|
||||
virtual bool valid() = 0;
|
||||
virtual const char* failure() const { return "focus unavailable"; }
|
||||
};
|
||||
using FocusFactory = std::function<std::unique_ptr<ControllerFocus>()>;
|
||||
|
||||
|
||||
+3
-1
@@ -167,9 +167,11 @@ bool FocusGuard::arm() {
|
||||
auto& p = *impl_;
|
||||
if (p.attempted || p.dead) return false;
|
||||
p.attempted = true;
|
||||
const char* display = std::getenv("DISPLAY");
|
||||
if (!display || !*display) { p.reason = "DISPLAY missing"; p.dead = true; return false; }
|
||||
int screen_number = 0;
|
||||
p.connection = xcb_connect(nullptr, &screen_number);
|
||||
if (!p.connection || xcb_connection_has_error(p.connection)) { p.dead = true; return false; }
|
||||
if (!p.connection || xcb_connection_has_error(p.connection)) { p.reason = "X display unavailable"; p.dead = true; return false; }
|
||||
const xcb_setup_t* setup = xcb_get_setup(p.connection);
|
||||
auto iter = xcb_setup_roots_iterator(setup);
|
||||
for (int i = 0; i < screen_number && iter.rem; ++i) xcb_screen_next(&iter);
|
||||
|
||||
@@ -106,6 +106,7 @@ public:
|
||||
trace_(std::string("focus invalid: ") + guard_.failure());
|
||||
return false;
|
||||
}
|
||||
const char* failure() const override { return guard_.failure(); }
|
||||
private:
|
||||
FocusGuard guard_;
|
||||
DeliveryTrace& trace_;
|
||||
|
||||
@@ -33,6 +33,12 @@ private:
|
||||
int main() {
|
||||
try {
|
||||
DisplaySetting isolated_display;
|
||||
unsetenv("DISPLAY");
|
||||
FocusGuard missing_display;
|
||||
CHECK(!missing_display.arm());
|
||||
CHECK(std::string(missing_display.failure()) == "DISPLAY missing");
|
||||
CHECK(!missing_display.arm());
|
||||
setenv("DISPLAY", "frameyap-no-such-display:9876", 1);
|
||||
FocusGuard guard; // Construction must not connect to X.
|
||||
CHECK(!guard.valid());
|
||||
CHECK(!guard.arm()); // No server: fail closed.
|
||||
|
||||
Reference in new issue
Block a user