WIP kinda working wayland hot keys

focus_loss
jackun 2 years ago
parent db9a23eb5a
commit 26c8d1dbdd
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3

@ -12,6 +12,8 @@
#include "../overlay.h"
#include "notify.h"
#include "mangoapp.h"
#include "wsi_helpers.h"
#include "keybinds.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
@ -303,7 +305,7 @@ int main(int, char**)
new_frame = false;
}
check_keybinds(params, vendorID);
check_keybinds(keys_are_pressed, params);
// Start the Dear ImGui frame
{
if (render(window)) {

@ -175,7 +175,7 @@ void imgui_create(void *ctx, GL_SESSION gl_session)
if (gl_session == GL_SESSION_X11)
wsi_conn.keys_are_pressed = keys_are_pressed;
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
#if !defined(MANGOAPP) && defined(VK_USE_PLATFORM_WAYLAND_KHR)
if (gl_session == GL_SESSION_WL)
{
wsi_conn.keys_are_pressed = wl_keys_are_pressed;
@ -216,7 +216,7 @@ void imgui_render(unsigned int width, unsigned int height)
process_control_socket(control_client, params);
}
check_keybinds(wsi_conn, params);
check_keybinds(wsi_conn.keys_are_pressed, params);
update_hud_info(sw_stats, params, vendorID);
ImGuiContext *saved_ctx = ImGui::GetCurrentContext();

@ -13,28 +13,6 @@
Clock::time_point last_f2_press, toggle_fps_limit_press , last_f12_press, reload_cfg_press, last_upload_press;
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
std::map<xkb_keysym_t, bool> xkb_state;
void wl_key_pressed(const xkb_keysym_t key, uint32_t state)
{
xkb_state[key] = !!state;
}
bool wl_keys_are_pressed(const std::vector<xkb_keysym_t>& keys) {
size_t pressed = 0;
for (KeySym ks : keys) {
if (xkb_state[ks])
pressed++;
}
if (pressed > 0 && pressed == keys.size()) {
return true;
}
return false;
}
#endif
#if defined(HAVE_X11)
bool keys_are_pressed(const std::vector<xkb_keysym_t>& keys) {
@ -83,7 +61,7 @@ bool keys_are_pressed(const std::vector<xkb_keysym_t>& keys) {
}
#endif
void check_keybinds(wsi_connection& wsi, struct overlay_params& params){
void check_keybinds(fun_keys_are_pressed keys_are_pressed, struct overlay_params& params){
using namespace std::chrono_literals;
auto now = Clock::now(); /* us */
auto elapsedF2 = now - last_f2_press;
@ -99,14 +77,14 @@ void check_keybinds(wsi_connection& wsi, struct overlay_params& params){
auto keyPressDelay = 400ms;
if (!wsi.keys_are_pressed)
if (!keys_are_pressed)
{
SPDLOG_DEBUG("wsi.keys_are_pressed is not set!");
SPDLOG_DEBUG("keys_are_pressed is not set!");
return;
}
if (elapsedF2 >= keyPressDelay &&
wsi.keys_are_pressed(params.toggle_logging)) {
keys_are_pressed(params.toggle_logging)) {
last_f2_press = now;
if (logger->is_active()) {
logger->stop_logging();
@ -117,7 +95,7 @@ void check_keybinds(wsi_connection& wsi, struct overlay_params& params){
}
if (elapsedFpsLimitToggle >= keyPressDelay &&
wsi.keys_are_pressed(params.toggle_fps_limit)) {
keys_are_pressed(params.toggle_fps_limit)) {
toggle_fps_limit_press = now;
for (size_t i = 0; i < params.fps_limit.size(); i++){
uint32_t fps_limit = params.fps_limit[i];
@ -136,26 +114,26 @@ void check_keybinds(wsi_connection& wsi, struct overlay_params& params){
}
if (elapsedF12 >= keyPressDelay &&
wsi.keys_are_pressed(params.toggle_hud)) {
keys_are_pressed(params.toggle_hud)) {
last_f12_press = now;
params.no_display = !params.no_display;
}
if (elapsedReloadCfg >= keyPressDelay &&
wsi.keys_are_pressed(params.reload_cfg)) {
keys_are_pressed(params.reload_cfg)) {
parse_overlay_config(&params, getenv("MANGOHUD_CONFIG"));
_params = &params;
reload_cfg_press = now;
}
if (params.permit_upload && elapsedUpload >= keyPressDelay &&
wsi.keys_are_pressed(params.upload_log)) {
keys_are_pressed(params.upload_log)) {
last_upload_press = now;
logger->upload_last_log();
}
if (params.permit_upload && elapsedUpload >= keyPressDelay &&
wsi.keys_are_pressed(params.upload_logs)) {
keys_are_pressed(params.upload_logs)) {
last_upload_press = now;
logger->upload_last_logs();
}

@ -12,10 +12,8 @@ typedef uint32_t xkb_keysym_t;
struct wsi_connection;
struct overlay_params;
void check_keybinds(wsi_connection&, overlay_params& params);
typedef std::function<bool(const std::vector<xkb_keysym_t>& keys)> fun_keys_are_pressed;
void check_keybinds(fun_keys_are_pressed, overlay_params& params);
bool keys_are_pressed(const std::vector<xkb_keysym_t>& keys);
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
bool wl_keys_are_pressed(const std::vector<xkb_keysym_t>& keys);
void wl_key_pressed(const xkb_keysym_t key, uint32_t state);
#endif
#endif //MANGOHUD_KEYBINDS_H

@ -249,6 +249,7 @@ if get_option('mangoapp') and sizeof_ptr == 8
spdlog_dep,
dbus_dep,
dep_x11,
dep_xkb,
glfw3_dep,
json_dep,
],

@ -252,7 +252,7 @@ void update_hud_info_with_frametime(struct swapchain_stats& sw_stats, const stru
#ifndef MANGOAPP
window_has_focus(sw_stats.wsi);
SPDLOG_DEBUG("lost focus: {}", sw_stats.lost_focus);
// SPDLOG_DEBUG("lost focus: {}", sw_stats.lost_focus);
#endif
sw_stats.fps = 1000000000.0 * sw_stats.n_frames_since_update / elapsed;

@ -133,6 +133,7 @@ parse_string_to_keysym_vec(const char *str)
for (auto& ks : keyStrings) {
trim(ks);
auto xk = xkb_keysym_from_name(ks.c_str(), XKB_KEYSYM_NO_FLAGS);
SPDLOG_DEBUG("KeySym: {}, {:08X}", ks, xk);
if (xk)
keys.push_back(xk);
else

@ -479,6 +479,10 @@ static void overlay_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
{
struct instance_data *instance_data = FIND(struct instance_data, instance);
struct surface_data *surface_data = FIND(struct surface_data, surface);
if (surface_data->wsi.wl.display)
wsi_wayland_deinit(surface_data->wsi);
destroy_surface_data(surface_data);
instance_data->vtable.DestroySurfaceKHR(instance, surface, pAllocator);
}
@ -536,7 +540,7 @@ static void snapshot_swapchain_frame(struct swapchain_data *data)
struct device_data *device_data = data->device;
struct instance_data *instance_data = device_data->instance;
update_hud_info(data->sw_stats, instance_data->params, device_data->properties.vendorID);
check_keybinds(data->surface_data->wsi, instance_data->params);
check_keybinds(data->surface_data->wsi.keys_are_pressed, instance_data->params);
#ifdef __linux__
if (instance_data->params.control >= 0) {
control_client_check(instance_data->params.control, instance_data->control_client, gpu.c_str());

@ -7,6 +7,7 @@
#include <xkbcommon/xkbcommon.h>
#endif
#include "wsi_helpers.h"
#include "keybinds.h" //TODO global funcs or pass by pointer with wsi_connection?
#ifdef VK_USE_PLATFORM_XCB_KHR
@ -98,60 +99,144 @@ void window_has_focus(wsi_connection* conn)
#endif
}
// -------- Wayland -------- //
struct table_entry {
// xkb_keysym_t symbol;
xkb_keycode_t code;
size_t level;
bool operator==(const table_entry& r) const
{
return code == r.code && level == r.level;
}
};
namespace std {
template <>
struct hash<table_entry>
{
std::size_t operator()(const table_entry& k) const
{
using std::hash;
return (hash<xkb_keycode_t>()(k.code) ^ (hash<size_t>()(k.level) << 1));
}
};
}
static std::unordered_map<xkb_keysym_t, std::vector<table_entry>> g_keysym_map;
struct wl_state
{
// wl_shell *shell;
// wl_seat *seat;
wsi_connection *wsi;
xkb_context *ctx;
xkb_keymap *keymap;
struct xkb_state *state;
} g_wl_state {}; //TODO per surface etc instance?
xkb_context *ctx;
xkb_keymap *keymap;
struct xkb_state *state;
};
// #ifdef VK_USE_PLATFORM_WAYLAND_KHR
static std::unordered_map<xkb_keycode_t, bool> xkb_state;
void wl_key_pressed(const xkb_keycode_t key, uint32_t state)
{
xkb_state[key] = !!state;
}
bool wl_keys_are_pressed(const std::vector<xkb_keysym_t>& keys) {
size_t pressed = 0;
for (auto ks : keys) {
auto kcs = g_keysym_map[ks];
// SPDLOG_DEBUG("code: {}, sym: {:08X}", kc.code, ks);
for (const auto& entry : kcs)
if (xkb_state[entry.code])
pressed++;
}
if (pressed > 0 && pressed == keys.size()) {
return true;
}
return false;
}
// #endif
static void key_iter(struct xkb_keymap* map, xkb_keycode_t code, void* data)
{
size_t n_levels = xkb_keymap_num_levels_for_key(map, code, 0);
for (size_t level = 0; level < n_levels; level++) {
const xkb_keysym_t* symbols;
size_t n = xkb_keymap_key_get_syms_by_level(map, code, 0, level, &symbols);
for (size_t i = 0; i < n; i++)
g_keysym_map[symbols[i]].push_back ({ code, level });
}
}
static void keyboard_keymap (void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size) {
SPDLOG_DEBUG("{}", __func__);
auto conn = reinterpret_cast<wsi_connection*>(data);
wl_state* state = reinterpret_cast<wl_state *>(conn->userdata);
if (!state->ctx)
return;
assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1);
char *map_shm = reinterpret_cast<char *>(mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0));
assert(map_shm != MAP_FAILED);
xkb_keymap_unref(g_wl_state.keymap);
g_wl_state.keymap = xkb_keymap_new_from_string(g_wl_state.ctx, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1,
XKB_KEYMAP_COMPILE_NO_FLAGS); // FIXME probably leaking stuff
xkb_keymap_unref(state->keymap);
state->keymap = xkb_keymap_new_from_string(state->ctx, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
munmap(map_shm, size);
close(fd);
xkb_state_unref(g_wl_state.state);
g_wl_state.state = xkb_state_new(g_wl_state.keymap); // FIXME probably leaking stuff
xkb_state_unref(state->state);
state->state = xkb_state_new(state->keymap);
xkb_keymap_key_for_each(state->keymap, key_iter, data);
}
static void keyboard_enter (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) {
auto wsi = reinterpret_cast<wsi_connection*>(data);
SPDLOG_DEBUG("{}: {} == {}", __func__, (void*)wsi->wl.surface, (void*)surface);
if (wsi->focus_changed && surface == wsi->wl.surface)
wsi->focus_changed(true);
auto conn = reinterpret_cast<wsi_connection*>(data);
SPDLOG_DEBUG("{}: {} == {}", __func__, (void*)conn->wl.surface, (void*)surface);
if (conn->focus_changed && surface == conn->wl.surface)
conn->focus_changed(true);
}
static void keyboard_leave (void *data, struct wl_keyboard *keyboard, uint32_t serial, struct wl_surface *surface) {
SPDLOG_DEBUG("{}: {}", __func__, (void*)surface);
auto wsi = reinterpret_cast<wsi_connection*>(data);
if (wsi->focus_changed && surface == wsi->wl.surface)
wsi->focus_changed(false);
auto conn = reinterpret_cast<wsi_connection*>(data);
if (conn->focus_changed && surface == conn->wl.surface)
conn->focus_changed(false);
}
static void keyboard_key (void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) {
auto wsi = reinterpret_cast<wsi_connection*>(data);
auto conn = reinterpret_cast<wsi_connection*>(data);
wl_state* wlstate = reinterpret_cast<wl_state *>(conn->userdata);
if (!wlstate->ctx)
return;
uint32_t keycode = key + 8;
xkb_keysym_t sym = xkb_state_key_get_one_sym(g_wl_state.state, keycode);
if (wsi->key_pressed)
wsi->key_pressed(sym, state);
// xkb_state_update_key(wlstate->state, keycode, state ? xkb_key_direction::XKB_KEY_DOWN : xkb_key_direction::XKB_KEY_UP);
auto level = xkb_state_key_get_level(wlstate->state, keycode, 0);
xkb_keysym_t sym = xkb_state_key_get_one_sym(wlstate->state, keycode);
// xkb_keysym_t sym = wlstate->xkb_keycode_map[{keycode, level}];
SPDLOG_DEBUG("{}: key pressed: {}, {}, {:08x}", __func__, key, state, sym);
// if (conn->key_pressed)
// conn->key_pressed(keycode, state);
wl_key_pressed(keycode, state);
SPDLOG_DEBUG("{}: key pressed: level:{}, keycode: {}, {}, keysym: {:08X}", __func__, level, keycode, state ? "down" : "up ", sym);
}
static void keyboard_modifiers (void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
SPDLOG_DEBUG("{}", __func__);
auto conn = reinterpret_cast<wsi_connection*>(data);
wl_state* wlstate = reinterpret_cast<wl_state *>(conn->userdata);
if (!wlstate->ctx)
return;
xkb_state_update_mask(wlstate->state, mods_depressed, mods_latched,
mods_locked, 0, 0, group);
}
static struct wl_keyboard_listener keyboard_listener = {&keyboard_keymap, &keyboard_enter, &keyboard_leave, &keyboard_key, &keyboard_modifiers};
@ -164,6 +249,7 @@ static void seat_capabilities (void *data, struct wl_seat *seat, uint32_t capabi
wl_keyboard_add_listener (keyboard, &keyboard_listener, data);
}
}
static struct wl_seat_listener seat_listener = {&seat_capabilities};
static void registry_add_object (void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) {
@ -175,6 +261,7 @@ static void registry_add_object (void *data, struct wl_registry *registry, uint3
wl_seat_add_listener (seat, &seat_listener, data);
}
}
static void registry_remove_object (void *data, struct wl_registry *registry, uint32_t name) {
}
@ -184,8 +271,20 @@ static struct wl_registry_listener registry_listener = {&registry_add_object, &r
void wsi_wayland_init(wsi_connection& conn)
{
auto registry = wl_display_get_registry(conn.wl.display);
g_wl_state.ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); //FIXME probably leaking stuff
g_wl_state.wsi = &conn; //TODO per surfacei nstance?
auto state = new wl_state();
state->ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!state->ctx)
SPDLOG_ERROR("Failed to create XKB context!");
conn.userdata = state;
wl_registry_add_listener(registry, &registry_listener, &conn);
wl_display_roundtrip(conn.wl.display);
}
void wsi_wayland_deinit(wsi_connection& conn)
{
wl_state* state = reinterpret_cast<wl_state *>(conn.userdata);
xkb_state_unref(state->state);
xkb_keymap_unref(state->keymap);
xkb_context_unref(state->ctx);
delete reinterpret_cast<wl_state *>(conn.userdata);
}

@ -20,31 +20,36 @@ typedef uint32_t xkb_keysym_t;
#include <wayland-client.h>
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
bool wl_keys_are_pressed(const std::vector<xkb_keysym_t>& keys);
void wl_key_pressed(const xkb_keycode_t key, uint32_t state);
#endif
struct wsi_connection
{
std::function<void(bool)> focus_changed;
std::function<void(xkb_keysym_t, uint32_t)> key_pressed;
std::function<bool(const std::vector<xkb_keysym_t>& keys)> keys_are_pressed;
void* userdata {};
#ifdef VK_USE_PLATFORM_XCB_KHR
struct xcb {
xcb_connection_t *conn;
xcb_window_t window;
} xcb;
} xcb {};
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
struct xlib {
Display *dpy;
Window window;
int evmask;
} xlib;
} xlib {};
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
struct wl {
wl_display *display;
wl_surface *surface;
} wl;
} wl {};
#endif
};
@ -52,4 +57,6 @@ struct wsi_connection
// bool check_window_focus(const wsi_connection&);
void wsi_wayland_init(wsi_connection& conn);
void wsi_wayland_deinit(wsi_connection& conn);

Loading…
Cancel
Save