Skip to content

Commit 078320c

Browse files
committed
panel: menu launchers double fork to not remain child of panel
1 parent 3252352 commit 078320c

1 file changed

Lines changed: 51 additions & 4 deletions

File tree

src/panel/widgets/menu.cpp

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <glibmm/spawn.h>
77
#include <iostream>
88
#include <gtk4-layer-shell.h>
9+
#include <sys/wait.h>
910

1011
#include "menu.hpp"
1112
#include "gtk-utils.hpp"
@@ -189,6 +190,45 @@ void WfMenuCategoryButton::on_click()
189190
menu->set_category(category);
190191
}
191192

193+
/* Double forks to launch the grandchild as a child of PID 1. */
194+
void double_fork(const std::function<void()>& action)
195+
{
196+
pid_t pid = fork();
197+
if (pid < 0)
198+
{
199+
return; /* Failed */
200+
}
201+
202+
if (pid > 0)
203+
{
204+
/* Main process. Wait briefly for the intermediate child to clean up and exit */
205+
waitpid(pid, nullptr, 0);
206+
return;
207+
}
208+
209+
/*Intermediate child process. Disavow parent */
210+
setsid();
211+
212+
pid_t grandchild_pid = fork();
213+
if (grandchild_pid < 0)
214+
{
215+
_exit(EXIT_FAILURE); /* Failed */
216+
}
217+
218+
if (grandchild_pid > 0)
219+
{
220+
_exit(EXIT_SUCCESS); /* Intermediate child ends, disavowing parent and child */
221+
}
222+
223+
/* End child process, perform action */
224+
try {
225+
action();
226+
} catch (...)
227+
{}
228+
229+
_exit(EXIT_SUCCESS);
230+
}
231+
192232
WfMenuItem::WfMenuItem(WayfireMenu *_menu, Glib::RefPtr<Gio::DesktopAppInfo> app) :
193233
Gtk::FlowBoxChild(), menu(_menu), app_info(app)
194234
{
@@ -304,8 +344,11 @@ WfMenuItem::WfMenuItem(WayfireMenu *_menu, Glib::RefPtr<Gio::DesktopAppInfo> app
304344
signals.push_back(action_obj->signal_activate().connect(
305345
[this, action] (Glib::VariantBase vb)
306346
{
307-
auto ctx = Gdk::Display::get_default()->get_app_launch_context();
308-
app_info->launch_action(action, ctx);
347+
double_fork([this, action] ()
348+
{
349+
auto context = Gio::AppLaunchContext::create();
350+
app_info->launch_action(action, context);
351+
});
309352
menu->hide_menu();
310353
}));
311354
m_menu->append_item(menu_item);
@@ -337,8 +380,12 @@ WfMenuItem::~WfMenuItem()
337380

338381
void WfMenuItem::on_click()
339382
{
340-
auto ctx = Gdk::Display::get_default()->get_app_launch_context();
341-
app_info->launch(std::vector<Glib::RefPtr<Gio::File>>(), ctx);
383+
double_fork([this] ()
384+
{
385+
auto context = Gio::AppLaunchContext::create();
386+
std::vector<Glib::RefPtr<Gio::File>> no_files;
387+
app_info->launch(no_files, context);
388+
});
342389
menu->hide_menu();
343390
}
344391

0 commit comments

Comments
 (0)