Wayland: only prevent game minimizing if the input focused window is x11. Change screenshot program to a command instead, allows spectacle -E to work

This commit is contained in:
dec05eba
2025-12-22 15:55:13 +01:00
parent 245dcf5730
commit c039b79174
6 changed files with 27 additions and 11 deletions

6
TODO
View File

@@ -247,3 +247,9 @@ Remove all mgl::Clock usage in Overlay. We only need to get the time once per up
Handle stopping replay/stream when recording is running (show notification that the video is saved and move the video to folder with game name).
Support translations.
Sometimes when opening gpu screen recorder ui gsr-global-hotkeys incorrectly detects that keyboard input is locked.
When running replay for a long time and then stopping it it takes a while. Improve this.
When adding webcamera make replay auto start wait for camera to be available (when /dev/video device exists and can be initialized), just like audio device.

View File

@@ -19,8 +19,8 @@ namespace gsr {
};
std::optional<std::string> get_window_title(Display *dpy, Window window);
Window get_focused_window(Display *dpy, WindowCaptureType cap_type);
std::string get_focused_window_name(Display *dpy, WindowCaptureType window_capture_type);
Window get_focused_window(Display *dpy, WindowCaptureType cap_type, bool fallback_cursor_focused = true);
std::string get_focused_window_name(Display *dpy, WindowCaptureType window_capture_type, bool fallback_cursor_focused = true);
std::string get_window_name_at_position(Display *dpy, mgl::vec2i position, Window ignore_window);
std::string get_window_name_at_cursor_position(Display *dpy, Window ignore_window);
void set_window_size_not_resizable(Display *dpy, Window window, int width, int height);

View File

@@ -17,6 +17,7 @@
#include "../include/CursorTracker/CursorTrackerX11.hpp"
#include "../include/CursorTracker/CursorTrackerWayland.hpp"
#include <iomanip>
#include <string.h>
#include <assert.h>
#include <sys/wait.h>
@@ -1022,7 +1023,10 @@ namespace gsr {
// Wayland doesn't allow XGrabPointer/XGrabKeyboard when a wayland application is focused.
// If the focused window is a wayland application then don't use override redirect and instead create
// a fullscreen window for the ui.
const bool prevent_game_minimizing = gsr_info.system_info.display_server != DisplayServer::WAYLAND || (x11_cursor_window && is_window_fullscreen_on_monitor(display, x11_cursor_window, *focused_monitor)) || is_wlroots || is_hyprland;
const bool prevent_game_minimizing = gsr_info.system_info.display_server != DisplayServer::WAYLAND
|| (x11_cursor_window && is_window_fullscreen_on_monitor(display, x11_cursor_window, *focused_monitor) && get_focused_window(display, WindowCaptureType::FOCUSED, false) == x11_cursor_window)
|| is_wlroots
|| is_hyprland;
if(prevent_game_minimizing) {
window_pos = focused_monitor->position;
@@ -1917,7 +1921,7 @@ namespace gsr {
const Window gsr_ui_window = window ? (Window)window->get_system_handle() : None;
std::string focused_window_name = get_window_name_at_cursor_position(display, gsr_ui_window);
if(focused_window_name.empty())
focused_window_name = get_focused_window_name(display, WindowCaptureType::FOCUSED);
focused_window_name = get_focused_window_name(display, WindowCaptureType::FOCUSED, false);
if(focused_window_name.empty())
focused_window_name = "Game";
@@ -2178,7 +2182,10 @@ namespace gsr {
led_indicator->blink();
if(!strip(config.screenshot_config.custom_script).empty()) {
const char *args[] = { config.screenshot_config.custom_script.c_str(), screenshot_filepath.c_str(), nullptr };
std::stringstream ss;
ss << config.screenshot_config.custom_script << " " << std::quoted(screenshot_filepath);
const std::string command = ss.str();
const char *args[] = { "/bin/sh", "-c", command.c_str(), nullptr };
exec_program_on_host_daemonized(args);
}
} else {
@@ -2230,7 +2237,7 @@ namespace gsr {
mgl_context *context = mgl_get_context();
Display *display = (Display*)context->connection;
const Window focused_window = get_focused_window(display, WindowCaptureType::FOCUSED);
const Window focused_window = get_focused_window(display, WindowCaptureType::FOCUSED, false);
if(window && focused_window == (Window)window->get_system_handle())
return;

View File

@@ -121,7 +121,7 @@ namespace gsr {
return root_pos;
}
Window get_focused_window(Display *dpy, WindowCaptureType cap_type) {
Window get_focused_window(Display *dpy, WindowCaptureType cap_type, bool fallback_cursor_focused) {
//const Atom net_active_window_atom = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
Window focused_window = None;
@@ -146,6 +146,9 @@ namespace gsr {
XGetInputFocus(dpy, &focused_window, &revert_to);
if(focused_window && focused_window != DefaultRootWindow(dpy) && window_is_user_program(dpy, focused_window))
return focused_window;
if(!fallback_cursor_focused)
return None;
}
get_cursor_position(dpy, &focused_window);
@@ -213,9 +216,9 @@ namespace gsr {
return result;
}
std::string get_focused_window_name(Display *dpy, WindowCaptureType window_capture_type) {
std::string get_focused_window_name(Display *dpy, WindowCaptureType window_capture_type, bool fallback_cursor_focused) {
std::string result;
const Window focused_window = get_focused_window(dpy, window_capture_type);
const Window focused_window = get_focused_window(dpy, window_capture_type, fallback_cursor_focused);
if(focused_window == None)
return result;

View File

@@ -261,7 +261,7 @@ namespace gsr {
std::unique_ptr<List> ScreenshotSettingsPage::create_custom_script_screenshot() {
auto custom_script_screenshot_list = std::make_unique<List>(List::Orientation::VERTICAL);
custom_script_screenshot_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Program to open the screenshot with:", get_color_theme().text_color));
custom_script_screenshot_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Command to open the screenshot with:", get_color_theme().text_color));
custom_script_screenshot_list->add_widget(create_custom_script_screenshot_entry());
return custom_script_screenshot_list;
}