aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMathias Gumz <akira@fluxbox.org>2015-01-21 21:16:19 (GMT)
committerMathias Gumz <akira@fluxbox.org>2015-01-21 21:16:19 (GMT)
commite2dbdeeb2eb1dd1e2ff97499e894a86d47d9e3db (patch)
treeb8c195be09bb46413025ed2a8f0c3cc7eadc8482 /src
parent145cf94ea67a7d58ccd0a90dae8cba8c38a3275a (diff)
downloadfluxbox-e2dbdeeb2eb1dd1e2ff97499e894a86d47d9e3db.zip
fluxbox-e2dbdeeb2eb1dd1e2ff97499e894a86d47d9e3db.tar.bz2
Fix segfault on shutdown
There was a problem deep within how the menus were connected and when and what gets deleted. It was clearly related to a menu which was kind of global. In order to better understand the code flow I eliminated the ExtraMenu code: it was used only to get the Remember-Menu into the Window-Menu. Instead of having a singleton of the Remember-Menu and fight against the shaky interconnections we just create a new one on demand and delete when the menu gets deleted. Looks like this fixes the problem. The menu code needs more love anyway. Closes #1118
Diffstat (limited to 'src')
-rw-r--r--src/MenuCreator.cc20
-rw-r--r--src/Remember.cc10
-rw-r--r--src/Remember.hh3
-rw-r--r--src/Screen.cc52
-rw-r--r--src/Screen.hh5
5 files changed, 29 insertions, 61 deletions
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc
index a90e234..7f7445f 100644
--- a/src/MenuCreator.cc
+++ b/src/MenuCreator.cc
@@ -56,6 +56,10 @@
56#include <iostream> 56#include <iostream>
57#include <algorithm> 57#include <algorithm>
58 58
59#ifdef REMEMBER
60#include "Remember.hh"
61#endif // REMEMBER
62
59using std::cerr; 63using std::cerr;
60using std::endl; 64using std::endl;
61using std::string; 65using std::string;
@@ -88,6 +92,8 @@ enum {
88 92
89 L_ALPHA, 93 L_ALPHA,
90 94
95 L_REMEMBER,
96
91 L_MENU_EXIT, 97 L_MENU_EXIT,
92 L_MENU_ICONS, 98 L_MENU_ICONS,
93}; 99};
@@ -112,6 +118,8 @@ const FbTk::FbString& _l(const FbTk::FbString& label, size_t type) {
112 118
113 _FB_XTEXT(Configmenu, Transparency, "Transparency", "Menu containing various transparency options"), 119 _FB_XTEXT(Configmenu, Transparency, "Transparency", "Menu containing various transparency options"),
114 120
121 _FB_XTEXT(Remember, MenuItemName, "Remember...", "Remember item in menu"),
122
115 _FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), 123 _FB_XTEXT(Menu, Exit, "Exit", "Exit Command"),
116 _FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), 124 _FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"),
117 }; 125 };
@@ -602,14 +610,13 @@ bool MenuCreator::createWindowMenuItem(const string &type,
602 } 610 }
603#endif // HAVE_XRENDER 611#endif // HAVE_XRENDER
604 } else if (type == "extramenus") { 612 } else if (type == "extramenus") {
613#ifdef REMEMBER
605 BScreen* s = Fluxbox::instance()->findScreen(screen); 614 BScreen* s = Fluxbox::instance()->findScreen(screen);
606 BScreen::ExtraMenus::iterator it = s->extraWindowMenus().begin(); 615 if (s == 0) {
607 BScreen::ExtraMenus::iterator it_end = s->extraWindowMenus().end(); 616 return false;
608 for (; it != it_end; ++it) {
609 it->second->disableTitle();
610 menu.insertSubmenu(it->first, it->second);
611 } 617 }
612 618 menu.insertSubmenu(_l("", L_REMEMBER), Remember::createMenu(*s));
619#endif
613 } else if (type == "sendto") { 620 } else if (type == "sendto") {
614 menu.insertSubmenu(_l(label, L_SENDTO), 621 menu.insertSubmenu(_l(label, L_SENDTO),
615 new SendToMenu(*Fluxbox::instance()->findScreen(screen))); 622 new SendToMenu(*Fluxbox::instance()->findScreen(screen)));
@@ -634,4 +641,3 @@ bool MenuCreator::createWindowMenuItem(const string &type,
634 return true; 641 return true;
635} 642}
636 643
637
diff --git a/src/Remember.cc b/src/Remember.cc
index f946ad0..19ea5f0 100644
--- a/src/Remember.cc
+++ b/src/Remember.cc
@@ -1442,10 +1442,10 @@ void Remember::updateClientClose(WinClient &winclient) {
1442 1442
1443} 1443}
1444 1444
1445void Remember::initForScreen(BScreen &screen) { 1445void Remember::initForScreen(BScreen &screen) { }
1446 // All windows get the remember menu. 1446
1447 _FB_USES_NLS; 1447FbTk::Menu* Remember::createMenu(BScreen& screen) {
1448 screen.addExtraWindowMenu(_FB_XTEXT(Remember, MenuItemName, "Remember...", "Remember item in menu"),
1449 createRememberMenu(screen));
1450 1448
1449 return createRememberMenu(screen);
1451} 1450}
1451
diff --git a/src/Remember.hh b/src/Remember.hh
index a1abf5a..a6a980e 100644
--- a/src/Remember.hh
+++ b/src/Remember.hh
@@ -41,6 +41,7 @@ class Application;
41 41
42namespace FbTk { 42namespace FbTk {
43class AutoReloadHelper; 43class AutoReloadHelper;
44class Menu;
44} 45}
45 46
46/** 47/**
@@ -125,6 +126,8 @@ public:
125 126
126 void initForScreen(BScreen &screen); 127 void initForScreen(BScreen &screen);
127 128
129 static FbTk::Menu* createMenu(BScreen& screen);
130
128 // Functions we ignore (zero from AtomHandler) 131 // Functions we ignore (zero from AtomHandler)
129 // Leaving here in case they might be useful later 132 // Leaving here in case they might be useful later
130 133
diff --git a/src/Screen.cc b/src/Screen.cc
index 1d81191..2ae63a1 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -357,8 +357,8 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
357 357
358 m_configmenu.reset(MenuCreator::createMenu(_FB_XTEXT(Menu, Configuration, 358 m_configmenu.reset(MenuCreator::createMenu(_FB_XTEXT(Menu, Configuration,
359 "Configuration", "Title of configuration menu"), *this)); 359 "Configuration", "Title of configuration menu"), *this));
360 setupConfigmenu(*m_configmenu.get());
361 m_configmenu->setInternalMenu(); 360 m_configmenu->setInternalMenu();
361 setupConfigmenu(*m_configmenu.get());
362 362
363 // check which desktop we should start on 363 // check which desktop we should start on
364 int first_desktop = 0; 364 int first_desktop = 0;
@@ -388,9 +388,7 @@ BScreen::~BScreen() {
388 388
389 if (! managed) 389 if (! managed)
390 return; 390 return;
391 391
392 m_configmenu.reset(0);
393
394 m_toolbar.reset(0); 392 m_toolbar.reset(0);
395 393
396 FbTk::EventManager *evm = FbTk::EventManager::instance(); 394 FbTk::EventManager *evm = FbTk::EventManager::instance();
@@ -407,35 +405,6 @@ BScreen::~BScreen() {
407 // we need to destroy it before we destroy workspaces 405 // we need to destroy it before we destroy workspaces
408 m_workspacemenu.reset(0); 406 m_workspacemenu.reset(0);
409 407
410 if (m_extramenus.size()) {
411 // check whether extramenus are included in windowmenu
412 // if not, we clean them ourselves
413 bool extramenus_in_windowmenu = false;
414 for (size_t i = 0, n = m_windowmenu->numberOfItems(); i < n; i++)
415 if (m_windowmenu->find(i)->submenu() == m_extramenus.begin()->second) {
416 extramenus_in_windowmenu = true;
417 break;
418 }
419
420 ExtraMenus::iterator mit = m_extramenus.begin();
421 ExtraMenus::iterator mit_end = m_extramenus.end();
422 for (; mit != mit_end; ++mit) {
423 // we set them to NOT internal so that they will be deleted when the
424 // menu is cleaned up. We can't delete them here because they are
425 // still in the menu
426 // (They need to be internal for most of the time so that if we
427 // rebuild the menu, then they won't be removed.
428 if (! extramenus_in_windowmenu) {
429 // not attached to our windowmenu
430 // so we clean it up
431 delete mit->second;
432 } else {
433 // let the parent clean it up
434 mit->second->setInternalMenu(false);
435 }
436 }
437 }
438
439 removeWorkspaceNames(); 408 removeWorkspaceNames();
440 using namespace FbTk::STLUtil; 409 using namespace FbTk::STLUtil;
441 destroyAndClear(m_workspaces_list); 410 destroyAndClear(m_workspaces_list);
@@ -461,9 +430,10 @@ BScreen::~BScreen() {
461 // slit must be destroyed before headAreas (Struts) 430 // slit must be destroyed before headAreas (Struts)
462 m_slit.reset(0); 431 m_slit.reset(0);
463 432
464 delete m_rootmenu.release(); 433 m_windowmenu.reset(0);
465 delete m_workspacemenu.release(); 434 m_rootmenu.reset(0);
466 delete m_windowmenu.release(); 435 m_workspacemenu.reset(0);
436 m_configmenu.reset(0);
467 437
468 // TODO fluxgen: check if this is the right place 438 // TODO fluxgen: check if this is the right place
469 for (size_t i = 0; i < m_head_areas.size(); i++) 439 for (size_t i = 0; i < m_head_areas.size(); i++)
@@ -471,6 +441,7 @@ BScreen::~BScreen() {
471 441
472 delete m_focus_control; 442 delete m_focus_control;
473 delete m_placement_strategy; 443 delete m_placement_strategy;
444
474} 445}
475 446
476bool BScreen::isRestart() { 447bool BScreen::isRestart() {
@@ -736,13 +707,6 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) {
736 707
737} 708}
738 709
739void BScreen::addExtraWindowMenu(const FbTk::FbString &label, FbTk::Menu *menu) {
740 menu->setInternalMenu();
741 menu->disableTitle();
742 m_extramenus.push_back(make_pair(label, menu));
743 rereadWindowMenu();
744}
745
746void BScreen::reconfigure() { 710void BScreen::reconfigure() {
747 Fluxbox *fluxbox = Fluxbox::instance(); 711 Fluxbox *fluxbox = Fluxbox::instance();
748 712
@@ -754,7 +718,7 @@ void BScreen::reconfigure() {
754 718
755 m_menutheme->setDelay(*resource.menu_delay); 719 m_menutheme->setDelay(*resource.menu_delay);
756 720
757 // realize the number of workspaces from the init-file 721 // provide the number of workspaces from the init-file
758 const unsigned int nr_ws = *resource.workspaces; 722 const unsigned int nr_ws = *resource.workspaces;
759 if (nr_ws > m_workspaces_list.size()) { 723 if (nr_ws > m_workspaces_list.size()) {
760 while(nr_ws != m_workspaces_list.size()) { 724 while(nr_ws != m_workspaces_list.size()) {
diff --git a/src/Screen.hh b/src/Screen.hh
index 771899f..c9a6ede 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -82,7 +82,6 @@ public:
82 82
83 typedef std::vector<Workspace *> Workspaces; 83 typedef std::vector<Workspace *> Workspaces;
84 typedef std::vector<std::string> WorkspaceNames; 84 typedef std::vector<std::string> WorkspaceNames;
85 typedef std::list<std::pair<FbTk::FbString, FbTk::Menu *> > ExtraMenus;
86 85
87 BScreen(FbTk::ResourceManager &rm, 86 BScreen(FbTk::ResourceManager &rm,
88 const std::string &screenname, const std::string &altscreenname, 87 const std::string &screenname, const std::string &altscreenname,
@@ -113,8 +112,6 @@ public:
113 FbMenu &configMenu() { return *m_configmenu.get(); } 112 FbMenu &configMenu() { return *m_configmenu.get(); }
114 const FbMenu &windowMenu() const { return *m_windowmenu.get(); } 113 const FbMenu &windowMenu() const { return *m_windowmenu.get(); }
115 FbMenu &windowMenu() { return *m_windowmenu.get(); } 114 FbMenu &windowMenu() { return *m_windowmenu.get(); }
116 ExtraMenus &extraWindowMenus() { return m_extramenus; }
117 const ExtraMenus &extraWindowMenus() const { return m_extramenus; }
118 115
119 FbWinFrame::TabPlacement getTabPlacement() const { return *resource.tab_placement; } 116 FbWinFrame::TabPlacement getTabPlacement() const { return *resource.tab_placement; }
120 117
@@ -480,8 +477,6 @@ private:
480 std::auto_ptr<FbTk::ImageControl> m_image_control; 477 std::auto_ptr<FbTk::ImageControl> m_image_control;
481 std::auto_ptr<FbMenu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu; 478 std::auto_ptr<FbMenu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu;
482 479
483 ExtraMenus m_extramenus;
484
485 Icons m_icon_list; 480 Icons m_icon_list;
486 481
487 std::auto_ptr<Slit> m_slit; 482 std::auto_ptr<Slit> m_slit;