From f8dea9b12368d185340631877c462ce16763ec74 Mon Sep 17 00:00:00 2001 From: arcplayz Date: Mon, 24 Nov 2025 21:09:54 +0100 Subject: [PATCH] wlr/taskbar: activate window on drag & drop --- include/modules/wlr/taskbar.hpp | 6 +++++ src/modules/wlr/taskbar.cpp | 40 ++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/modules/wlr/taskbar.hpp b/include/modules/wlr/taskbar.hpp index 8dc4dadd38..cf473bc814 100644 --- a/include/modules/wlr/taskbar.hpp +++ b/include/modules/wlr/taskbar.hpp @@ -122,6 +122,12 @@ class Task { void handle_drag_data_received(const Glib::RefPtr &context, int x, int y, Gtk::SelectionData selection_data, guint info, guint time); + sigc::connection activate_timer; + bool handle_activate_timer(); + + bool handle_drag_motion(const Glib::RefPtr& context, int x, int y, guint time); + void handle_drag_leave(const Glib::RefPtr& context, guint time); + public: bool operator==(const Task &) const; bool operator!=(const Task &) const; diff --git a/src/modules/wlr/taskbar.cpp b/src/modules/wlr/taskbar.cpp index c5c522d85e..4b429f60f3 100644 --- a/src/modules/wlr/taskbar.cpp +++ b/src/modules/wlr/taskbar.cpp @@ -78,8 +78,9 @@ static const struct zwlr_foreign_toplevel_handle_v1_listener toplevel_handle_imp .parent = tl_handle_parent, }; -static const std::vector target_entries = { - Gtk::TargetEntry("WAYBAR_TOPLEVEL", Gtk::TARGET_SAME_APP, 0)}; +static const std::vector source_entries = { + Gtk::TargetEntry("WAYBAR_TOPLEVEL", Gtk::TARGET_SAME_APP, 0) +}; Task::Task(const waybar::Bar &bar, const Json::Value &config, Taskbar *tbar, struct zwlr_foreign_toplevel_handle_v1 *tl_handle, struct wl_seat *seat) @@ -146,12 +147,39 @@ Task::Task(const waybar::Bar &bar, const Json::Value &config, Taskbar *tbar, button.signal_motion_notify_event().connect(sigc::mem_fun(*this, &Task::handle_motion_notify), false); - button.drag_source_set(target_entries, Gdk::BUTTON1_MASK, Gdk::ACTION_MOVE); - button.drag_dest_set(target_entries, Gtk::DEST_DEFAULT_ALL, Gdk::ACTION_MOVE); + button.drag_source_set(source_entries, Gdk::BUTTON1_MASK, Gdk::ACTION_MOVE); + button.drag_dest_set(source_entries, Gtk::DEST_DEFAULT_ALL, Gdk::ACTION_MOVE); + gtk_drag_dest_set_track_motion(GTK_WIDGET(button.gobj()), TRUE); button.signal_drag_data_get().connect(sigc::mem_fun(*this, &Task::handle_drag_data_get), false); button.signal_drag_data_received().connect(sigc::mem_fun(*this, &Task::handle_drag_data_received), false); + + button.signal_drag_motion().connect(sigc::mem_fun(*this, &Task::handle_drag_motion)); + button.signal_drag_leave().connect(sigc::mem_fun(*this, &Task::handle_drag_leave)); +} + +bool Task::handle_drag_motion(const Glib::RefPtr& context, int x, int y, guint time) { + auto targets = context->list_targets(); + for (const auto& target : targets) { + if (target == "WAYBAR_TOPLEVEL") return true; + } + if (!activate_timer.connected()) { + activate_timer = Glib::signal_timeout().connect( + sigc::mem_fun(*this, &Task::handle_activate_timer), + 500 + ); + } + return true; +} + +bool Task::handle_activate_timer() { + activate(); + return true; +} + +void Task::handle_drag_leave(const Glib::RefPtr& context, guint time) { + activate_timer.disconnect(); } Task::~Task() { @@ -417,7 +445,7 @@ bool Task::handle_motion_notify(GdkEventMotion *mn) { if (button.drag_check_threshold(drag_start_x, drag_start_y, mn->x, mn->y)) { /* start drag in addition to other assigned action */ - auto target_list = Gtk::TargetList::create(target_entries); + auto target_list = Gtk::TargetList::create(source_entries); auto refptr = Glib::RefPtr(target_list); auto drag_context = button.drag_begin(refptr, Gdk::DragAction::ACTION_MOVE, drag_start_button, (GdkEvent *)mn); @@ -437,6 +465,8 @@ void Task::handle_drag_data_get(const Glib::RefPtr &context, void Task::handle_drag_data_received(const Glib::RefPtr &context, int x, int y, Gtk::SelectionData selection_data, guint info, guint time) { spdlog::debug("drag_data_received"); + auto type = selection_data.get_data_type(); + if (type != "WAYBAR_TOPLEVEL") return; gpointer handle = *(gpointer *)selection_data.get_data(); auto dragged_button = (Gtk::Button *)handle;