mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-05-05 22:40:44 +09:00
Force window always on top, even if restacking order changes
This commit is contained in:
4
TODO
4
TODO
@@ -54,10 +54,10 @@ Look at /home/dec05eba/git/global-hotkeys for hotkeys.
|
|||||||
|
|
||||||
Show navigation breadcrumbs for settings and deeper navigation (such as selecting a directory to save videos).
|
Show navigation breadcrumbs for settings and deeper navigation (such as selecting a directory to save videos).
|
||||||
|
|
||||||
If recording stops because of an error then the ui wont be running and we wont get a notification that recording failed.
|
|
||||||
|
|
||||||
Add option to hide stream key like a password input.
|
Add option to hide stream key like a password input.
|
||||||
|
|
||||||
Add global setting. In that setting there should be an option to enable/disable gsr-ui from system startup (the systemd service).
|
Add global setting. In that setting there should be an option to enable/disable gsr-ui from system startup (the systemd service).
|
||||||
|
|
||||||
Add profiles and hotkey to switch between profiles (show notification when switching profile).
|
Add profiles and hotkey to switch between profiles (show notification when switching profile).
|
||||||
|
|
||||||
|
Fix first frame being black.
|
||||||
|
|||||||
@@ -7,11 +7,12 @@
|
|||||||
#include "window_texture.h"
|
#include "window_texture.h"
|
||||||
|
|
||||||
#include <mglpp/window/Window.hpp>
|
#include <mglpp/window/Window.hpp>
|
||||||
|
#include <mglpp/window/Event.hpp>
|
||||||
#include <mglpp/graphics/Texture.hpp>
|
#include <mglpp/graphics/Texture.hpp>
|
||||||
#include <mglpp/graphics/Sprite.hpp>
|
#include <mglpp/graphics/Sprite.hpp>
|
||||||
#include <mglpp/graphics/Rectangle.hpp>
|
#include <mglpp/graphics/Rectangle.hpp>
|
||||||
#include <mglpp/graphics/Text.hpp>
|
#include <mglpp/graphics/Text.hpp>
|
||||||
#include <mglpp/window/Event.hpp>
|
#include <mglpp/system/Clock.hpp>
|
||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
class DropdownButton;
|
class DropdownButton;
|
||||||
@@ -32,7 +33,7 @@ namespace gsr {
|
|||||||
|
|
||||||
class Overlay {
|
class Overlay {
|
||||||
public:
|
public:
|
||||||
Overlay(std::string resources_path, GsrInfo gsr_info, egl_functions egl_funcs, mgl::Color bg_color);
|
Overlay(std::string resources_path, GsrInfo gsr_info, egl_functions egl_funcs);
|
||||||
Overlay(const Overlay&) = delete;
|
Overlay(const Overlay&) = delete;
|
||||||
Overlay& operator=(const Overlay&) = delete;
|
Overlay& operator=(const Overlay&) = delete;
|
||||||
~Overlay();
|
~Overlay();
|
||||||
@@ -75,6 +76,8 @@ namespace gsr {
|
|||||||
void on_press_start_record();
|
void on_press_start_record();
|
||||||
void on_press_start_stream();
|
void on_press_start_stream();
|
||||||
bool update_compositor_texture(const mgl_monitor *monitor);
|
bool update_compositor_texture(const mgl_monitor *monitor);
|
||||||
|
|
||||||
|
void force_window_on_top();
|
||||||
private:
|
private:
|
||||||
using KeyBindingCallback = std::function<void()>;
|
using KeyBindingCallback = std::function<void()>;
|
||||||
struct KeyBinding {
|
struct KeyBinding {
|
||||||
@@ -87,7 +90,6 @@ namespace gsr {
|
|||||||
std::string resources_path;
|
std::string resources_path;
|
||||||
GsrInfo gsr_info;
|
GsrInfo gsr_info;
|
||||||
egl_functions egl_funcs;
|
egl_functions egl_funcs;
|
||||||
mgl::Color bg_color;
|
|
||||||
std::vector<gsr::AudioDevice> audio_devices;
|
std::vector<gsr::AudioDevice> audio_devices;
|
||||||
mgl::Texture window_texture_texture;
|
mgl::Texture window_texture_texture;
|
||||||
mgl::Sprite window_texture_sprite;
|
mgl::Sprite window_texture_sprite;
|
||||||
@@ -109,6 +111,7 @@ namespace gsr {
|
|||||||
DropdownButton *replay_dropdown_button_ptr = nullptr;
|
DropdownButton *replay_dropdown_button_ptr = nullptr;
|
||||||
DropdownButton *record_dropdown_button_ptr = nullptr;
|
DropdownButton *record_dropdown_button_ptr = nullptr;
|
||||||
DropdownButton *stream_dropdown_button_ptr = nullptr;
|
DropdownButton *stream_dropdown_button_ptr = nullptr;
|
||||||
|
mgl::Clock force_window_on_top_clock;
|
||||||
|
|
||||||
RecordingStatus recording_status = RecordingStatus::NONE;
|
RecordingStatus recording_status = RecordingStatus::NONE;
|
||||||
bool paused = false;
|
bool paused = false;
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
|
static const mgl::Color bg_color(0, 0, 0, 100);
|
||||||
|
static const double force_window_on_top_timeout_seconds = 1.0;
|
||||||
|
|
||||||
static mgl::Texture texture_from_ximage(XImage *img) {
|
static mgl::Texture texture_from_ximage(XImage *img) {
|
||||||
uint8_t *texture_data = (uint8_t*)malloc(img->width * img->height * 3);
|
uint8_t *texture_data = (uint8_t*)malloc(img->width * img->height * 3);
|
||||||
// TODO:
|
// TODO:
|
||||||
@@ -185,11 +188,10 @@ namespace gsr {
|
|||||||
return XGetSelectionOwner(dpy, prop_atom) != None;
|
return XGetSelectionOwner(dpy, prop_atom) != None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Overlay::Overlay(std::string resources_path, GsrInfo gsr_info, egl_functions egl_funcs, mgl::Color bg_color) :
|
Overlay::Overlay(std::string resources_path, GsrInfo gsr_info, egl_functions egl_funcs) :
|
||||||
resources_path(std::move(resources_path)),
|
resources_path(std::move(resources_path)),
|
||||||
gsr_info(gsr_info),
|
gsr_info(gsr_info),
|
||||||
egl_funcs(egl_funcs),
|
egl_funcs(egl_funcs),
|
||||||
bg_color(bg_color),
|
|
||||||
bg_screenshot_overlay({0.0f, 0.0f}),
|
bg_screenshot_overlay({0.0f, 0.0f}),
|
||||||
top_bar_background({0.0f, 0.0f}),
|
top_bar_background({0.0f, 0.0f}),
|
||||||
close_button_widget({0.0f, 0.0f}),
|
close_button_widget({0.0f, 0.0f}),
|
||||||
@@ -297,6 +299,8 @@ namespace gsr {
|
|||||||
if(!window)
|
if(!window)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
force_window_on_top();
|
||||||
|
|
||||||
window->clear(bg_color);
|
window->clear(bg_color);
|
||||||
|
|
||||||
if(window_texture_sprite.get_texture() && window_texture.texture_id) {
|
if(window_texture_sprite.get_texture() && window_texture.texture_id) {
|
||||||
@@ -1291,4 +1295,15 @@ namespace gsr {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Overlay::force_window_on_top() {
|
||||||
|
if(force_window_on_top_clock.get_elapsed_time_seconds() >= force_window_on_top_timeout_seconds) {
|
||||||
|
force_window_on_top_clock.restart();
|
||||||
|
|
||||||
|
mgl_context *context = mgl_get_context();
|
||||||
|
Display *display = (Display*)context->connection;
|
||||||
|
XRaiseWindow(display, window->get_system_handle());
|
||||||
|
XFlush(display);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -526,7 +526,7 @@ namespace gsr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CheckBox> SettingsPage::create_start_replay_on_startup() {
|
std::unique_ptr<CheckBox> SettingsPage::create_start_replay_on_startup() {
|
||||||
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Start replay automatically");
|
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Turn on replay automatically");
|
||||||
start_replay_automatically_ptr = checkbox.get();
|
start_replay_automatically_ptr = checkbox.get();
|
||||||
return checkbox;
|
return checkbox;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,19 +15,13 @@
|
|||||||
|
|
||||||
// TODO: Make keyboard controllable for steam deck (and other controllers).
|
// TODO: Make keyboard controllable for steam deck (and other controllers).
|
||||||
// TODO: Keep track of gpu screen recorder run by other programs to not allow recording at the same time, or something.
|
// TODO: Keep track of gpu screen recorder run by other programs to not allow recording at the same time, or something.
|
||||||
// TODO: Remove gpu-screen-recorder-overlay-daemon and handle that alt+z global hotkey here instead, to show/hide the window
|
|
||||||
// without restaring the program. Or make the daemon handle gpu screen recorder program state and pass that to the overlay.
|
|
||||||
// TODO: Add systray by using org.kde.StatusNotifierWatcher/etc dbus directly.
|
// TODO: Add systray by using org.kde.StatusNotifierWatcher/etc dbus directly.
|
||||||
// TODO: Dont allow replay and record/stream at the same time. If we want to allow that then do that in gpu screen recorder instead
|
|
||||||
// to make it more efficient by doing record/replay/stream with the same encoded packets.
|
|
||||||
// TODO: Make sure the overlay always stays on top. Test with starting the overlay and then opening youtube in fullscreen.
|
// TODO: Make sure the overlay always stays on top. Test with starting the overlay and then opening youtube in fullscreen.
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <mgl/mgl.h>
|
#include <mgl/mgl.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
const mgl::Color bg_color(0, 0, 0, 100);
|
|
||||||
|
|
||||||
static sig_atomic_t running = 1;
|
static sig_atomic_t running = 1;
|
||||||
static void sigint_handler(int signal) {
|
static void sigint_handler(int signal) {
|
||||||
(void)signal;
|
(void)signal;
|
||||||
@@ -99,7 +93,7 @@ int main(void) {
|
|||||||
|
|
||||||
fprintf(stderr, "info: gsr ui is now ready, waiting for inputs. Press alt+z to show/hide the overlay\n");
|
fprintf(stderr, "info: gsr ui is now ready, waiting for inputs. Press alt+z to show/hide the overlay\n");
|
||||||
|
|
||||||
auto overlay = std::make_unique<gsr::Overlay>(resources_path, gsr_info, egl_funcs, bg_color);
|
auto overlay = std::make_unique<gsr::Overlay>(resources_path, gsr_info, egl_funcs);
|
||||||
//overlay.show();
|
//overlay.show();
|
||||||
|
|
||||||
gsr::GlobalHotkeysX11 global_hotkeys;
|
gsr::GlobalHotkeysX11 global_hotkeys;
|
||||||
|
|||||||
Reference in New Issue
Block a user