kranewl

A wlroots-based dynamic Wayland compositor, written in C++, configurable with Lua
git clone git://git.deurzen.net/kranewl
Log | Files | Refs | LICENSE

commit 7e52bfde60eeae43e37c66066d1fab8516912bac
parent 2754909b86d60c9c87c2c33a5e37ecfa1dec5227
Author: deurzen <m.deurzen@tum.de>
Date:   Sat, 21 May 2022 11:22:33 +0200

fixes race condition

Diffstat:
M.gitignore | 1+
MCMakeLists.txt | 6+++++-
Minclude/kranewl/model.hh | 6++----
Minclude/kranewl/server.hh | 8++++----
Dinclude/kranewl/tree/workspace.hh | 3---
Minclude/kranewl/workspace.hh | 6+++---
Ainclude/trace.hh | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minclude/version.hh | 4++--
Msrc/kranewl/conf/config.cc | 8--------
Msrc/kranewl/main.cc | 17+++++++++--------
Msrc/kranewl/model.cc | 25++++++++++++++++---------
Msrc/kranewl/server.cc | 1001+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Asrc/kranewl/trace.cc | 41+++++++++++++++++++++++++++++++++++++++++
Dsrc/kranewl/tree/workspace.cc | 3---
Asrc/kranewl/workspace.cc | 534+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15 files changed, 1188 insertions(+), 531 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -2,3 +2,4 @@ /tags /TODO /.ccls-cache +/.gdb_history diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -12,7 +12,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) add_compile_options( - -g -fdiagnostics-show-option # -Weffc++ -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic @@ -33,6 +32,11 @@ add_compile_options( -Wdouble-promotion -Wformat=2 -DXWAYLAND + -O0 + # debug options + -g + # -finstrument-functions -finstrument-functions-exclude-file-list=/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11,/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11/backward,/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.1/include/g++-v11/x86_64-pc-linux-gnu,/usr/local/include -ldl -Wl,--export-dynamic + ) find_program(CCACHE ccache) diff --git a/include/kranewl/model.hh b/include/kranewl/model.hh @@ -22,12 +22,10 @@ public: Model(Config const&, std::optional<std::string>); ~Model(); - void register_server(Server&); - - void run(); + void register_server(Server_ptr); void exit(); - Output_ptr create_output(struct wlr_output*, struct wlr_scene_output*); + Output_ptr create_output(Server_ptr, struct wlr_output*, struct wlr_scene_output*); void register_output(Output_ptr); void unregister_output(Output_ptr); diff --git a/include/kranewl/server.hh b/include/kranewl/server.hh @@ -11,7 +11,7 @@ extern "C" { #include <cstdint> #include <string> -class Model; +typedef class Model* Model_ptr; typedef struct Client* Client_ptr; typedef class Server* Server_ptr; typedef class Server final { @@ -22,18 +22,18 @@ typedef class Server final { }; public: - Server(Model&); + Server(Model_ptr); ~Server(); void start() noexcept; private: static void new_output(struct wl_listener*, void*); + static void output_destroy(struct wl_listener*, void*); static void output_layout_change(struct wl_listener*, void*); static void output_manager_apply(struct wl_listener*, void*); static void output_manager_test(struct wl_listener*, void*); static void output_frame(struct wl_listener*, void*); - static void output_destroy(struct wl_listener*, void*); static void new_xdg_surface(struct wl_listener*, void*); static void new_layer_shell_surface(struct wl_listener*, void*); @@ -83,7 +83,7 @@ private: static void xwayland_set_hints(struct wl_listener*, void*); #endif - Model& m_model; + Model_ptr mp_model; struct wl_display* mp_display; struct wl_event_loop* mp_event_loop; diff --git a/include/kranewl/tree/workspace.hh b/include/kranewl/tree/workspace.hh @@ -1,3 +0,0 @@ -#pragma once - - diff --git a/include/kranewl/workspace.hh b/include/kranewl/workspace.hh @@ -38,7 +38,7 @@ public: Index size() const; Index length() const; - Index main_count() const; + int main_count() const; Context_ptr context() const; @@ -90,8 +90,8 @@ public: void reset_margin(); void reset_layout_data(); - void save_layout(Index) const; - void load_layout(Index); + void save_layout(int) const; + void load_layout(int); void toggle_layout(); void set_layout(LayoutHandler::LayoutKind); diff --git a/include/trace.hh b/include/trace.hh @@ -0,0 +1,56 @@ +#pragma once + +#include <spdlog/spdlog.h> + +#include <string> + +#ifndef NDEBUG +#ifndef TRACING_DISABLED +#define TRACING_ENABLED 1 +#endif +#endif + +#ifdef TRACING_ENABLED +namespace tracing +{ + class Tracer { + public: + Tracer() = delete; + Tracer(Tracer const&) = delete; + Tracer(Tracer&&) = delete; + + Tracer& operator=(Tracer const&) = delete; + Tracer& operator=(Tracer&&) = delete; + + Tracer(std::string const& fun, std::string const& file, int const line) + : m_function_name{fun}, + m_file_name{file}, + m_line_number{line} + { + spdlog::trace("Entering function: " + + m_function_name + + " (" + + m_file_name + + ":" + + std::to_string(m_line_number) + + ")"); + } + + ~Tracer() + { + spdlog::trace("Leaving function: " + m_function_name); + } + + private: + std::string m_function_name; + std::string m_file_name; + int m_line_number; + }; +} +#endif + +#ifdef TRACING_ENABLED +#define TRACE() tracing::Tracer _tracer_object__ ## __COUNTER__ {__func__, __FILE__, __LINE__} +#else +#define TRACE() +#endif diff --git a/include/version.hh b/include/version.hh @@ -1 +1 @@ -#define VERSION "master/76dfd2d+" -\ No newline at end of file +#define VERSION "master/2754909+" +\ No newline at end of file diff --git a/src/kranewl/conf/config.cc b/src/kranewl/conf/config.cc @@ -59,8 +59,6 @@ ConfigParser::parse_decorations(Config& config) const noexcept static_cast<void>(config); lua_getglobal(m_state.get(), "decorations"); - if (lua_istable(m_state.get(), -1)) - print_table(m_state.get()); return true; } @@ -72,8 +70,6 @@ ConfigParser::parse_outputs(Config& config) const noexcept static_cast<void>(config); lua_getglobal(m_state.get(), "outputs"); - if (lua_istable(m_state.get(), -1)) - print_table(m_state.get()); return true; } @@ -85,8 +81,6 @@ ConfigParser::parse_commands(Config& config) const noexcept static_cast<void>(config); lua_getglobal(m_state.get(), "commands"); - if (lua_istable(m_state.get(), -1)) - print_table(m_state.get()); return true; } @@ -98,8 +92,6 @@ ConfigParser::parse_bindings(Config& config) const noexcept static_cast<void>(config); lua_getglobal(m_state.get(), "bindings"); - if (lua_istable(m_state.get(), -1)) - print_table(m_state.get()); return true; } diff --git a/src/kranewl/main.cc b/src/kranewl/main.cc @@ -1,7 +1,4 @@ -#ifndef NDEBUG -#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG -#endif - +#include <trace.hh> #include <version.hh> #include <kranewl/conf/config.hh> @@ -23,6 +20,13 @@ main(int argc, char** argv) { #ifndef NDEBUG /* wlr_log_init(WLR_DEBUG, NULL); */ +#ifdef TRACING_ENABLED + spdlog::set_level(spdlog::level::trace); +#else + spdlog::set_level(spdlog::level::debug); +#endif +#else + spdlog::set_level(spdlog::level::info); #endif const Options options = parse_options(argc, argv); @@ -32,10 +36,7 @@ main(int argc, char** argv) const Config config = config_parser.generate_config(); Model model{config, options.autostart_path}; - Server server{model}; - - model.register_server(server); - model.run(); + Server{&model}.start(); return EXIT_SUCCESS; } diff --git a/src/kranewl/model.cc b/src/kranewl/model.cc @@ -1,3 +1,5 @@ +#include <trace.hh> + #include <kranewl/model.hh> #include <kranewl/common.hh> @@ -38,6 +40,8 @@ Model::Model( m_key_bindings{}, m_mouse_bindings{} { + TRACE(); + #ifdef NDEBUG if (autostart_path) { spdlog::info("Executing autostart file at " + *autostart_path); @@ -82,23 +86,22 @@ Model::~Model() {} void -Model::register_server(Server& server) +Model::register_server(Server_ptr server) { - mp_server = &server; -} + TRACE(); -void -Model::run() -{ - mp_server->start(); + mp_server = server; } Output_ptr Model::create_output( + Server_ptr server, struct wlr_output* wlr_output, struct wlr_scene_output* wlr_scene_output ) { + TRACE(); + Output_ptr output = new Output( mp_server, wlr_output, @@ -111,15 +114,19 @@ Model::create_output( } void -Model::register_output(Output_ptr) +Model::register_output(Output_ptr output) { + TRACE(); + m_outputs.insert_at_back(output); } void -Model::unregister_output(Output_ptr) +Model::unregister_output(Output_ptr output) { + TRACE(); + m_outputs.remove_element(output); } Client_ptr diff --git a/src/kranewl/server.cc b/src/kranewl/server.cc @@ -1,3 +1,5 @@ +#include <trace.hh> + #include <kranewl/server.hh> #include <kranewl/exec.hh> @@ -66,8 +68,11 @@ extern "C" { #include <cstdlib> -Server::Server(Model& model) - : m_model(model), +Server::Server(Model_ptr model) + : mp_model([this,model]() { + model->register_server(this); + return model; + }()), mp_display(wl_display_create()), mp_event_loop(wl_display_get_event_loop(mp_display)), mp_backend(wlr_backend_autocreate(mp_display)), @@ -106,6 +111,8 @@ Server::Server(Model& model) #endif m_socket(wl_display_add_socket_auto(mp_display)) { + TRACE(); + mp_compositor = wlr_compositor_create(mp_display, mp_renderer); mp_data_device_manager = wlr_data_device_manager_create(mp_display); @@ -227,6 +234,8 @@ Server::Server(Model& model) Server::~Server() { + TRACE(); + wl_display_destroy_clients(mp_display); wl_display_destroy(mp_display); } @@ -234,12 +243,16 @@ Server::~Server() void Server::start() noexcept { + TRACE(); + wl_display_run(mp_display); } void Server::new_output(struct wl_listener* listener, void* data) { + TRACE(); + Server_ptr server = wl_container_of(listener, server, ml_new_output); struct wlr_output* wlr_output = reinterpret_cast<struct wlr_output*>(data); @@ -254,11 +267,13 @@ Server::new_output(struct wl_listener* listener, void* data) return; } - Output_ptr output = server->m_model.create_output( + Output_ptr output = server->mp_model->create_output( + server, wlr_output, wlr_scene_output_create(server->mp_scene, wlr_output) ); + wlr_output->data = output; output->ml_frame.notify = Server::output_frame; output->ml_destroy.notify = Server::output_destroy; wl_signal_add(&wlr_output->events.frame, &output->ml_frame); @@ -268,6 +283,24 @@ Server::new_output(struct wl_listener* listener, void* data) } void +Server::output_destroy(struct wl_listener* listener, void* data) +{ + TRACE(); + + struct wlr_output* wlr_output = reinterpret_cast<struct wlr_output*>(data); + Output_ptr output = reinterpret_cast<Output_ptr>(wlr_output->data); + Server_ptr server = output->mp_server; + + wl_list_remove(&output->ml_destroy.link); + wl_list_remove(&output->ml_frame.link); + + wlr_scene_output_destroy(output->mp_wlr_scene_output); + wlr_output_layout_remove(server->mp_output_layout, output->mp_wlr_output); + + server->mp_model->unregister_output(output); +} + +void Server::output_layout_change(struct wl_listener* listener, void* data) { // TODO @@ -288,68 +321,64 @@ Server::output_manager_test(struct wl_listener* listener, void* data) void Server::output_frame(struct wl_listener* listener, void* data) { - Output_ptr output = wl_container_of(listener, output, ml_frame); + TRACE(); - wlr_scene_output_commit(output->mp_wlr_scene_output); + Output_ptr output = wl_container_of(listener, output, ml_frame); struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); - wlr_scene_output_send_frame_done(output->mp_wlr_scene_output, &now); -} -void -Server::output_destroy(struct wl_listener* listener, void* data) -{ - // TODO + wlr_scene_output_commit(output->mp_wlr_scene_output); + wlr_scene_output_send_frame_done(output->mp_wlr_scene_output, &now); } void Server::new_xdg_surface(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_new_xdg_surface); - - struct wlr_xdg_surface* xdg_surface = reinterpret_cast<struct wlr_xdg_surface*>(data); - - if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { - struct wlr_xdg_surface* parent - = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent); - - struct wlr_scene_node* parent_node - = reinterpret_cast<struct wlr_scene_node*>(parent->data); - - xdg_surface->data = wlr_scene_xdg_surface_create(parent_node, xdg_surface); - return; - } - assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); - - Client_ptr client = new Client( - server, - Surface{xdg_surface, true}, - nullptr, - nullptr, - nullptr - ); - - xdg_surface->data = client->mp_scene; - client->mp_scene = wlr_scene_xdg_surface_create( - &client->mp_server->mp_scene->node, - client->m_surface.xdg - ); - - client->mp_scene->data = client; - - client->ml_map.notify = xdg_toplevel_map; - wl_signal_add(&xdg_surface->events.map, &client->ml_map); - client->ml_unmap.notify = xdg_toplevel_unmap; - wl_signal_add(&xdg_surface->events.unmap, &client->ml_unmap); - client->ml_destroy.notify = xdg_toplevel_destroy; - wl_signal_add(&xdg_surface->events.destroy, &client->ml_destroy); - - struct wlr_xdg_toplevel* toplevel = xdg_surface->toplevel; - client->ml_request_move.notify = xdg_toplevel_request_move; - wl_signal_add(&toplevel->events.request_move, &client->ml_request_move); - client->ml_request_resize.notify = xdg_toplevel_request_resize; - wl_signal_add(&toplevel->events.request_resize, &client->ml_request_resize); + /* Server_ptr server = wl_container_of(listener, server, ml_new_xdg_surface); */ + + /* struct wlr_xdg_surface* xdg_surface = reinterpret_cast<struct wlr_xdg_surface*>(data); */ + + /* if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { */ + /* struct wlr_xdg_surface* parent */ + /* = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent); */ + + /* struct wlr_scene_node* parent_node */ + /* = reinterpret_cast<struct wlr_scene_node*>(parent->data); */ + + /* xdg_surface->data = wlr_scene_xdg_surface_create(parent_node, xdg_surface); */ + /* return; */ + /* } */ + /* assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL); */ + + /* Client_ptr client = new Client( */ + /* server, */ + /* Surface{xdg_surface, true}, */ + /* nullptr, */ + /* nullptr, */ + /* nullptr */ + /* ); */ + + /* xdg_surface->data = client->mp_scene; */ + /* client->mp_scene = wlr_scene_xdg_surface_create( */ + /* &client->mp_server->mp_scene->node, */ + /* client->m_surface.xdg */ + /* ); */ + + /* client->mp_scene->data = client; */ + + /* client->ml_map.notify = xdg_toplevel_map; */ + /* wl_signal_add(&xdg_surface->events.map, &client->ml_map); */ + /* client->ml_unmap.notify = xdg_toplevel_unmap; */ + /* wl_signal_add(&xdg_surface->events.unmap, &client->ml_unmap); */ + /* client->ml_destroy.notify = xdg_toplevel_destroy; */ + /* wl_signal_add(&xdg_surface->events.destroy, &client->ml_destroy); */ + + /* struct wlr_xdg_toplevel* toplevel = xdg_surface->toplevel; */ + /* client->ml_request_move.notify = xdg_toplevel_request_move; */ + /* wl_signal_add(&toplevel->events.request_move, &client->ml_request_move); */ + /* client->ml_request_resize.notify = xdg_toplevel_request_resize; */ + /* wl_signal_add(&toplevel->events.request_resize, &client->ml_request_resize); */ } void @@ -367,59 +396,59 @@ Server::xdg_activation(struct wl_listener* listener, void* data) void Server::new_input(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_new_input); - struct wlr_input_device* device = reinterpret_cast<struct wlr_input_device*>(data); - - switch (device->type) { - case WLR_INPUT_DEVICE_KEYBOARD: - new_keyboard(server, device); - break; - case WLR_INPUT_DEVICE_POINTER: - new_pointer(server, device); - break; - default: - break; - } - - uint32_t caps = WL_SEAT_CAPABILITY_POINTER; - if (!wl_list_empty(&server->m_keyboards)) - caps |= WL_SEAT_CAPABILITY_KEYBOARD; - - wlr_seat_set_capabilities(server->mp_seat, caps); + /* Server_ptr server = wl_container_of(listener, server, ml_new_input); */ + /* struct wlr_input_device* device = reinterpret_cast<struct wlr_input_device*>(data); */ + + /* switch (device->type) { */ + /* case WLR_INPUT_DEVICE_KEYBOARD: */ + /* new_keyboard(server, device); */ + /* break; */ + /* case WLR_INPUT_DEVICE_POINTER: */ + /* new_pointer(server, device); */ + /* break; */ + /* default: */ + /* break; */ + /* } */ + + /* uint32_t caps = WL_SEAT_CAPABILITY_POINTER; */ + /* if (!wl_list_empty(&server->m_keyboards)) */ + /* caps |= WL_SEAT_CAPABILITY_KEYBOARD; */ + + /* wlr_seat_set_capabilities(server->mp_seat, caps); */ } void Server::new_pointer(Server_ptr server, struct wlr_input_device* device) { - wlr_cursor_attach_input_device(server->mp_cursor, device); + /* wlr_cursor_attach_input_device(server->mp_cursor, device); */ } void Server::new_keyboard(Server_ptr server, struct wlr_input_device* device) { - Keyboard* keyboard = reinterpret_cast<Keyboard*>(calloc(1, sizeof(Keyboard))); - keyboard->mp_server = server; - keyboard->mp_device = device; - - struct xkb_context* context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - struct xkb_keymap* keymap = xkb_keymap_new_from_names( - context, - NULL, - XKB_KEYMAP_COMPILE_NO_FLAGS - ); - - wlr_keyboard_set_keymap(device->keyboard, keymap); - xkb_keymap_unref(keymap); - xkb_context_unref(context); - wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); - - keyboard->ml_modifiers.notify = keyboard_handle_modifiers; - wl_signal_add(&device->keyboard->events.modifiers, &keyboard->ml_modifiers); - keyboard->ml_key.notify = keyboard_handle_key; - wl_signal_add(&device->keyboard->events.key, &keyboard->ml_key); - - wlr_seat_set_keyboard(server->mp_seat, device); - wl_list_insert(&server->m_keyboards, &keyboard->m_link); + /* Keyboard* keyboard = reinterpret_cast<Keyboard*>(calloc(1, sizeof(Keyboard))); */ + /* keyboard->mp_server = server; */ + /* keyboard->mp_device = device; */ + + /* struct xkb_context* context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); */ + /* struct xkb_keymap* keymap = xkb_keymap_new_from_names( */ + /* context, */ + /* NULL, */ + /* XKB_KEYMAP_COMPILE_NO_FLAGS */ + /* ); */ + + /* wlr_keyboard_set_keymap(device->keyboard, keymap); */ + /* xkb_keymap_unref(keymap); */ + /* xkb_context_unref(context); */ + /* wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); */ + + /* keyboard->ml_modifiers.notify = keyboard_handle_modifiers; */ + /* wl_signal_add(&device->keyboard->events.modifiers, &keyboard->ml_modifiers); */ + /* keyboard->ml_key.notify = keyboard_handle_key; */ + /* wl_signal_add(&device->keyboard->events.key, &keyboard->ml_key); */ + + /* wlr_seat_set_keyboard(server->mp_seat, device); */ + /* wl_list_insert(&server->m_keyboards, &keyboard->m_link); */ } void @@ -449,210 +478,210 @@ Server::idle_inhibitor_destroy(struct wl_listener* listener, void* data) void Server::cursor_motion(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_cursor_motion); - struct wlr_event_pointer_motion* event - = reinterpret_cast<wlr_event_pointer_motion*>(data); + /* Server_ptr server = wl_container_of(listener, server, ml_cursor_motion); */ + /* struct wlr_event_pointer_motion* event */ + /* = reinterpret_cast<wlr_event_pointer_motion*>(data); */ - wlr_cursor_move(server->mp_cursor, event->device, event->delta_x, event->delta_y); - cursor_process_motion(server, event->time_msec); + /* wlr_cursor_move(server->mp_cursor, event->device, event->delta_x, event->delta_y); */ + /* cursor_process_motion(server, event->time_msec); */ } void Server::cursor_motion_absolute(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_cursor_motion_absolute); - struct wlr_event_pointer_motion_absolute* event - = reinterpret_cast<wlr_event_pointer_motion_absolute*>(data); + /* Server_ptr server = wl_container_of(listener, server, ml_cursor_motion_absolute); */ + /* struct wlr_event_pointer_motion_absolute* event */ + /* = reinterpret_cast<wlr_event_pointer_motion_absolute*>(data); */ - wlr_cursor_warp_absolute(server->mp_cursor, event->device, event->x, event->y); - cursor_process_motion(server, event->time_msec); + /* wlr_cursor_warp_absolute(server->mp_cursor, event->device, event->x, event->y); */ + /* cursor_process_motion(server, event->time_msec); */ } void Server::cursor_button(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_cursor_button); - - struct wlr_event_pointer_button* event - = reinterpret_cast<wlr_event_pointer_button*>(data); - - wlr_seat_pointer_notify_button( - server->mp_seat, - event->time_msec, - event->button, - event->state - ); - - struct wlr_surface* surface = NULL; - - double sx, sy; - Client_ptr client = desktop_client_at( - server, - server->mp_cursor->x, - server->mp_cursor->y, - &surface, - &sx, - &sy - ); - - if (event->state == WLR_BUTTON_RELEASED) - server->m_cursor_mode = Server::CursorMode::Passthrough; - else - focus_client(client, surface); + /* Server_ptr server = wl_container_of(listener, server, ml_cursor_button); */ + + /* struct wlr_event_pointer_button* event */ + /* = reinterpret_cast<wlr_event_pointer_button*>(data); */ + + /* wlr_seat_pointer_notify_button( */ + /* server->mp_seat, */ + /* event->time_msec, */ + /* event->button, */ + /* event->state */ + /* ); */ + + /* struct wlr_surface* surface = NULL; */ + + /* double sx, sy; */ + /* Client_ptr client = desktop_client_at( */ + /* server, */ + /* server->mp_cursor->x, */ + /* server->mp_cursor->y, */ + /* &surface, */ + /* &sx, */ + /* &sy */ + /* ); */ + + /* if (event->state == WLR_BUTTON_RELEASED) */ + /* server->m_cursor_mode = Server::CursorMode::Passthrough; */ + /* else */ + /* focus_client(client, surface); */ } void Server::cursor_axis(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_cursor_axis); - - struct wlr_event_pointer_axis* event - = reinterpret_cast<wlr_event_pointer_axis*>(data); - - wlr_seat_pointer_notify_axis( - server->mp_seat, - event->time_msec, - event->orientation, - event->delta, - event->delta_discrete, - event->source - ); + /* Server_ptr server = wl_container_of(listener, server, ml_cursor_axis); */ + + /* struct wlr_event_pointer_axis* event */ + /* = reinterpret_cast<wlr_event_pointer_axis*>(data); */ + + /* wlr_seat_pointer_notify_axis( */ + /* server->mp_seat, */ + /* event->time_msec, */ + /* event->orientation, */ + /* event->delta, */ + /* event->delta_discrete, */ + /* event->source */ + /* ); */ } void Server::cursor_frame(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_cursor_frame); + /* Server_ptr server = wl_container_of(listener, server, ml_cursor_frame); */ - wlr_seat_pointer_notify_frame(server->mp_seat); + /* wlr_seat_pointer_notify_frame(server->mp_seat); */ } void Server::request_set_cursor(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_request_set_cursor); - - struct wlr_seat_pointer_request_set_cursor_event* event - = reinterpret_cast<struct wlr_seat_pointer_request_set_cursor_event*>(data); - struct wlr_seat_client* focused_client = server->mp_seat->pointer_state.focused_client; - - if (focused_client == event->seat_client) - wlr_cursor_set_surface( - server->mp_cursor, - event->surface, - event->hotspot_x, - event->hotspot_y - ); + /* Server_ptr server = wl_container_of(listener, server, ml_request_set_cursor); */ + + /* struct wlr_seat_pointer_request_set_cursor_event* event */ + /* = reinterpret_cast<struct wlr_seat_pointer_request_set_cursor_event*>(data); */ + /* struct wlr_seat_client* focused_client = server->mp_seat->pointer_state.focused_client; */ + + /* if (focused_client == event->seat_client) */ + /* wlr_cursor_set_surface( */ + /* server->mp_cursor, */ + /* event->surface, */ + /* event->hotspot_x, */ + /* event->hotspot_y */ + /* ); */ } void Server::cursor_process_motion(Server_ptr server, uint32_t time) { - switch (server->m_cursor_mode) { - case Server::CursorMode::Move: cursor_process_move(server, time); return; - case Server::CursorMode::Resize: cursor_process_resize(server, time); return; - default: break; - } - - struct wlr_seat* seat = server->mp_seat; - struct wlr_surface* surface = NULL; - - double sx, sy; - Client_ptr client = desktop_client_at( - server, - server->mp_cursor->x, - server->mp_cursor->y, - &surface, - &sx, - &sy - ); - - if (!client) - wlr_xcursor_manager_set_cursor_image( - server->mp_cursor_manager, - "left_ptr", - server->mp_cursor - ); + /* switch (server->m_cursor_mode) { */ + /* case Server::CursorMode::Move: cursor_process_move(server, time); return; */ + /* case Server::CursorMode::Resize: cursor_process_resize(server, time); return; */ + /* default: break; */ + /* } */ + + /* struct wlr_seat* seat = server->mp_seat; */ + /* struct wlr_surface* surface = NULL; */ + + /* double sx, sy; */ + /* Client_ptr client = desktop_client_at( */ + /* server, */ + /* server->mp_cursor->x, */ + /* server->mp_cursor->y, */ + /* &surface, */ + /* &sx, */ + /* &sy */ + /* ); */ + + /* if (!client) */ + /* wlr_xcursor_manager_set_cursor_image( */ + /* server->mp_cursor_manager, */ + /* "left_ptr", */ + /* server->mp_cursor */ + /* ); */ - if (surface) { - wlr_seat_pointer_notify_enter(seat, surface, sx, sy); - wlr_seat_pointer_notify_motion(seat, time, sx, sy); - } else - wlr_seat_pointer_clear_focus(seat); + /* if (surface) { */ + /* wlr_seat_pointer_notify_enter(seat, surface, sx, sy); */ + /* wlr_seat_pointer_notify_motion(seat, time, sx, sy); */ + /* } else */ + /* wlr_seat_pointer_clear_focus(seat); */ } void Server::cursor_process_move(Server_ptr server, uint32_t time) { - Client_ptr client = server->mp_grabbed_client; + /* Client_ptr client = server->mp_grabbed_client; */ - client->m_active_region.pos.x = server->mp_cursor->x - server->m_grab_x; - client->m_active_region.pos.y = server->mp_cursor->y - server->m_grab_y; + /* client->m_active_region.pos.x = server->mp_cursor->x - server->m_grab_x; */ + /* client->m_active_region.pos.y = server->mp_cursor->y - server->m_grab_y; */ - wlr_scene_node_set_position( - client->mp_scene, - client->m_active_region.pos.x, - client->m_active_region.pos.y - ); + /* wlr_scene_node_set_position( */ + /* client->mp_scene, */ + /* client->m_active_region.pos.x, */ + /* client->m_active_region.pos.y */ + /* ); */ } void Server::cursor_process_resize(Server_ptr server, uint32_t time) { - Client_ptr client = server->mp_grabbed_client; + /* Client_ptr client = server->mp_grabbed_client; */ - double border_x = server->mp_cursor->x - server->m_grab_x; - double border_y = server->mp_cursor->y - server->m_grab_y; + /* double border_x = server->mp_cursor->x - server->m_grab_x; */ + /* double border_y = server->mp_cursor->y - server->m_grab_y; */ - int new_left = server->m_grab_geobox.x; - int new_right = server->m_grab_geobox.x + server->m_grab_geobox.width; - int new_top = server->m_grab_geobox.y; - int new_bottom = server->m_grab_geobox.y + server->m_grab_geobox.height; + /* int new_left = server->m_grab_geobox.x; */ + /* int new_right = server->m_grab_geobox.x + server->m_grab_geobox.width; */ + /* int new_top = server->m_grab_geobox.y; */ + /* int new_bottom = server->m_grab_geobox.y + server->m_grab_geobox.height; */ - if (server->m_resize_edges & WLR_EDGE_TOP) { - new_top = border_y; + /* if (server->m_resize_edges & WLR_EDGE_TOP) { */ + /* new_top = border_y; */ - if (new_top >= new_bottom) - new_top = new_bottom - 1; - } else if (server->m_resize_edges & WLR_EDGE_BOTTOM) { - new_bottom = border_y; + /* if (new_top >= new_bottom) */ + /* new_top = new_bottom - 1; */ + /* } else if (server->m_resize_edges & WLR_EDGE_BOTTOM) { */ + /* new_bottom = border_y; */ - if (new_bottom <= new_top) - new_bottom = new_top + 1; - } + /* if (new_bottom <= new_top) */ + /* new_bottom = new_top + 1; */ + /* } */ - if (server->m_resize_edges & WLR_EDGE_LEFT) { - new_left = border_x; + /* if (server->m_resize_edges & WLR_EDGE_LEFT) { */ + /* new_left = border_x; */ - if (new_left >= new_right) - new_left = new_right - 1; - } else if (server->m_resize_edges & WLR_EDGE_RIGHT) { - new_right = border_x; + /* if (new_left >= new_right) */ + /* new_left = new_right - 1; */ + /* } else if (server->m_resize_edges & WLR_EDGE_RIGHT) { */ + /* new_right = border_x; */ - if (new_right <= new_left) - new_right = new_left + 1; - } + /* if (new_right <= new_left) */ + /* new_right = new_left + 1; */ + /* } */ - struct wlr_box geo_box; - wlr_xdg_surface_get_geometry(client->m_surface.xdg, &geo_box); + /* struct wlr_box geo_box; */ + /* wlr_xdg_surface_get_geometry(client->m_surface.xdg, &geo_box); */ - client->m_active_region.pos.x = new_left - geo_box.x; - client->m_active_region.pos.y = new_top - geo_box.y; + /* client->m_active_region.pos.x = new_left - geo_box.x; */ + /* client->m_active_region.pos.y = new_top - geo_box.y; */ - wlr_scene_node_set_position( - client->mp_scene, - client->m_active_region.pos.x, - client->m_active_region.pos.y - ); + /* wlr_scene_node_set_position( */ + /* client->mp_scene, */ + /* client->m_active_region.pos.x, */ + /* client->m_active_region.pos.y */ + /* ); */ - int new_width = new_right - new_left; - int new_height = new_bottom - new_top; + /* int new_width = new_right - new_left; */ + /* int new_height = new_bottom - new_top; */ - wlr_xdg_toplevel_set_size( - client->m_surface.xdg, - new_width, - new_height - ); + /* wlr_xdg_toplevel_set_size( */ + /* client->m_surface.xdg, */ + /* new_width, */ + /* new_height */ + /* ); */ } void @@ -670,115 +699,115 @@ Server::start_drag(struct wl_listener*, void*) void Server::keyboard_handle_modifiers(struct wl_listener* listener, void* data) { - Keyboard* keyboard = wl_container_of(listener, keyboard, ml_modifiers); + /* Keyboard* keyboard = wl_container_of(listener, keyboard, ml_modifiers); */ - wlr_seat_set_keyboard(keyboard->mp_server->mp_seat, keyboard->mp_device); - wlr_seat_keyboard_notify_modifiers( - keyboard->mp_server->mp_seat, - &keyboard->mp_device->keyboard->modifiers - ); + /* wlr_seat_set_keyboard(keyboard->mp_server->mp_seat, keyboard->mp_device); */ + /* wlr_seat_keyboard_notify_modifiers( */ + /* keyboard->mp_server->mp_seat, */ + /* &keyboard->mp_device->keyboard->modifiers */ + /* ); */ } void Server::keyboard_handle_key(struct wl_listener* listener, void* data) { - Keyboard* keyboard = wl_container_of(listener, keyboard, ml_key); - Server_ptr server = keyboard->mp_server; - - struct wlr_event_keyboard_key* event - = reinterpret_cast<struct wlr_event_keyboard_key*>(data); - struct wlr_seat* seat = server->mp_seat; - - uint32_t keycode = event->keycode + 8; - const xkb_keysym_t* syms; - - int nsyms = xkb_state_key_get_syms( - keyboard->mp_device->keyboard->xkb_state, - keycode, - &syms - ); - - bool handled = false; - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->mp_device->keyboard); - - if ((modifiers & WLR_MODIFIER_ALT) && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - for (int i = 0; i < nsyms; i++) - handled = keyboard_handle_keybinding(server, syms[i]); - } - - if (!handled) { - wlr_seat_set_keyboard(seat, keyboard->mp_device); - wlr_seat_keyboard_notify_key( - seat, - event->time_msec, - event->keycode, - event->state - ); - } + /* Keyboard* keyboard = wl_container_of(listener, keyboard, ml_key); */ + /* Server_ptr server = keyboard->mp_server; */ + + /* struct wlr_event_keyboard_key* event */ + /* = reinterpret_cast<struct wlr_event_keyboard_key*>(data); */ + /* struct wlr_seat* seat = server->mp_seat; */ + + /* uint32_t keycode = event->keycode + 8; */ + /* const xkb_keysym_t* syms; */ + + /* int nsyms = xkb_state_key_get_syms( */ + /* keyboard->mp_device->keyboard->xkb_state, */ + /* keycode, */ + /* &syms */ + /* ); */ + + /* bool handled = false; */ + /* uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->mp_device->keyboard); */ + + /* if ((modifiers & WLR_MODIFIER_ALT) && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { */ + /* for (int i = 0; i < nsyms; i++) */ + /* handled = keyboard_handle_keybinding(server, syms[i]); */ + /* } */ + + /* if (!handled) { */ + /* wlr_seat_set_keyboard(seat, keyboard->mp_device); */ + /* wlr_seat_keyboard_notify_key( */ + /* seat, */ + /* event->time_msec, */ + /* event->keycode, */ + /* event->state */ + /* ); */ + /* } */ } bool Server::keyboard_handle_keybinding(Server_ptr server, xkb_keysym_t sym) { - switch (sym) { - case XKB_KEY_Escape: - wl_display_terminate(server->mp_display); - break; - case XKB_KEY_j: - { - if (wl_list_length(&server->m_clients) < 2) - break; - - /* Client_ptr prev_client = wl_container_of( */ - /* server->m_clients.prev, */ - /* prev_client, */ - /* link */ - /* ); */ - - /* focus_client( */ - /* prev_client, */ - /* prev_client->get_surface() */ - /* ); */ - } - break; - case XKB_KEY_Return: - { - std::string foot = "foot"; - exec_external(foot); - } - break; - case XKB_KEY_semicolon: - { - std::string st = "st"; - exec_external(st); - } - break; - default: return false; - } - - return true; + /* switch (sym) { */ + /* case XKB_KEY_Escape: */ + /* wl_display_terminate(server->mp_display); */ + /* break; */ + /* case XKB_KEY_j: */ + /* { */ + /* if (wl_list_length(&server->m_clients) < 2) */ + /* break; */ + + /* /1* Client_ptr prev_client = wl_container_of( *1/ */ + /* /1* server->m_clients.prev, *1/ */ + /* /1* prev_client, *1/ */ + /* /1* link *1/ */ + /* /1* ); *1/ */ + + /* /1* focus_client( *1/ */ + /* /1* prev_client, *1/ */ + /* /1* prev_client->get_surface() *1/ */ + /* /1* ); *1/ */ + /* } */ + /* break; */ + /* case XKB_KEY_Return: */ + /* { */ + /* std::string foot = "foot"; */ + /* exec_external(foot); */ + /* } */ + /* break; */ + /* case XKB_KEY_semicolon: */ + /* { */ + /* std::string st = "st"; */ + /* exec_external(st); */ + /* } */ + /* break; */ + /* default: return false; */ + /* } */ + + /* return true; */ } void Server::request_set_selection(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_request_set_selection); + /* Server_ptr server = wl_container_of(listener, server, ml_request_set_selection); */ - struct wlr_seat_request_set_selection_event* event - = reinterpret_cast<struct wlr_seat_request_set_selection_event*>(data); + /* struct wlr_seat_request_set_selection_event* event */ + /* = reinterpret_cast<struct wlr_seat_request_set_selection_event*>(data); */ - wlr_seat_set_selection(server->mp_seat, event->source, event->serial); + /* wlr_seat_set_selection(server->mp_seat, event->source, event->serial); */ } void Server::request_set_primary_selection(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_request_set_primary_selection); + /* Server_ptr server = wl_container_of(listener, server, ml_request_set_primary_selection); */ - struct wlr_seat_request_set_primary_selection_event* event - = reinterpret_cast<struct wlr_seat_request_set_primary_selection_event*>(data); + /* struct wlr_seat_request_set_primary_selection_event* event */ + /* = reinterpret_cast<struct wlr_seat_request_set_primary_selection_event*>(data); */ - wlr_seat_set_primary_selection(server->mp_seat, event->source, event->serial); + /* wlr_seat_set_primary_selection(server->mp_seat, event->source, event->serial); */ } Client_ptr @@ -791,109 +820,109 @@ Server::desktop_client_at( double* sy ) { - struct wlr_scene_node* node = wlr_scene_node_at( - &server->mp_scene->node, - lx, ly, - sx, sy - ); + /* struct wlr_scene_node* node = wlr_scene_node_at( */ + /* &server->mp_scene->node, */ + /* lx, ly, */ + /* sx, sy */ + /* ); */ - if (!node || node->type != WLR_SCENE_NODE_SURFACE) - return nullptr; + /* if (!node || node->type != WLR_SCENE_NODE_SURFACE) */ + /* return nullptr; */ - *surface = wlr_scene_surface_from_node(node)->surface; + /* *surface = wlr_scene_surface_from_node(node)->surface; */ - while (node && !node->data) - node = node->parent; + /* while (node && !node->data) */ + /* node = node->parent; */ - return reinterpret_cast<Client_ptr>(node->data); + /* return reinterpret_cast<Client_ptr>(node->data); */ } void Server::focus_client(Client_ptr client, struct wlr_surface* surface) { - if (!client) - return; - - Server_ptr server = client->mp_server; - struct wlr_seat* seat = server->mp_seat; - struct wlr_surface* prev_surface = seat->keyboard_state.focused_surface; - - if (prev_surface == surface) - return; - - /* if (prev_surface) */ - /* wlr_xdg_toplevel_set_activated( */ - /* wlr_xdg_surface_from_wlr_surface( */ - /* seat->keyboard_state.focused_surface */ - /* ), */ - /* false */ - /* ); */ - - struct wlr_keyboard* keyboard = wlr_seat_get_keyboard(seat); - - if (client->mp_scene) - wlr_scene_node_raise_to_top(client->mp_scene); - - /* wl_list_remove(&client->link); */ - /* wl_list_insert(&server->m_clients, &client->link); */ - - if (client->m_surface.type == SurfaceType::XDGShell || client->m_surface.type == SurfaceType::LayerShell) - wlr_xdg_toplevel_set_activated(client->m_surface.xdg, true); - - wlr_seat_keyboard_notify_enter( - seat, - client->get_surface(), - keyboard->keycodes, - keyboard->num_keycodes, - &keyboard->modifiers - ); + /* if (!client) */ + /* return; */ + + /* Server_ptr server = client->mp_server; */ + /* struct wlr_seat* seat = server->mp_seat; */ + /* struct wlr_surface* prev_surface = seat->keyboard_state.focused_surface; */ + + /* if (prev_surface == surface) */ + /* return; */ + + /* /1* if (prev_surface) *1/ */ + /* /1* wlr_xdg_toplevel_set_activated( *1/ */ + /* /1* wlr_xdg_surface_from_wlr_surface( *1/ */ + /* /1* seat->keyboard_state.focused_surface *1/ */ + /* /1* ), *1/ */ + /* /1* false *1/ */ + /* /1* ); *1/ */ + + /* struct wlr_keyboard* keyboard = wlr_seat_get_keyboard(seat); */ + + /* if (client->mp_scene) */ + /* wlr_scene_node_raise_to_top(client->mp_scene); */ + + /* /1* wl_list_remove(&client->link); *1/ */ + /* /1* wl_list_insert(&server->m_clients, &client->link); *1/ */ + + /* if (client->m_surface.type == SurfaceType::XDGShell || client->m_surface.type == SurfaceType::LayerShell) */ + /* wlr_xdg_toplevel_set_activated(client->m_surface.xdg, true); */ + + /* wlr_seat_keyboard_notify_enter( */ + /* seat, */ + /* client->get_surface(), */ + /* keyboard->keycodes, */ + /* keyboard->num_keycodes, */ + /* &keyboard->modifiers */ + /* ); */ } void Server::xdg_toplevel_map(struct wl_listener* listener, void* data) { - Client_ptr client = wl_container_of(listener, client, ml_map); + /* Client_ptr client = wl_container_of(listener, client, ml_map); */ - /* wl_list_insert(&client->server->m_clients, &client->link); */ - focus_client(client, client->get_surface()); + /* /1* wl_list_insert(&client->server->m_clients, &client->link); *1/ */ + /* focus_client(client, client->get_surface()); */ } void Server::xdg_toplevel_unmap(struct wl_listener* listener, void* data) { - Client_ptr client = wl_container_of(listener, client, ml_unmap); - /* wl_list_remove(&client->link); */ + /* Client_ptr client = wl_container_of(listener, client, ml_unmap); */ + /* /1* wl_list_remove(&client->link); *1/ */ } void Server::xdg_toplevel_destroy(struct wl_listener* listener, void* data) { - Client_ptr client = wl_container_of(listener, client, ml_destroy); + /* Client_ptr client = wl_container_of(listener, client, ml_destroy); */ - wl_list_remove(&client->ml_map.link); - wl_list_remove(&client->ml_unmap.link); - wl_list_remove(&client->ml_destroy.link); - wl_list_remove(&client->ml_request_move.link); - wl_list_remove(&client->ml_request_resize.link); + /* wl_list_remove(&client->ml_map.link); */ + /* wl_list_remove(&client->ml_unmap.link); */ + /* wl_list_remove(&client->ml_destroy.link); */ + /* wl_list_remove(&client->ml_request_move.link); */ + /* wl_list_remove(&client->ml_request_resize.link); */ - delete client; + /* delete client; */ } void Server::xdg_toplevel_request_move(struct wl_listener* listener, void* data) { - Client_ptr client = wl_container_of(listener, client, ml_request_move); - xdg_toplevel_handle_moveresize(client, Server::CursorMode::Move, 0); + /* Client_ptr client = wl_container_of(listener, client, ml_request_move); */ + /* xdg_toplevel_handle_moveresize(client, Server::CursorMode::Move, 0); */ } void Server::xdg_toplevel_request_resize(struct wl_listener* listener, void* data) { - struct wlr_xdg_toplevel_resize_event* event - = reinterpret_cast<struct wlr_xdg_toplevel_resize_event*>(data); + /* struct wlr_xdg_toplevel_resize_event* event */ + /* = reinterpret_cast<struct wlr_xdg_toplevel_resize_event*>(data); */ - Client_ptr client = wl_container_of(listener, client, ml_request_resize); - xdg_toplevel_handle_moveresize(client, Server::CursorMode::Resize, event->edges); + /* Client_ptr client = wl_container_of(listener, client, ml_request_resize); */ + /* xdg_toplevel_handle_moveresize(client, Server::CursorMode::Resize, event->edges); */ } void @@ -903,111 +932,111 @@ Server::xdg_toplevel_handle_moveresize( uint32_t edges ) { - Server_ptr server = client->mp_server; - - if (client->get_surface() - != wlr_surface_get_root_surface(server->mp_seat->pointer_state.focused_surface)) - { - return; - } - - server->mp_grabbed_client = client; - server->m_cursor_mode = mode; - - switch (mode) { - case Server::CursorMode::Move: - server->m_grab_x = server->mp_cursor->x - client->m_active_region.pos.x; - server->m_grab_y = server->mp_cursor->y - client->m_active_region.pos.y; - return; - case Server::CursorMode::Resize: - { - struct wlr_box geo_box; - wlr_xdg_surface_get_geometry(client->m_surface.xdg, &geo_box); - - double border_x = (client->m_active_region.pos.x + geo_box.x) + - ((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0); - - double border_y = (client->m_active_region.pos.y + geo_box.y) + - ((edges & WLR_EDGE_BOTTOM) ? geo_box.height : 0); - - server->m_grab_x = server->mp_cursor->x - border_x; - server->m_grab_y = server->mp_cursor->y - border_y; - - server->m_grab_geobox = geo_box; - server->m_grab_geobox.x += client->m_active_region.pos.x; - server->m_grab_geobox.y += client->m_active_region.pos.y; - - server->m_resize_edges = edges; - } - return; - default: return; - } + /* Server_ptr server = client->mp_server; */ + + /* if (client->get_surface() */ + /* != wlr_surface_get_root_surface(server->mp_seat->pointer_state.focused_surface)) */ + /* { */ + /* return; */ + /* } */ + + /* server->mp_grabbed_client = client; */ + /* server->m_cursor_mode = mode; */ + + /* switch (mode) { */ + /* case Server::CursorMode::Move: */ + /* server->m_grab_x = server->mp_cursor->x - client->m_active_region.pos.x; */ + /* server->m_grab_y = server->mp_cursor->y - client->m_active_region.pos.y; */ + /* return; */ + /* case Server::CursorMode::Resize: */ + /* { */ + /* struct wlr_box geo_box; */ + /* wlr_xdg_surface_get_geometry(client->m_surface.xdg, &geo_box); */ + + /* double border_x = (client->m_active_region.pos.x + geo_box.x) + */ + /* ((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0); */ + + /* double border_y = (client->m_active_region.pos.y + geo_box.y) + */ + /* ((edges & WLR_EDGE_BOTTOM) ? geo_box.height : 0); */ + + /* server->m_grab_x = server->mp_cursor->x - border_x; */ + /* server->m_grab_y = server->mp_cursor->y - border_y; */ + + /* server->m_grab_geobox = geo_box; */ + /* server->m_grab_geobox.x += client->m_active_region.pos.x; */ + /* server->m_grab_geobox.y += client->m_active_region.pos.y; */ + + /* server->m_resize_edges = edges; */ + /* } */ + /* return; */ + /* default: return; */ + /* } */ } #ifdef XWAYLAND void Server::xwayland_ready(struct wl_listener* listener, void*) { - Server_ptr server = wl_container_of(listener, server, ml_xwayland_ready); - - xcb_connection_t* xconn = xcb_connect(server->mp_xwayland->display_name, NULL); - if (xcb_connection_has_error(xconn)) { - spdlog::error("Could not establish a connection with the X server"); - spdlog::warn("Continuing with limited XWayland functionality"); - return; - } - - /* netatom[NetWMWindowTypeDialog] = getatom(xconn, "_NET_WM_WINDOW_TYPE_DIALOG"); */ - /* netatom[NetWMWindowTypeSplash] = getatom(xconn, "_NET_WM_WINDOW_TYPE_SPLASH"); */ - /* netatom[NetWMWindowTypeToolbar] = getatom(xconn, "_NET_WM_WINDOW_TYPE_TOOLBAR"); */ - /* netatom[NetWMWindowTypeUtility] = getatom(xconn, "_NET_WM_WINDOW_TYPE_UTILITY"); */ - - wlr_xwayland_set_seat(server->mp_xwayland, server->mp_seat); - - struct wlr_xcursor* xcursor; - if ((xcursor = wlr_xcursor_manager_get_xcursor(server->mp_cursor_manager, "left_ptr", 1))) - wlr_xwayland_set_cursor(server->mp_xwayland, - xcursor->images[0]->buffer, xcursor->images[0]->width * 4, - xcursor->images[0]->width, xcursor->images[0]->height, - xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y); - - xcb_disconnect(xconn); + /* Server_ptr server = wl_container_of(listener, server, ml_xwayland_ready); */ + + /* xcb_connection_t* xconn = xcb_connect(server->mp_xwayland->display_name, NULL); */ + /* if (xcb_connection_has_error(xconn)) { */ + /* spdlog::error("Could not establish a connection with the X server"); */ + /* spdlog::warn("Continuing with limited XWayland functionality"); */ + /* return; */ + /* } */ + + /* /1* netatom[NetWMWindowTypeDialog] = getatom(xconn, "_NET_WM_WINDOW_TYPE_DIALOG"); *1/ */ + /* /1* netatom[NetWMWindowTypeSplash] = getatom(xconn, "_NET_WM_WINDOW_TYPE_SPLASH"); *1/ */ + /* /1* netatom[NetWMWindowTypeToolbar] = getatom(xconn, "_NET_WM_WINDOW_TYPE_TOOLBAR"); *1/ */ + /* /1* netatom[NetWMWindowTypeUtility] = getatom(xconn, "_NET_WM_WINDOW_TYPE_UTILITY"); *1/ */ + + /* wlr_xwayland_set_seat(server->mp_xwayland, server->mp_seat); */ + + /* struct wlr_xcursor* xcursor; */ + /* if ((xcursor = wlr_xcursor_manager_get_xcursor(server->mp_cursor_manager, "left_ptr", 1))) */ + /* wlr_xwayland_set_cursor(server->mp_xwayland, */ + /* xcursor->images[0]->buffer, xcursor->images[0]->width * 4, */ + /* xcursor->images[0]->width, xcursor->images[0]->height, */ + /* xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y); */ + + /* xcb_disconnect(xconn); */ } void Server::new_xwayland_surface(struct wl_listener* listener, void* data) { - Server_ptr server = wl_container_of(listener, server, ml_new_xwayland_surface); - - struct wlr_xwayland_surface* xwayland_surface - = reinterpret_cast<wlr_xwayland_surface*>(data); - - Client_ptr client = new Client( - server, - Surface{xwayland_surface, xwayland_surface->override_redirect}, - nullptr, - nullptr, - nullptr - ); - - xwayland_surface->data = client; - - client->ml_map = { .notify = Server::xdg_toplevel_map }; - client->ml_unmap = { .notify = Server::xdg_toplevel_unmap }; - client->ml_destroy = { .notify = Server::xdg_toplevel_destroy }; - // TODO: client->ml_set_title = { .notify = Server::... }; - // TODO: client->ml_fullscreen = { .notify = Server::... }; - client->ml_request_activate = { .notify = Server::xwayland_request_activate }; - client->ml_request_configure = { .notify = Server::xwayland_request_configure }; - client->ml_set_hints = { .notify = Server::xwayland_set_hints }; - // TODO: client->ml_new_xdg_popup = { .notify = Server::... }; - - wl_signal_add(&xwayland_surface->events.map, &client->ml_map); - wl_signal_add(&xwayland_surface->events.unmap, &client->ml_unmap); - wl_signal_add(&xwayland_surface->events.destroy, &client->ml_destroy); - wl_signal_add(&xwayland_surface->events.request_activate, &client->ml_request_activate); - wl_signal_add(&xwayland_surface->events.request_configure, &client->ml_request_configure); - wl_signal_add(&xwayland_surface->events.set_hints, &client->ml_set_hints); + /* Server_ptr server = wl_container_of(listener, server, ml_new_xwayland_surface); */ + + /* struct wlr_xwayland_surface* xwayland_surface */ + /* = reinterpret_cast<wlr_xwayland_surface*>(data); */ + + /* Client_ptr client = new Client( */ + /* server, */ + /* Surface{xwayland_surface, xwayland_surface->override_redirect}, */ + /* nullptr, */ + /* nullptr, */ + /* nullptr */ + /* ); */ + + /* xwayland_surface->data = client; */ + + /* client->ml_map = { .notify = Server::xdg_toplevel_map }; */ + /* client->ml_unmap = { .notify = Server::xdg_toplevel_unmap }; */ + /* client->ml_destroy = { .notify = Server::xdg_toplevel_destroy }; */ + /* // TODO: client->ml_set_title = { .notify = Server::... }; */ + /* // TODO: client->ml_fullscreen = { .notify = Server::... }; */ + /* client->ml_request_activate = { .notify = Server::xwayland_request_activate }; */ + /* client->ml_request_configure = { .notify = Server::xwayland_request_configure }; */ + /* client->ml_set_hints = { .notify = Server::xwayland_set_hints }; */ + /* // TODO: client->ml_new_xdg_popup = { .notify = Server::... }; */ + + /* wl_signal_add(&xwayland_surface->events.map, &client->ml_map); */ + /* wl_signal_add(&xwayland_surface->events.unmap, &client->ml_unmap); */ + /* wl_signal_add(&xwayland_surface->events.destroy, &client->ml_destroy); */ + /* wl_signal_add(&xwayland_surface->events.request_activate, &client->ml_request_activate); */ + /* wl_signal_add(&xwayland_surface->events.request_configure, &client->ml_request_configure); */ + /* wl_signal_add(&xwayland_surface->events.set_hints, &client->ml_set_hints); */ } void diff --git a/src/kranewl/trace.cc b/src/kranewl/trace.cc @@ -0,0 +1,41 @@ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <dlfcn.h> + +#include <cstdio> +#include <iomanip> + +namespace { + Dl_info get_dl_info(void*, void*) __attribute__((no_instrument_function)); + + Dl_info get_dl_info(void*func, void*) { + Dl_info info; + if(!dladdr(func, &info)){ + info.dli_fname = "?"; + info.dli_sname = "?"; + } + if(!info.dli_fname) { + info.dli_fname = "?"; + } + if(!info.dli_sname) { + info.dli_sname = "?"; + } + return info; + } +} + +extern "C" { + void __cyg_profile_func_enter(void*, void*) __attribute__((no_instrument_function)); + void __cyg_profile_func_exit(void*, void*) __attribute__((no_instrument_function)); + + void __cyg_profile_func_enter(void* func, void* caller) { + auto info = get_dl_info(func, caller); + std::printf("> %p [%s] %s\n", func, info.dli_fname, info.dli_sname); + } + + void __cyg_profile_func_exit (void* func, void* caller) { + auto info = get_dl_info(func, caller); + std::printf("< %p [%s] %s\n", func, info.dli_fname, info.dli_sname); + } +}; diff --git a/src/kranewl/tree/workspace.cc b/src/kranewl/tree/workspace.cc @@ -1,3 +0,0 @@ -#include <kranewl/tree/workspace.hh> - - diff --git a/src/kranewl/workspace.cc b/src/kranewl/workspace.cc @@ -0,0 +1,534 @@ +#include <kranewl/workspace.hh> + +#include <kranewl/context.hh> +#include <kranewl/cycle.t.hh> +#include <kranewl/tree/client.hh> +#include <kranewl/util.hh> + +#include <algorithm> +#include <optional> + +bool +Workspace::empty() const +{ + return m_clients.empty(); +} + +bool +Workspace::contains(Client_ptr client) const +{ + return m_clients.contains(client); +} + +bool +Workspace::focus_follows_mouse() const +{ + return m_focus_follows_mouse; +} + +void +Workspace::set_focus_follows_mouse(bool focus_follows_mouse) +{ + m_focus_follows_mouse = focus_follows_mouse; +} + +bool +Workspace::layout_is_free() const +{ + return m_layout_handler.layout_is_free(); +} + +bool +Workspace::layout_has_margin() const +{ + return m_layout_handler.layout_has_margin(); +} + +bool +Workspace::layout_has_gap() const +{ + return m_layout_handler.layout_has_gap(); +} + +bool +Workspace::layout_is_persistent() const +{ + return m_layout_handler.layout_is_persistent(); +} + +bool +Workspace::layout_is_single() const +{ + return m_layout_handler.layout_is_single(); +} + +bool +Workspace::layout_wraps() const +{ + return m_layout_handler.layout_wraps(); +} + +std::size_t +Workspace::size() const +{ + return m_clients.size(); +} + +std::size_t +Workspace::length() const +{ + return m_clients.length(); +} + +int +Workspace::main_count() const +{ + return m_layout_handler.main_count(); +} + +Context_ptr +Workspace::context() const +{ + return mp_context; +} + +Index +Workspace::index() const +{ + return m_index; +} + +std::string const& +Workspace::name() const +{ + return m_name; +} + +std::string +Workspace::identifier() const +{ + if (!m_name.empty()) + return mp_context->name() + + ":" + + std::to_string(m_index) + + ":" + + m_name; + + return mp_context->name() + + ":" + + std::to_string(m_index); +} + +Client_ptr +Workspace::active() const +{ + return mp_active; +} + + +Cycle<Client_ptr> const& +Workspace::clients() const +{ + return m_clients; +} + +std::vector<Client_ptr> +Workspace::stack_after_focus() const +{ + std::vector<Client_ptr> stack = m_clients.stack(); + + if (mp_active) { + Util::erase_remove(stack, mp_active); + stack.push_back(mp_active); + } + + return stack; +} + +Client_ptr +Workspace::next_client() const +{ + std::optional<Client_ptr> client + = m_clients.next_element(Direction::Forward); + + if (client != mp_active) + return *client; + + return nullptr; +} + +Client_ptr +Workspace::prev_client() const +{ + std::optional<Client_ptr> client + = m_clients.next_element(Direction::Backward); + + if (client != mp_active) + return *client; + + return nullptr; +} + +void +Workspace::cycle(Direction direction) +{ + switch (direction) { + case Direction::Forward: + { + if (!layout_wraps() && m_clients.active_index() == m_clients.last_index()) + return; + + break; + } + case Direction::Backward: + { + if (!layout_wraps() && m_clients.active_index() == 0) + return; + + break; + } + } + + m_clients.cycle_active(direction); + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::drag(Direction direction) +{ + switch (direction) { + case Direction::Forward: + { + if (!layout_wraps() && m_clients.active_index() == m_clients.last_index()) + return; + + break; + } + case Direction::Backward: + { + if (!layout_wraps() && m_clients.active_index() == 0) + return; + + break; + } + } + + m_clients.drag_active(direction); + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::reverse() +{ + m_clients.reverse(); + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::rotate(Direction direction) +{ + m_clients.rotate(direction); + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::shuffle_main(Direction direction) +{ + m_clients.rotate_range( + direction, + 0, + static_cast<Index>(m_layout_handler.main_count()) + ); + + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::shuffle_stack(Direction direction) +{ + m_clients.rotate_range( + direction, + static_cast<Index>(m_layout_handler.main_count()), + m_clients.size() + ); + + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::activate_client(Client_ptr client) +{ + if (m_clients.contains(client)) { + m_clients.activate_element(client); + mp_active = client; + } +} + +void +Workspace::add_client(Client_ptr client) +{ + if (m_clients.contains(client)) + return; + + m_clients.insert_at_back(client); + mp_active = client; +} + +void +Workspace::remove_client(Client_ptr client) +{ + m_clients.remove_element(client); + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::replace_client(Client_ptr client, Client_ptr replacement) +{ + bool was_active + = m_clients.active_element().value_or(nullptr) == client; + + m_clients.replace_element(client, replacement); + + if (was_active) { + m_clients.activate_element(replacement); + mp_active = replacement; + } +} + +void +Workspace::client_to_icon(Client_ptr client) +{ + if (m_clients.remove_element(client)) + m_icons.insert_at_back(client); + + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::icon_to_client(Client_ptr client) +{ + if (m_icons.remove_element(client)) + m_clients.insert_at_back(client); + + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::add_icon(Client_ptr client) +{ + if (m_icons.contains(client)) + return; + + m_icons.insert_at_back(client); +} + +void +Workspace::remove_icon(Client_ptr client) +{ + m_icons.remove_element(client); +} + +std::optional<Client_ptr> +Workspace::pop_icon() +{ + return m_icons.empty() + ? std::nullopt + : std::optional(m_icons[m_icons.size() - 1]); +} + +void +Workspace::client_to_disowned(Client_ptr client) +{ + if (m_clients.remove_element(client)) + m_disowned.insert_at_back(client); + + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::disowned_to_client(Client_ptr client) +{ + if (m_disowned.remove_element(client)) + m_clients.insert_at_back(client); + + mp_active = m_clients.active_element().value_or(nullptr); +} + +void +Workspace::add_disowned(Client_ptr client) +{ + if (m_disowned.contains(client)) + return; + + m_disowned.insert_at_back(client); +} + +void +Workspace::remove_disowned(Client_ptr client) +{ + m_disowned.remove_element(client); +} + +void +Workspace::save_layout(int number) const +{ + m_layout_handler.save_layout(number); +} + +void +Workspace::load_layout(int number) +{ + m_layout_handler.load_layout(number); +} + +void +Workspace::toggle_layout_data() +{ + m_layout_handler.set_prev_layout_data(); +} + +void +Workspace::cycle_layout_data(Direction direction) +{ + m_layout_handler.cycle_layout_data(direction); +} + +void +Workspace::copy_data_from_prev_layout() +{ + m_layout_handler.copy_data_from_prev_layout(); +} + + +void +Workspace::change_gap_size(Util::Change<int> change) +{ + m_layout_handler.change_gap_size(change); +} + +void +Workspace::change_main_count(Util::Change<int> change) +{ + m_layout_handler.change_main_count(change); +} + +void +Workspace::change_main_factor(Util::Change<float> change) +{ + m_layout_handler.change_main_factor(change); +} + +void +Workspace::change_margin(Util::Change<int> change) +{ + m_layout_handler.change_margin(change); +} + +void +Workspace::change_margin(Edge edge, Util::Change<int> change) +{ + m_layout_handler.change_margin(edge, change); +} + +void +Workspace::reset_gap_size() +{ + m_layout_handler.reset_gap_size(); +} + +void +Workspace::reset_margin() +{ + m_layout_handler.reset_margin(); +} + +void +Workspace::reset_layout_data() +{ + m_layout_handler.reset_layout_data(); +} + + +void +Workspace::toggle_layout() +{ + m_layout_handler.set_prev_kind(); +} + +void +Workspace::set_layout(LayoutHandler::LayoutKind layout) +{ + m_layout_handler.set_kind(layout); +} + +std::vector<Placement> +Workspace::arrange(Region region) const +{ + std::deque<Client_ptr> clients = m_clients.as_deque(); + std::vector<Placement> placements; + placements.reserve(clients.size()); + + auto fullscreen_iter = std::stable_partition( + clients.begin(), + clients.end(), + [](const Client_ptr client) -> bool { + return client->m_fullscreen && !client->m_contained; + } + ); + + auto free_iter = std::stable_partition( + fullscreen_iter, + clients.end(), + [=,this](const Client_ptr client) -> bool { + return !layout_is_free() && Client::is_free(client); + } + ); + + std::transform( + clients.begin(), + fullscreen_iter, + std::back_inserter(placements), + [region](const Client_ptr client) -> Placement { + return Placement { + Placement::PlacementMethod::Tile, + client, + NO_DECORATION, + region + }; + } + ); + + std::transform( + fullscreen_iter, + free_iter, + std::back_inserter(placements), + [](const Client_ptr client) -> Placement { + return Placement { + Placement::PlacementMethod::Free, + client, + FREE_DECORATION, + client->m_free_region + }; + } + ); + + m_layout_handler.arrange( + region, + placements, + free_iter, + clients.end() + ); + + if (layout_is_single()) { + std::for_each( + placements.begin(), + placements.end(), + [](Placement& placement) { + if (!placement.client->m_focused) + placement.region = std::nullopt; + } + ); + } + + return placements; +}