@@ -30,7 +30,8 @@ namespace IconProvider
3030
3131class WayfireToplevel ::impl
3232{
33- zwlr_foreign_toplevel_handle_v1 *handle;
33+ zwlr_foreign_toplevel_handle_v1 *handle, *parent;
34+ std::vector<zwlr_foreign_toplevel_handle_v1 *> children;
3435 uint32_t state;
3536
3637 Gtk::Button button;
@@ -48,6 +49,7 @@ class WayfireToplevel::impl
4849 impl (WayfireWindowList *window_list, zwlr_foreign_toplevel_handle_v1 *handle)
4950 {
5051 this ->handle = handle;
52+ this ->parent = nullptr ;
5153 zwlr_foreign_toplevel_handle_v1_add_listener (handle,
5254 &toplevel_handle_v1_impl, this );
5355
@@ -235,7 +237,17 @@ class WayfireToplevel::impl
235237 return ;
236238 }
237239
238- if (!(state & WF_TOPLEVEL_STATE_ACTIVATED ))
240+ bool child_activated = false ;
241+ for (auto c : get_children ())
242+ {
243+ if (window_list->toplevels [c]->get_state () & WF_TOPLEVEL_STATE_ACTIVATED )
244+ {
245+ child_activated = true ;
246+ break ;
247+ }
248+ }
249+
250+ if (!(state & WF_TOPLEVEL_STATE_ACTIVATED ) && !child_activated)
239251 {
240252 auto gseat = Gdk::Display::get_default ()->get_default_seat ();
241253 auto seat = gdk_wayland_seat_get_wl_seat (gseat->gobj ());
@@ -285,7 +297,7 @@ class WayfireToplevel::impl
285297 }
286298
287299 auto panel =
288- WayfirePanelApp::get ().panel_for_wl_output ( window_list->output ->wo );
300+ WayfirePanelApp::get ().panel_for_wl_output (window_list->output ->wo );
289301 if (!panel)
290302 return ;
291303
@@ -349,6 +361,32 @@ class WayfireToplevel::impl
349361 label.set_text (shorten_title (show_chars));
350362 }
351363
364+ uint32_t get_state ()
365+ {
366+ return this ->state ;
367+ }
368+
369+ zwlr_foreign_toplevel_handle_v1 * get_parent ()
370+ {
371+ return this ->parent ;
372+ }
373+
374+ void set_parent (zwlr_foreign_toplevel_handle_v1 *parent)
375+ {
376+ this ->parent = parent;
377+ }
378+
379+ std::vector<zwlr_foreign_toplevel_handle_v1 *>& get_children ()
380+ {
381+ return this ->children ;
382+ }
383+
384+ void remove_button ()
385+ {
386+ auto & container = window_list->box ;
387+ container.remove (button);
388+ }
389+
352390 void update_menu_item_text ()
353391 {
354392 if (state & WF_TOPLEVEL_STATE_MINIMIZED )
@@ -386,6 +424,10 @@ class WayfireToplevel::impl
386424
387425 void handle_output_enter (wl_output *output)
388426 {
427+ if (this ->parent )
428+ {
429+ return ;
430+ }
389431 auto & container = window_list->box ;
390432 if (window_list->output ->wo == output)
391433 {
@@ -410,6 +452,10 @@ WayfireToplevel::WayfireToplevel(WayfireWindowList *window_list,
410452 :pimpl(new WayfireToplevel::impl(window_list, handle)) { }
411453
412454void WayfireToplevel::set_width (int pixels) { return pimpl->set_max_width (pixels); }
455+ std::vector<zwlr_foreign_toplevel_handle_v1 *>& WayfireToplevel::get_children () { return pimpl->get_children (); }
456+ zwlr_foreign_toplevel_handle_v1 * WayfireToplevel::get_parent () { return pimpl->get_parent (); }
457+ void WayfireToplevel::set_parent (zwlr_foreign_toplevel_handle_v1 *parent) { return pimpl->set_parent (parent); }
458+ uint32_t WayfireToplevel::get_state () { return pimpl->get_state (); }
413459WayfireToplevel::~WayfireToplevel () = default ;
414460
415461using toplevel_t = zwlr_foreign_toplevel_handle_v1*;
@@ -473,13 +519,47 @@ static void handle_toplevel_done(void *data, toplevel_t)
473519// auto impl = static_cast<WayfireToplevel::impl*> (data);
474520}
475521
522+ static void remove_child_from_parent (WayfireToplevel::impl *impl, toplevel_t child)
523+ {
524+ auto parent = impl->get_parent ();
525+ auto & parent_toplevel = impl->window_list ->toplevels [parent];
526+ if (child && parent && parent_toplevel)
527+ {
528+ auto & children = parent_toplevel->get_children ();
529+ children.erase (std::find (children.begin (), children.end (), child));
530+ }
531+ }
532+
476533static void handle_toplevel_closed (void *data, toplevel_t handle)
477534{
478535 // WayfirePanelApp::get().handle_toplevel_closed(handle);
479536 auto impl = static_cast <WayfireToplevel::impl*> (data);
537+ remove_child_from_parent (impl, handle);
480538 impl->window_list ->handle_toplevel_closed (handle);
481539}
482540
541+ static void handle_toplevel_parent (void *data, toplevel_t handle, toplevel_t parent)
542+ {
543+ auto impl = static_cast <WayfireToplevel::impl*> (data);
544+ if (!parent)
545+ {
546+ if (impl->get_parent ())
547+ {
548+ impl->handle_output_enter (impl->window_list ->output ->wo );
549+ }
550+ remove_child_from_parent (impl, handle);
551+ impl->set_parent (parent);
552+ return ;
553+ }
554+ if (impl->window_list ->toplevels [parent])
555+ {
556+ auto & children = impl->window_list ->toplevels [parent]->get_children ();
557+ children.push_back (handle);
558+ }
559+ impl->set_parent (parent);
560+ impl->remove_button ();
561+ }
562+
483563namespace
484564{
485565struct zwlr_foreign_toplevel_handle_v1_listener toplevel_handle_v1_impl = {
@@ -489,7 +569,8 @@ struct zwlr_foreign_toplevel_handle_v1_listener toplevel_handle_v1_impl = {
489569 .output_leave = handle_toplevel_output_leave,
490570 .state = handle_toplevel_state,
491571 .done = handle_toplevel_done,
492- .closed = handle_toplevel_closed
572+ .closed = handle_toplevel_closed,
573+ .parent = handle_toplevel_parent
493574};
494575}
495576
0 commit comments