mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-01-31 01:13:04 +09:00
Better cursor position handling on wayland
This commit is contained in:
4
TODO
4
TODO
@@ -258,4 +258,6 @@ Redesign the UI to allow capturing multiple video sources. Move webcam to captur
|
||||
|
||||
Add option to choose video container (either flv or mpegts) for youtube livestreaming.
|
||||
|
||||
Get wayland cursor position for region selector, otherwise the start position before the cursor moves is off.
|
||||
Get wayland cursor position for region selector, otherwise the start position before the cursor moves is off.
|
||||
|
||||
Add option to set preset on nvidia. Use -ffmpeg-video-opts for that.
|
||||
|
||||
@@ -6,15 +6,19 @@
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#include <mglpp/system/Rect.hpp>
|
||||
|
||||
namespace gsr {
|
||||
static const int MAX_CONNECTORS = 32;
|
||||
static const uint32_t plane_property_all = 0xF;
|
||||
static const uint32_t plane_property_all = 0x3F;
|
||||
|
||||
typedef enum {
|
||||
PLANE_PROPERTY_CRTC_X = 1 << 0,
|
||||
PLANE_PROPERTY_CRTC_Y = 1 << 1,
|
||||
PLANE_PROPERTY_CRTC_ID = 1 << 2,
|
||||
PLANE_PROPERTY_TYPE_CURSOR = 1 << 3,
|
||||
PLANE_PROPERTY_CRTC_W = 1 << 2,
|
||||
PLANE_PROPERTY_CRTC_H = 1 << 3,
|
||||
PLANE_PROPERTY_CRTC_ID = 1 << 4,
|
||||
PLANE_PROPERTY_TYPE_CURSOR = 1 << 5,
|
||||
} plane_property_mask;
|
||||
|
||||
typedef struct {
|
||||
@@ -29,10 +33,17 @@ namespace gsr {
|
||||
bool has_any_crtc_with_vrr_enabled;
|
||||
} drm_connectors;
|
||||
|
||||
static bool rectangles_intersect(mgl::IntRect rect1, mgl::IntRect rect2) {
|
||||
return rect1.position.x < rect2.position.x + rect2.size.x && rect1.position.x + rect1.size.x > rect2.position.x &&
|
||||
rect1.position.y < rect2.position.y + rect2.size.y && rect1.position.y + rect1.size.y > rect2.position.y;
|
||||
}
|
||||
|
||||
/* Returns plane_property_mask */
|
||||
static uint32_t plane_get_properties(int drm_fd, uint32_t plane_id, int *crtc_x, int *crtc_y, int *crtc_id) {
|
||||
static uint32_t plane_get_properties(int drm_fd, uint32_t plane_id, int *crtc_x, int *crtc_y, int *crtc_w, int *crtc_h, int *crtc_id) {
|
||||
*crtc_x = 0;
|
||||
*crtc_y = 0;
|
||||
*crtc_w = 0;
|
||||
*crtc_h = 0;
|
||||
*crtc_id = 0;
|
||||
|
||||
uint32_t property_mask = 0;
|
||||
@@ -54,6 +65,12 @@ namespace gsr {
|
||||
} else if((type & DRM_MODE_PROP_SIGNED_RANGE) && strcmp(prop->name, "CRTC_Y") == 0) {
|
||||
*crtc_y = (int)props->prop_values[i];
|
||||
property_mask |= PLANE_PROPERTY_CRTC_Y;
|
||||
} else if((type & DRM_MODE_PROP_RANGE) && strcmp(prop->name, "CRTC_W") == 0) {
|
||||
*crtc_w = (int)props->prop_values[i];
|
||||
property_mask |= PLANE_PROPERTY_CRTC_W;
|
||||
} else if((type & DRM_MODE_PROP_RANGE) && strcmp(prop->name, "CRTC_H") == 0) {
|
||||
*crtc_h = (int)props->prop_values[i];
|
||||
property_mask |= PLANE_PROPERTY_CRTC_H;
|
||||
} else if((type & DRM_MODE_PROP_OBJECT) && strcmp(prop->name, "CRTC_ID") == 0) {
|
||||
*crtc_id = (int)props->prop_values[i];
|
||||
property_mask |= PLANE_PROPERTY_CRTC_ID;
|
||||
@@ -259,11 +276,17 @@ namespace gsr {
|
||||
for(uint32_t i = 0; i < planes->count_planes; ++i) {
|
||||
drmModePlanePtr plane = nullptr;
|
||||
const drm_connector *connector = nullptr;
|
||||
|
||||
int crtc_x = 0;
|
||||
int crtc_y = 0;
|
||||
int crtc_w = 0;
|
||||
int crtc_h = 0;
|
||||
int crtc_id = 0;
|
||||
uint32_t property_mask = 0;
|
||||
|
||||
mgl::IntRect monitor_rect;
|
||||
mgl::IntRect cursor_rect;
|
||||
|
||||
plane = drmModeGetPlane(drm_fd, planes->planes[i]);
|
||||
if(!plane)
|
||||
goto next;
|
||||
@@ -271,7 +294,7 @@ namespace gsr {
|
||||
if(!plane->fb_id)
|
||||
goto next;
|
||||
|
||||
property_mask = plane_get_properties(drm_fd, planes->planes[i], &crtc_x, &crtc_y, &crtc_id);
|
||||
property_mask = plane_get_properties(drm_fd, planes->planes[i], &crtc_x, &crtc_y, &crtc_w, &crtc_h, &crtc_id);
|
||||
if(property_mask != plane_property_all || crtc_id <= 0)
|
||||
goto next;
|
||||
|
||||
@@ -279,7 +302,10 @@ namespace gsr {
|
||||
if(!connector)
|
||||
goto next;
|
||||
|
||||
if(crtc_x >= 0 && crtc_x <= connector->size.x && crtc_y >= 0 && crtc_y <= connector->size.y) {
|
||||
monitor_rect = { mgl::vec2i(0, 0), connector->size };
|
||||
cursor_rect = { mgl::vec2i(crtc_x, crtc_y), mgl::vec2i(crtc_w, crtc_h) };
|
||||
|
||||
if(rectangles_intersect(cursor_rect, cursor_rect)) {
|
||||
latest_cursor_position.x = crtc_x;
|
||||
latest_cursor_position.y = crtc_y;
|
||||
latest_crtc_id = crtc_id;
|
||||
|
||||
@@ -1052,7 +1052,6 @@ namespace gsr {
|
||||
focused_monitor = find_monitor_by_name(monitors, cursor_info->monitor_name);
|
||||
if(!focused_monitor)
|
||||
focused_monitor = &monitors.front();
|
||||
cursor_position = cursor_info->position;
|
||||
} else {
|
||||
const mgl::vec2i monitor_position_query_value = (x11_cursor_window || gsr_info.system_info.display_server != DisplayServer::WAYLAND) ? cursor_position : create_window_get_center_position(display);
|
||||
focused_monitor = find_monitor_at_position(monitors, monitor_position_query_value);
|
||||
@@ -1069,6 +1068,10 @@ namespace gsr {
|
||||
|| is_wlroots
|
||||
|| is_hyprland;
|
||||
|
||||
const bool drm_cursor_pos = !prevent_game_minimizing && cursor_info;
|
||||
if(drm_cursor_pos)
|
||||
cursor_position = cursor_info->position;
|
||||
|
||||
if(prevent_game_minimizing) {
|
||||
window_pos = focused_monitor->position;
|
||||
window_size = focused_monitor->size;
|
||||
@@ -1162,7 +1165,7 @@ namespace gsr {
|
||||
// The real cursor doesn't move when all devices are grabbed, so we create our own cursor and diplay that while grabbed
|
||||
cursor_hotspot = {0, 0};
|
||||
xi_setup_fake_cursor();
|
||||
if(cursor_info && gsr_info.system_info.display_server == DisplayServer::WAYLAND) {
|
||||
if(drm_cursor_pos) {
|
||||
win->cursor_position.x += cursor_hotspot.x;
|
||||
win->cursor_position.y += cursor_hotspot.y;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user