diff --git a/src/main.cpp b/src/main.cpp index 8c1cd9d..c62a1b7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,7 +16,7 @@ namespace wf { namespace osk { - int spacing = 8; + int spacing = OSK_SPACING; int default_width = 800; int default_height = 400; std::string anchor; @@ -112,12 +112,8 @@ namespace wf void Keyboard::set_layout(KeyboardLayout *new_layout) { - if (this->current_layout) - this->window->remove(); - this->current_layout = new_layout; - this->window->add(new_layout->box); - this->window->show_all(); + window->set_widget(new_layout->box); } Keyboard::Keyboard() diff --git a/src/wayland-window.cpp b/src/wayland-window.cpp index 9a4f8aa..a6e04d1 100644 --- a/src/wayland-window.cpp +++ b/src/wayland-window.cpp @@ -1,9 +1,17 @@ #include "wayland-window.hpp" #include #include +#include +#include #include #include #include +#include + +#include +#include + +static constexpr int HEADERBAR_SIZE = 60; namespace wf { @@ -95,7 +103,8 @@ namespace wf void WaylandWindow::init(int width, int height, std::string anchor) { gtk_layer_init_for_window(this->gobj()); - gtk_layer_set_layer(this->gobj(), GTK_LAYER_SHELL_LAYER_TOP); + gtk_layer_set_layer(this->gobj(), GTK_LAYER_SHELL_LAYER_OVERLAY); + gtk_layer_set_namespace(this->gobj(), "keyboard"); auto layer_anchor = check_anchor(anchor); if (layer_anchor > -1) { @@ -118,8 +127,59 @@ namespace wf WaylandWindow::WaylandWindow(int width, int height, std::string anchor) : Gtk::Window() { - /* Trick: first show the window, get frame size, then subtract it again */ - this->set_type_hint(Gdk::WINDOW_TYPE_HINT_DOCK); + // setup close button + close_button.get_style_context()->add_class("image-button"); + close_button.set_image_from_icon_name("window-close-symbolic", + Gtk::ICON_SIZE_LARGE_TOOLBAR); + close_button.signal_clicked().connect_notify([=] () { + this->get_application()->quit(); + }); + + // setup move gesture + headerbar_drag = Gtk::GestureDrag::create(drag_box); + headerbar_drag->signal_drag_begin().connect_notify([=] (double, double) { + if (this->wf_surface) + { + zwf_surface_v2_interactive_move(this->wf_surface); + /* Taken from GDK's Wayland impl of begin_move_drag() */ + Gdk::Display::get_default()->get_default_seat()->ungrab(); + headerbar_drag->reset(); + } + }); + Gtk::HeaderBar bar; + headerbar_box.override_background_color(bar.get_style_context()->get_background_color()); + + + // setup headerbar layout + headerbar_box.set_size_request(-1, HEADERBAR_SIZE); + + close_button.set_size_request(HEADERBAR_SIZE * 0.8, HEADERBAR_SIZE * 0.8); + close_button.set_margin_bottom(OSK_SPACING); + close_button.set_margin_top(OSK_SPACING); + close_button.set_margin_left(OSK_SPACING); + close_button.set_margin_right(OSK_SPACING); + + headerbar_box.pack_end(close_button, false, false); + headerbar_box.pack_start(drag_box, true, true); + layout_box.pack_start(headerbar_box); + layout_box.set_spacing(OSK_SPACING); + this->add(layout_box); + + // setup gtk layer shell init(width, height, anchor); } + + void WaylandWindow::set_widget(Gtk::Widget& w) + { + if (current_widget) + this->layout_box.remove(*current_widget); + + this->layout_box.pack_end(w); + current_widget = &w; + + w.set_margin_bottom(OSK_SPACING); + w.set_margin_left(OSK_SPACING); + w.set_margin_right(OSK_SPACING); + this->show_all(); + } } diff --git a/src/wayland-window.hpp b/src/wayland-window.hpp index 6720dcb..fa64509 100644 --- a/src/wayland-window.hpp +++ b/src/wayland-window.hpp @@ -1,9 +1,16 @@ #pragma once +#include +#include #include +#include +#include +#include #include #include +#define OSK_SPACING 8 + namespace wf { class WaylandDisplay @@ -19,12 +26,20 @@ namespace wf class WaylandWindow : public Gtk::Window { - zwf_surface_v2 *wf_surface; + zwf_surface_v2 *wf_surface = nullptr; + + Gtk::Widget* current_widget = nullptr; + Glib::RefPtr headerbar_drag; + Gtk::EventBox drag_box; + Gtk::Button close_button; + Gtk::HBox headerbar_box; + Gtk::VBox layout_box; int32_t check_anchor(std::string anchor); void init(int width, int height, std::string anchor); - public: + public: WaylandWindow(int width, int height, std::string anchor); + void set_widget(Gtk::Widget& w); }; }