mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-03-31 09:17:04 +09:00
Start on rpc, open existing instances ui when trying to launch gsr-ui a second time
This commit is contained in:
@@ -89,7 +89,7 @@ namespace gsr {
|
||||
}
|
||||
|
||||
bool GlobalHotkeysLinux::bind_action(const std::string &id, GlobalHotkeyCallback callback) {
|
||||
return bound_actions_by_id.insert(std::make_pair(id, callback)).second;
|
||||
return bound_actions_by_id.insert(std::make_pair(id, std::move(callback))).second;
|
||||
}
|
||||
|
||||
void GlobalHotkeysLinux::poll_events() {
|
||||
@@ -103,20 +103,23 @@ namespace gsr {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string action;
|
||||
char buffer[256];
|
||||
while(true) {
|
||||
char *line = fgets(buffer, sizeof(buffer), read_file);
|
||||
if(!line)
|
||||
break;
|
||||
|
||||
const int line_len = strlen(line);
|
||||
int line_len = strlen(line);
|
||||
if(line_len == 0)
|
||||
continue;
|
||||
|
||||
if(line[line_len - 1] == '\n')
|
||||
if(line[line_len - 1] == '\n') {
|
||||
line[line_len - 1] = '\0';
|
||||
--line_len;
|
||||
}
|
||||
|
||||
const std::string action = line;
|
||||
action = line;
|
||||
auto it = bound_actions_by_id.find(action);
|
||||
if(it != bound_actions_by_id.end())
|
||||
it->second(action);
|
||||
|
||||
133
src/Rpc.cpp
Normal file
133
src/Rpc.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
#include "../include/Rpc.hpp"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
namespace gsr {
|
||||
static void get_runtime_filepath(char *buffer, size_t buffer_size, const char *filename) {
|
||||
char dir[PATH_MAX];
|
||||
|
||||
const char *runtime_dir = getenv("XDG_RUNTIME_DIR");
|
||||
if(runtime_dir)
|
||||
snprintf(dir, sizeof(dir), "%s", runtime_dir);
|
||||
else
|
||||
snprintf(dir, sizeof(dir), "/run/user/%d", geteuid());
|
||||
|
||||
if(access(dir, F_OK) != 0)
|
||||
snprintf(dir, sizeof(dir), "/tmp");
|
||||
|
||||
snprintf(buffer, buffer_size, "%s/%s", dir, filename);
|
||||
}
|
||||
|
||||
Rpc::~Rpc() {
|
||||
if(fd > 0)
|
||||
close(fd);
|
||||
|
||||
if(file)
|
||||
fclose(file);
|
||||
|
||||
if(!fifo_filepath.empty())
|
||||
remove(fifo_filepath.c_str());
|
||||
}
|
||||
|
||||
bool Rpc::create(const char *name) {
|
||||
if(file) {
|
||||
fprintf(stderr, "Error: Rpc::create: already created/opened\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
char fifo_filepath_tmp[PATH_MAX];
|
||||
get_runtime_filepath(fifo_filepath_tmp, sizeof(fifo_filepath_tmp), name);
|
||||
fifo_filepath = fifo_filepath_tmp;
|
||||
remove(fifo_filepath.c_str());
|
||||
|
||||
if(mkfifo(fifo_filepath.c_str(), 0600) != 0) {
|
||||
fprintf(stderr, "Error: mkfifo failed, error: %s, %s\n", strerror(errno), fifo_filepath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!open_filepath(fifo_filepath.c_str())) {
|
||||
remove(fifo_filepath.c_str());
|
||||
fifo_filepath.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Rpc::open(const char *name) {
|
||||
if(file) {
|
||||
fprintf(stderr, "Error: Rpc::open: already created/opened\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
char fifo_filepath_tmp[PATH_MAX];
|
||||
get_runtime_filepath(fifo_filepath_tmp, sizeof(fifo_filepath_tmp), name);
|
||||
return open_filepath(fifo_filepath_tmp);
|
||||
}
|
||||
|
||||
bool Rpc::open_filepath(const char *filepath) {
|
||||
fd = ::open(filepath, O_RDWR | O_NONBLOCK);
|
||||
if(fd <= 0)
|
||||
return false;
|
||||
|
||||
file = fdopen(fd, "r+");
|
||||
if(!file) {
|
||||
close(fd);
|
||||
fd = 0;
|
||||
return false;
|
||||
}
|
||||
fd = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Rpc::write(const char *str, size_t size) {
|
||||
if(!file) {
|
||||
fprintf(stderr, "Error: Rpc::write: fifo not created/opened yet\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ssize_t offset = 0;
|
||||
while(offset < (ssize_t)size) {
|
||||
const ssize_t bytes_written = fwrite(str + offset, 1, size - offset, file);
|
||||
fflush(file);
|
||||
if(bytes_written > 0)
|
||||
offset += bytes_written;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Rpc::poll() {
|
||||
if(!file) {
|
||||
//fprintf(stderr, "Error: Rpc::poll: fifo not created/opened yet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
char line[1024];
|
||||
while(fgets(line, sizeof(line), file)) {
|
||||
int line_len = strlen(line);
|
||||
if(line_len == 0)
|
||||
continue;
|
||||
|
||||
if(line[line_len - 1] == '\n') {
|
||||
line[line_len - 1] = '\0';
|
||||
--line_len;
|
||||
}
|
||||
|
||||
name = line;
|
||||
auto it = handlers_by_name.find(name);
|
||||
if(it != handlers_by_name.end())
|
||||
it->second(name);
|
||||
}
|
||||
}
|
||||
|
||||
bool Rpc::add_handler(const std::string &name, RpcCallback callback) {
|
||||
return handlers_by_name.insert(std::make_pair(name, std::move(callback))).second;
|
||||
}
|
||||
}
|
||||
33
src/main.cpp
33
src/main.cpp
@@ -5,6 +5,7 @@
|
||||
#include "../include/GlobalHotkeysLinux.hpp"
|
||||
#include "../include/gui/Utils.hpp"
|
||||
#include "../include/Process.hpp"
|
||||
#include "../include/Rpc.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
@@ -193,8 +194,14 @@ int main(int argc, char **argv) {
|
||||
// TODO: This is a shitty method to detect if multiple instances of gsr-ui is running but this will work properly even in flatpak
|
||||
// that uses pid sandboxing. Replace this with a better method once we no longer rely on linux global hotkeys on some platform.
|
||||
if(is_gsr_ui_virtual_keyboard_running()) {
|
||||
const char *args[] = { "gsr-notify", "--text", "Another instance of GPU Screen Recorder UI is already running.\nPress Alt+Z to open the UI.", "--timeout", "5.0", "--icon-color", "ff0000", "--bg-color", "ff0000", nullptr };
|
||||
gsr::exec_program_daemonized(args);
|
||||
gsr::Rpc rpc;
|
||||
if(rpc.open("gsr-ui") && rpc.write("show_ui", 7)) {
|
||||
fprintf(stderr, "Error: another instance of gsr-ui is already running, opening that one instead\n");
|
||||
} else {
|
||||
fprintf(stderr, "Error: failed to send command to running gsr-ui instance, user will have to open the UI manually with Alt+Z\n");
|
||||
const char *args[] = { "gsr-notify", "--text", "Another instance of GPU Screen Recorder UI is already running.\nPress Alt+Z to open the UI.", "--timeout", "5.0", "--icon-color", "ff0000", "--bg-color", "ff0000", nullptr };
|
||||
gsr::exec_program_daemonized(args);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// const pid_t gsr_ui_pid = gsr::pidof("gsr-ui");
|
||||
@@ -264,18 +271,16 @@ int main(int argc, char **argv) {
|
||||
|
||||
fprintf(stderr, "Info: gsr ui is now ready, waiting for inputs. Press alt+z to show/hide the overlay\n");
|
||||
|
||||
auto rpc = std::make_unique<gsr::Rpc>();
|
||||
if(!rpc->create("gsr-ui"))
|
||||
fprintf(stderr, "Error: Failed to create rpc, commands won't be received\n");
|
||||
|
||||
auto overlay = std::make_unique<gsr::Overlay>(resources_path, std::move(gsr_info), std::move(capture_options), egl_funcs);
|
||||
|
||||
// std::unique_ptr<gsr::GlobalHotkeys> global_hotkeys = nullptr;
|
||||
// if(display_server == gsr::DisplayServer::X11) {
|
||||
// global_hotkeys = register_x11_hotkeys(overlay.get());
|
||||
// if(!global_hotkeys) {
|
||||
// fprintf(stderr, "Info: failed to register some x11 hotkeys because they are registered by another program. Will use linux hotkeys instead\n");
|
||||
// global_hotkeys = register_linux_hotkeys(overlay.get());
|
||||
// }
|
||||
// } else {
|
||||
// global_hotkeys = register_linux_hotkeys(overlay.get());
|
||||
// }
|
||||
rpc->add_handler("show_ui", [&](const std::string&) {
|
||||
overlay->show();
|
||||
});
|
||||
|
||||
std::unique_ptr<gsr::GlobalHotkeys> global_hotkeys = register_linux_hotkeys(overlay.get());
|
||||
|
||||
if(launch_action == LaunchAction::LAUNCH_SHOW)
|
||||
@@ -290,6 +295,7 @@ int main(int argc, char **argv) {
|
||||
const double frame_delta_seconds = frame_delta_clock.restart();
|
||||
gsr::set_frame_delta_seconds(frame_delta_seconds);
|
||||
|
||||
rpc->poll();
|
||||
global_hotkeys->poll_events();
|
||||
overlay->handle_events(global_hotkeys.get());
|
||||
if(!overlay->draw()) {
|
||||
@@ -299,11 +305,12 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
fprintf(stderr, "Info: shutting down!\n");
|
||||
rpc.reset();
|
||||
global_hotkeys.reset();
|
||||
overlay.reset();
|
||||
gsr::deinit_theme();
|
||||
gsr::deinit_color_theme();
|
||||
mgl_deinit();
|
||||
global_hotkeys.reset();
|
||||
|
||||
if(exit_reason == "back-to-old-ui") {
|
||||
const char *args[] = { "gpu-screen-recorder-gtk", "use-old-ui", nullptr };
|
||||
|
||||
Reference in New Issue
Block a user