Only capture focused window monitor when replay starts because of fullscreen window

This commit is contained in:
dec05eba
2026-03-10 12:58:53 +01:00
parent b8d29f0ac0
commit b32ae6e2f1
4 changed files with 68 additions and 46 deletions

View File

@@ -157,7 +157,7 @@ namespace gsr {
void on_press_save_replay();
void on_press_save_replay_1_min_replay();
void on_press_save_replay_10_min_replay();
bool on_press_start_replay(bool disable_notification, bool finished_selection);
bool on_press_start_replay(bool disable_notification, bool finished_selection, std::string monitor_to_capture = "");
void on_press_start_record(bool finished_selection, RecordForceType force_type);
void on_press_start_stream(bool finished_selection);
void on_press_take_screenshot(bool finished_selection, ScreenshotForceType force_type);

View File

@@ -20,6 +20,13 @@ namespace gsr {
std::string name;
};
struct DrawableGeometry {
int x = 0;
int y = 0;
int width = 0;
int height = 0;
};
std::optional<std::string> get_window_title(Display *dpy, Window window);
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);
@@ -39,6 +46,8 @@ namespace gsr {
void xi_warp_all_mouse_devices(Display *dpy, mgl::vec2i position);
void window_set_fullscreen(Display *dpy, Window window, bool fullscreen);
bool window_is_fullscreen(Display *display, Window window);
bool get_drawable_geometry(Display *display, Drawable drawable, DrawableGeometry *geometry);
std::optional<Monitor> get_monitor_by_window_center(Display *display, Window window);
bool set_window_wm_state(Display *dpy, Window window, Atom atom);
void make_window_click_through(Display *display, Window window);
bool make_window_sticky(Display *dpy, Window window);

View File

@@ -161,26 +161,6 @@ namespace gsr {
return result;
}
struct DrawableGeometry {
int x, y, width, height;
};
static bool get_drawable_geometry(Display *display, Drawable drawable, DrawableGeometry *geometry) {
geometry->x = 0;
geometry->y = 0;
geometry->width = 0;
geometry->height = 0;
Window root_window;
unsigned int w, h;
unsigned int dummy_border, dummy_depth;
Status s = XGetGeometry(display, drawable, &root_window, &geometry->x, &geometry->y, &w, &h, &dummy_border, &dummy_depth);
geometry->width = w;
geometry->height = h;
return s != Success;
}
static bool diff_int(int a, int b, int difference) {
return std::abs(a - b) <= difference;
}
@@ -2378,11 +2358,12 @@ namespace gsr {
const bool is_kwin_wayland = wm_name == "KWin" && gsr_info.system_info.display_server == DisplayServer::WAYLAND;
const bool prev_focused_window_is_fullscreen = focused_window_is_fullscreen;
Window focused_window = None;
if (is_kwin_wayland) {
focused_window_is_fullscreen = get_current_kwin_window_fullscreen();
} else {
const Window focused_window = get_focused_window(display, WindowCaptureType::FOCUSED, false);
focused_window = get_focused_window(display, WindowCaptureType::FOCUSED, false);
if(window && focused_window == (Window)window->get_system_handle())
return;
@@ -2390,11 +2371,22 @@ namespace gsr {
}
if(focused_window_is_fullscreen != prev_focused_window_is_fullscreen) {
std::string fullscreen_window_monitor;
if(is_kwin_wayland) {
fullscreen_window_monitor = get_current_kwin_window_monitor_name();
} else {
auto window_monitor = get_monitor_by_window_center(display, focused_window);
if(window_monitor.has_value())
fullscreen_window_monitor = std::move(window_monitor->name);
else
fullscreen_window_monitor.clear();
}
if(recording_status == RecordingStatus::NONE && focused_window_is_fullscreen) {
if(are_all_audio_tracks_available_to_capture(config.replay_config.record_options.audio_tracks_list) && is_webcam_available_to_capture(config.replay_config.record_options))
on_press_start_replay(false, false);
on_press_start_replay(false, false, fullscreen_window_monitor);
} else if(recording_status == RecordingStatus::REPLAY && !focused_window_is_fullscreen) {
on_press_start_replay(true, false);
on_press_start_replay(true, false, fullscreen_window_monitor);
}
}
}
@@ -2693,30 +2685,20 @@ namespace gsr {
if(capture_target == "window") {
return std::to_string(region_selector.get_window_selection());
} else if(capture_target == "focused_monitor") {
mgl_context *context = mgl_get_context();
Display *display = (Display*)context->connection;
const std::string wm_name = get_window_manager_name(display);
const bool is_kwin_wayland = wm_name == "KWin" && gsr_info.system_info.display_server == DisplayServer::WAYLAND;
std::string focused_monitor_name;
if (is_kwin_wayland && focused_window_is_fullscreen) {
focused_monitor_name = get_current_kwin_window_monitor_name();
} else {
std::optional<CursorInfo> cursor_info;
if(cursor_tracker) {
cursor_tracker->update();
cursor_info = cursor_tracker->get_latest_cursor_info();
}
std::string focused_monitor_name;
if(cursor_info) {
focused_monitor_name = std::move(cursor_info->monitor_name);
} else {
mgl_context *context = mgl_get_context();
Display *display = (Display*)context->connection;
focused_monitor_name = get_focused_monitor_by_cursor(cursor_tracker.get(), gsr_info, get_monitors(display));
}
}
focused_monitor_name = get_valid_capture_target(focused_monitor_name, capture_options);
if(!focused_monitor_name.empty())
@@ -2895,7 +2877,7 @@ namespace gsr {
return capture_source_arg;
}
bool Overlay::on_press_start_replay(bool disable_notification, bool finished_selection) {
bool Overlay::on_press_start_replay(bool disable_notification, bool finished_selection, std::string monitor_to_capture) {
if(region_selector.is_started())
return false;
@@ -2956,7 +2938,7 @@ namespace gsr {
}
const SupportedCaptureOptions capture_options = get_supported_capture_options(gsr_info);
recording_capture_target = get_capture_target(config.replay_config.record_options.record_area_option, capture_options);
recording_capture_target = !monitor_to_capture.empty() ? monitor_to_capture : get_capture_target(config.replay_config.record_options.record_area_option, capture_options);
if(!validate_capture_target(config.replay_config.record_options.record_area_option, capture_options)) {
char err_msg[256];
snprintf(err_msg, sizeof(err_msg), TR("Failed to start replay, capture target \"%s\" is invalid.\nPlease change capture target in settings"), recording_capture_target.c_str());

View File

@@ -11,6 +11,7 @@
#include <wayland-client.h>
#include "xdg-output-unstable-v1-client-protocol.h"
#include <mglpp/system/Rect.hpp>
#include <mglpp/system/Utf8.hpp>
extern "C" {
@@ -893,6 +894,36 @@ namespace gsr {
return is_fullscreen;
}
bool get_drawable_geometry(Display *display, Drawable drawable, DrawableGeometry *geometry) {
geometry->x = 0;
geometry->y = 0;
geometry->width = 0;
geometry->height = 0;
Window root_window;
unsigned int w, h;
unsigned int dummy_border, dummy_depth;
Status s = XGetGeometry(display, drawable, &root_window, &geometry->x, &geometry->y, &w, &h, &dummy_border, &dummy_depth);
geometry->width = w;
geometry->height = h;
return s != Success;
}
std::optional<Monitor> get_monitor_by_window_center(Display *display, Window window) {
DrawableGeometry geometry;
if(!get_drawable_geometry(display, window, &geometry))
return std::nullopt;
const mgl::vec2i window_center = mgl::vec2i(geometry.x, geometry.y) + mgl::vec2i(geometry.width, geometry.height) / 2;
auto monitors = get_monitors(display);
for(auto &monitor : monitors) {
if(mgl::IntRect(monitor.position, monitor.size).contains(window_center))
return std::move(monitor);
}
return std::nullopt;
}
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2