mirror of
https://github.com/baketnk/frame-yap.git
synced 2026-10-06 06: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
|
commit sets `RELEASE_VERSION` in `scripts/install_payload.py` (then
|
||||||
`python3 scripts/sync-installer.py`); upload the archive, its `.sha256` and
|
`python3 scripts/sync-installer.py`); upload the archive, its `.sha256` and
|
||||||
`install.sh` to the GitHub release.
|
`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() {
|
std::shared_ptr<ControllerFocus> Controller::manual_focus() {
|
||||||
auto focus = focus_factory_();
|
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));
|
return std::shared_ptr<ControllerFocus>(std::move(focus));
|
||||||
}
|
}
|
||||||
void Controller::queue_paced(std::string text, bool enter, bool review,
|
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) {
|
} catch (const std::exception& e) {
|
||||||
if (session_.state() == State::Recording || session_.state() == State::Transcribing) {
|
if (session_.state() == State::Recording || session_.state() == State::Transcribing) {
|
||||||
audio_.close(); session_.fail(); armed_focus_.reset(); status_note_.clear();
|
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();
|
detail_ = e.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
virtual ~ControllerFocus() = default;
|
virtual ~ControllerFocus() = default;
|
||||||
virtual bool arm() = 0;
|
virtual bool arm() = 0;
|
||||||
virtual bool valid() = 0;
|
virtual bool valid() = 0;
|
||||||
|
virtual const char* failure() const { return "focus unavailable"; }
|
||||||
};
|
};
|
||||||
using FocusFactory = std::function<std::unique_ptr<ControllerFocus>()>;
|
using FocusFactory = std::function<std::unique_ptr<ControllerFocus>()>;
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -167,9 +167,11 @@ bool FocusGuard::arm() {
|
|||||||
auto& p = *impl_;
|
auto& p = *impl_;
|
||||||
if (p.attempted || p.dead) return false;
|
if (p.attempted || p.dead) return false;
|
||||||
p.attempted = true;
|
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;
|
int screen_number = 0;
|
||||||
p.connection = xcb_connect(nullptr, &screen_number);
|
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);
|
const xcb_setup_t* setup = xcb_get_setup(p.connection);
|
||||||
auto iter = xcb_setup_roots_iterator(setup);
|
auto iter = xcb_setup_roots_iterator(setup);
|
||||||
for (int i = 0; i < screen_number && iter.rem; ++i) xcb_screen_next(&iter);
|
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());
|
trace_(std::string("focus invalid: ") + guard_.failure());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
const char* failure() const override { return guard_.failure(); }
|
||||||
private:
|
private:
|
||||||
FocusGuard guard_;
|
FocusGuard guard_;
|
||||||
DeliveryTrace& trace_;
|
DeliveryTrace& trace_;
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ private:
|
|||||||
int main() {
|
int main() {
|
||||||
try {
|
try {
|
||||||
DisplaySetting isolated_display;
|
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.
|
FocusGuard guard; // Construction must not connect to X.
|
||||||
CHECK(!guard.valid());
|
CHECK(!guard.valid());
|
||||||
CHECK(!guard.arm()); // No server: fail closed.
|
CHECK(!guard.arm()); // No server: fail closed.
|
||||||
|
|||||||
Reference in new issue
Block a user