Force window always on top, even if restacking order changes

This commit is contained in:
dec05eba
2024-11-02 11:56:01 +01:00
parent 6fbd8b0dd3
commit bfadff61d2
5 changed files with 27 additions and 15 deletions

4
TODO
View File

@@ -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.

View File

@@ -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;

View File

@@ -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);
}
}
} }

View File

@@ -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;
} }

View File

@@ -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;