Fix window capture selection not working if the cursor is hidden and grabbed when starting capture

This commit is contained in:
dec05eba
2026-02-15 18:04:56 +01:00
parent 728ccc40a6
commit 1ce12067aa
10 changed files with 206 additions and 356 deletions

View File

@@ -9,7 +9,6 @@
#include "GlobalHotkeys/GlobalHotkeysJoystick.hpp"
#include "AudioPlayer.hpp"
#include "RegionSelector.hpp"
#include "WindowSelector.hpp"
#include "ClipboardFile.hpp"
#include "LedIndicator.hpp"
#include "CursorTracker/CursorTracker.hpp"
@@ -275,9 +274,7 @@ namespace gsr {
bool start_region_capture = false;
std::function<void()> on_region_selected;
WindowSelector window_selector;
bool start_window_capture = false;
std::function<void()> on_window_selected;
std::string recording_capture_target;
std::string screenshot_capture_target;

View File

@@ -15,14 +15,26 @@ namespace gsr {
mgl::vec2i size;
};
struct RegionWindow {
Window window = None;
mgl::vec2i pos;
mgl::vec2i size;
};
class RegionSelector {
public:
enum class SelectionType {
NONE,
REGION,
WINDOW
};
RegionSelector();
RegionSelector(const RegionSelector&) = delete;
RegionSelector& operator=(const RegionSelector&) = delete;
~RegionSelector();
bool start(mgl::Color border_color);
bool start(SelectionType selection_type, mgl::Color border_color);
void stop();
bool is_started() const;
@@ -30,7 +42,11 @@ namespace gsr {
bool poll_events();
bool take_selection();
bool take_canceled();
Region get_selection(Display *x11_dpy, struct wl_display *wayland_dpy) const;
Region get_region_selection(Display *x11_dpy, struct wl_display *wayland_dpy) const;
// Returns None (0) if none is selected
Window get_window_selection() const;
SelectionType get_selection_type() const;
private:
void on_button_press(const void *de);
void on_button_release(const void *de);
@@ -50,6 +66,10 @@ namespace gsr {
bool canceled = false;
bool is_wayland = false;
std::vector<Monitor> monitors;
std::vector<RegionWindow> windows; // First window is the window that is on top
std::optional<RegionWindow> focused_window;
mgl::vec2i cursor_pos;
SelectionType selection_type = SelectionType::NONE;
};
}

View File

@@ -1,33 +0,0 @@
#pragma once
#include <X11/Xlib.h>
#include <mglpp/graphics/Color.hpp>
namespace gsr {
class WindowSelector {
public:
WindowSelector();
WindowSelector(const WindowSelector&) = delete;
WindowSelector& operator=(const WindowSelector&) = delete;
~WindowSelector();
bool start(mgl::Color border_color);
void stop();
bool is_started() const;
bool failed() const;
bool poll_events();
bool take_selection();
bool take_canceled();
Window get_selection() const;
private:
Display *dpy = nullptr;
Cursor crosshair_cursor = None;
Colormap border_window_colormap = None;
Window border_window = None;
Window selected_window = None;
bool selected = false;
bool canceled = false;
};
}

View File

@@ -27,6 +27,7 @@ namespace gsr {
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);
Window window_get_target_window_child(Display *display, Window window);
unsigned char* window_get_property(Display *dpy, Window window, Atom property_type, const char *property_name, unsigned int *property_size);
mgl::vec2i get_cursor_position(Display *dpy, Window *window);
mgl::vec2i create_window_get_center_position(Display *display);
std::string get_window_manager_name(Display *display);