aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Labath <pavelo@centrum.sk>2011-07-02 15:21:24 (GMT)
committerPavel Labath <pavelo@centrum.sk>2013-02-17 00:09:35 (GMT)
commitb9de0c5be3022db926e167fbe765dc222c1db828 (patch)
tree3af2cb3b644e2986d904f486fe73a5e158757009
parentdb435c66cce9644abf5599f62229426b1f09a9e3 (diff)
downloadfluxbox_pavel-b9de0c5be3022db926e167fbe765dc222c1db828.zip
fluxbox_pavel-b9de0c5be3022db926e167fbe765dc222c1db828.tar.bz2
Store menus if smart pointers (RefCount)
This was originally intended to be a bugfix for an memory error reported by valgrind (accessing freed memory). While debugging it, I found the menu ownership semantics confusing (setInternalMenu() et al.), so I decided to get rid of it and store it in smart pointers everywhere. Looking back, I'm not sure if this was worth all the trouble, but the good news is that the valgrind error disappeared. :)
-rw-r--r--src/FbCommands.cc2
-rw-r--r--src/FbTk/Menu.cc24
-rw-r--r--src/FbTk/Menu.hh4
-rw-r--r--src/FbTk/MenuItem.cc1
-rw-r--r--src/FbTk/MenuItem.hh10
-rw-r--r--src/FbTk/MultiButtonMenuItem.cc3
-rw-r--r--src/FbTk/MultiButtonMenuItem.hh2
-rw-r--r--src/FbTk/RadioMenuItem.hh2
-rw-r--r--src/IconbarTool.cc18
-rw-r--r--src/IconbarTool.hh2
-rw-r--r--src/MenuCreator.cc50
-rw-r--r--src/MenuCreator.hh3
-rw-r--r--src/Remember.cc4
-rw-r--r--src/Screen.cc63
-rw-r--r--src/Screen.hh24
-rw-r--r--src/Slit.cc78
-rw-r--r--src/Slit.hh8
-rw-r--r--src/ToolFactory.cc6
-rw-r--r--src/Toolbar.cc79
-rw-r--r--src/Toolbar.hh18
-rw-r--r--src/Workspace.cc12
-rw-r--r--src/Workspace.hh6
-rw-r--r--src/WorkspaceMenu.cc5
23 files changed, 179 insertions, 245 deletions
diff --git a/src/FbCommands.cc b/src/FbCommands.cc
index 52526e1..a3a0c27 100644
--- a/src/FbCommands.cc
+++ b/src/FbCommands.cc
@@ -372,7 +372,7 @@ void ShowWorkspaceMenuCmd::execute() {
372 if (screen == 0) 372 if (screen == 0)
373 return; 373 return;
374 374
375 ::showMenu(*screen, screen->workspaceMenu()); 375 ::showMenu(*screen, *screen->workspaceMenu());
376} 376}
377 377
378REGISTER_COMMAND_WITH_ARGS(setworkspacename, FbCommands::SetWorkspaceNameCmd, void); 378REGISTER_COMMAND_WITH_ARGS(setworkspacename, FbCommands::SetWorkspaceNameCmd, void);
diff --git a/src/FbTk/Menu.cc b/src/FbTk/Menu.cc
index dfba1d0..645a712 100644
--- a/src/FbTk/Menu.cc
+++ b/src/FbTk/Menu.cc
@@ -126,8 +126,7 @@ Menu::Menu(FbTk::ThemeProxy<MenuTheme> &tm, ImageControl &imgctrl):
126 126
127 m_title_vis = true; 127 m_title_vis = true;
128 128
129 m_internal_menu = 129 m_moving =
130 m_moving =
131 m_closing = 130 m_closing =
132 m_torn = 131 m_torn =
133 m_visible = false; 132 m_visible = false;
@@ -227,7 +226,7 @@ int Menu::insert(const FbString &label, int pos) {
227 return insert(new MenuItem(label, *this), pos); 226 return insert(new MenuItem(label, *this), pos);
228} 227}
229 228
230int Menu::insert(const FbString &label, Menu *submenu, int pos) { 229int Menu::insert(const FbString &label, const RefCount<Menu> &submenu, int pos) {
231 return insert(new MenuItem(label, submenu, this), pos); 230 return insert(new MenuItem(label, submenu, this), pos);
232} 231}
233 232
@@ -274,19 +273,6 @@ int Menu::remove(unsigned int index) {
274 if (index != menuitems.size()) 273 if (index != menuitems.size())
275 fixMenuItemIndices(); 274 fixMenuItemIndices();
276 275
277 if (item->submenu() != 0) {
278 Menu *tmp = item->submenu();
279 // if menu is internal we should just hide it instead
280 // if destroying it
281 if (! tmp->m_internal_menu) {
282 delete tmp;
283 }
284 // We can't internal_hide here, as the child may be deleted!
285// } else
286// tmp->internal_hide();
287 }
288
289
290 delete item; 276 delete item;
291 } 277 }
292 278
@@ -374,8 +360,8 @@ void Menu::enterSubmenu() {
374 if (!validIndex(m_active_index)) 360 if (!validIndex(m_active_index))
375 return; 361 return;
376 362
377 Menu *submenu = menuitems[m_active_index]->submenu(); 363 RefCount<Menu> submenu = menuitems[m_active_index]->submenu();
378 if (submenu == 0) 364 if (! submenu)
379 return; 365 return;
380 366
381 if (submenu->menuitems.empty()) 367 if (submenu->menuitems.empty())
@@ -759,7 +745,7 @@ void Menu::drawSubmenu(unsigned int index) {
759 clearItem(index); 745 clearItem(index);
760 746
761 if (! item->submenu()->isVisible() && item->submenu()->numberOfItems() > 0) { 747 if (! item->submenu()->isVisible() && item->submenu()->numberOfItems() > 0) {
762 shown = item->submenu(); 748 shown = item->submenu().get();
763 item->showSubmenu(); 749 item->showSubmenu();
764 item->submenu()->raise(); 750 item->submenu()->raise();
765 } 751 }
diff --git a/src/FbTk/Menu.hh b/src/FbTk/Menu.hh
index 4096295..5807592 100644
--- a/src/FbTk/Menu.hh
+++ b/src/FbTk/Menu.hh
@@ -65,14 +65,13 @@ public:
65 /// add empty menu item 65 /// add empty menu item
66 int insert(const FbString &label, int pos=-1); 66 int insert(const FbString &label, int pos=-1);
67 /// add submenu 67 /// add submenu
68 int insert(const FbString &label, Menu *submenu, int pos= -1); 68 int insert(const FbString &label, const RefCount<Menu> &submenu, int pos= -1);
69 /// add menu item 69 /// add menu item
70 int insert(MenuItem *item, int pos=-1); 70 int insert(MenuItem *item, int pos=-1);
71 /// remove an item 71 /// remove an item
72 int remove(unsigned int item); 72 int remove(unsigned int item);
73 /// remove all items 73 /// remove all items
74 void removeAll(); 74 void removeAll();
75 void setInternalMenu(bool val = true) { m_internal_menu = val; }
76 void setAlignment(Alignment a) { m_alignment = a; } 75 void setAlignment(Alignment a) { m_alignment = a; }
77 76
78 /// raise this window 77 /// raise this window
@@ -213,7 +212,6 @@ private:
213 bool m_closing; ///< if we're right clicking on the menu title 212 bool m_closing; ///< if we're right clicking on the menu title
214 bool m_visible; ///< menu visibility 213 bool m_visible; ///< menu visibility
215 bool m_torn; ///< torn from parent 214 bool m_torn; ///< torn from parent
216 bool m_internal_menu; ///< whether we should destroy this menu or if it's managed somewhere else
217 bool m_title_vis; ///< title visibility 215 bool m_title_vis; ///< title visibility
218 216
219 int m_which_sub; 217 int m_which_sub;
diff --git a/src/FbTk/MenuItem.cc b/src/FbTk/MenuItem.cc
index c128c57..0715ecc 100644
--- a/src/FbTk/MenuItem.cc
+++ b/src/FbTk/MenuItem.cc
@@ -27,7 +27,6 @@
27#include "Image.hh" 27#include "Image.hh"
28#include "App.hh" 28#include "App.hh"
29#include "StringUtil.hh" 29#include "StringUtil.hh"
30#include "Menu.hh"
31#include <X11/keysym.h> 30#include <X11/keysym.h>
32 31
33namespace FbTk { 32namespace FbTk {
diff --git a/src/FbTk/MenuItem.hh b/src/FbTk/MenuItem.hh
index cc24228..227488f 100644
--- a/src/FbTk/MenuItem.hh
+++ b/src/FbTk/MenuItem.hh
@@ -22,6 +22,7 @@
22#ifndef FBTK_MENUITEM_HH 22#ifndef FBTK_MENUITEM_HH
23#define FBTK_MENUITEM_HH 23#define FBTK_MENUITEM_HH
24 24
25#include "Menu.hh"
25#include "RefCount.hh" 26#include "RefCount.hh"
26#include "Command.hh" 27#include "Command.hh"
27#include "PixmapWithMask.hh" 28#include "PixmapWithMask.hh"
@@ -32,7 +33,6 @@
32 33
33namespace FbTk { 34namespace FbTk {
34 35
35class Menu;
36class MenuTheme; 36class MenuTheme;
37class FbDrawable; 37class FbDrawable;
38template <class T> class ThemeProxy; 38template <class T> class ThemeProxy;
@@ -80,7 +80,7 @@ public:
80 m_toggle_item(false) 80 m_toggle_item(false)
81 { } 81 { }
82 82
83 MenuItem(const BiDiString &label, Menu *submenu, Menu *host_menu = 0) 83 MenuItem(const BiDiString &label, const RefCount<Menu> &submenu, Menu *host_menu = 0)
84 : m_label(label), 84 : m_label(label),
85 m_menu(host_menu), 85 m_menu(host_menu),
86 m_submenu(submenu), 86 m_submenu(submenu),
@@ -98,7 +98,7 @@ public:
98 virtual void setToggleItem(bool val) { m_toggle_item = val; } 98 virtual void setToggleItem(bool val) { m_toggle_item = val; }
99 void setCloseOnClick(bool val) { m_close_on_click = val; } 99 void setCloseOnClick(bool val) { m_close_on_click = val; }
100 void setIcon(const std::string &filename, int screen_num); 100 void setIcon(const std::string &filename, int screen_num);
101 virtual Menu *submenu() { return m_submenu; } 101 virtual const RefCount<Menu>& submenu() { return m_submenu; }
102 /** 102 /**
103 @name accessors 103 @name accessors
104 */ 104 */
@@ -107,7 +107,7 @@ public:
107 virtual const PixmapWithMask *icon() const { 107 virtual const PixmapWithMask *icon() const {
108 return m_icon.get() ? m_icon->pixmap.get() : 0; 108 return m_icon.get() ? m_icon->pixmap.get() : 0;
109 } 109 }
110 virtual const Menu *submenu() const { return m_submenu; } 110 virtual RefCount<const Menu> submenu() const { return m_submenu; }
111 virtual bool isEnabled() const { return m_enabled; } 111 virtual bool isEnabled() const { return m_enabled; }
112 virtual bool isSelected() const { return m_selected; } 112 virtual bool isSelected() const { return m_selected; }
113 virtual bool isToggleItem() const { return m_toggle_item; } 113 virtual bool isToggleItem() const { return m_toggle_item; }
@@ -150,7 +150,7 @@ public:
150private: 150private:
151 BiDiString m_label; ///< label of this item 151 BiDiString m_label; ///< label of this item
152 Menu *m_menu; ///< the menu we live in 152 Menu *m_menu; ///< the menu we live in
153 Menu *m_submenu; ///< a submenu, 0 if we don't have one 153 RefCount<Menu> m_submenu; ///< a submenu, 0 if we don't have one
154 RefCount<Command<void> > m_command; ///< command to be executed 154 RefCount<Command<void> > m_command; ///< command to be executed
155 bool m_enabled, m_selected; 155 bool m_enabled, m_selected;
156 bool m_close_on_click, m_toggle_item; 156 bool m_close_on_click, m_toggle_item;
diff --git a/src/FbTk/MultiButtonMenuItem.cc b/src/FbTk/MultiButtonMenuItem.cc
index f5b9990..359e96c 100644
--- a/src/FbTk/MultiButtonMenuItem.cc
+++ b/src/FbTk/MultiButtonMenuItem.cc
@@ -33,7 +33,8 @@ MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbTk::BiDiString &la
33 init(buttons); 33 init(buttons);
34} 34}
35 35
36MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbTk::BiDiString &label, Menu *submenu): 36MultiButtonMenuItem::MultiButtonMenuItem(int buttons, const FbTk::BiDiString &label,
37 const RefCount<Menu> &submenu):
37 MenuItem(label, submenu), 38 MenuItem(label, submenu),
38 m_button_exe(0), 39 m_button_exe(0),
39 m_buttons(buttons) { 40 m_buttons(buttons) {
diff --git a/src/FbTk/MultiButtonMenuItem.hh b/src/FbTk/MultiButtonMenuItem.hh
index 0a9c5e6..427302c 100644
--- a/src/FbTk/MultiButtonMenuItem.hh
+++ b/src/FbTk/MultiButtonMenuItem.hh
@@ -31,7 +31,7 @@ namespace FbTk {
31class MultiButtonMenuItem: public FbTk::MenuItem { 31class MultiButtonMenuItem: public FbTk::MenuItem {
32public: 32public:
33 MultiButtonMenuItem(int buttons, const FbTk::BiDiString& label); 33 MultiButtonMenuItem(int buttons, const FbTk::BiDiString& label);
34 MultiButtonMenuItem(int buttons, const FbTk::BiDiString& label, Menu *submenu); 34 MultiButtonMenuItem(int buttons, const FbTk::BiDiString& label, const RefCount<Menu> &submenu);
35 virtual ~MultiButtonMenuItem(); 35 virtual ~MultiButtonMenuItem();
36 /// sets command to specified button 36 /// sets command to specified button
37 void setCommand(int button, FbTk::RefCount<FbTk::Command<void> > &cmd); 37 void setCommand(int button, FbTk::RefCount<FbTk::Command<void> > &cmd);
diff --git a/src/FbTk/RadioMenuItem.hh b/src/FbTk/RadioMenuItem.hh
index ddd2274..cc3f00a 100644
--- a/src/FbTk/RadioMenuItem.hh
+++ b/src/FbTk/RadioMenuItem.hh
@@ -47,7 +47,7 @@ public:
47 setToggleItem(true); 47 setToggleItem(true);
48 } 48 }
49 49
50 RadioMenuItem(const FbString &label, Menu *submenu, Menu *host_menu = 0): 50 RadioMenuItem(const FbString &label, const RefCount<Menu> &submenu, Menu *host_menu = 0):
51 MenuItem(label, submenu, host_menu) { 51 MenuItem(label, submenu, host_menu) {
52 setToggleItem(true); 52 setToggleItem(true);
53 } 53 }
diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc
index ebf67fe..070e45b 100644
--- a/src/IconbarTool.cc
+++ b/src/IconbarTool.cc
@@ -246,12 +246,12 @@ IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme,
246 m_rc_client_padding(screen.resourceManager(), 10, 246 m_rc_client_padding(screen.resourceManager(), 10,
247 screen.name() + ".iconbar.iconTextPadding"), 247 screen.name() + ".iconbar.iconTextPadding"),
248 m_rc_use_pixmap(screen.resourceManager(), true, screen.name() + ".iconbar.usePixmap"), 248 m_rc_use_pixmap(screen.resourceManager(), true, screen.name() + ".iconbar.usePixmap"),
249 m_menu(screen.menuTheme(), screen.imageControl(), 249 m_menu(new FbMenu(screen.menuTheme(), screen.imageControl(),
250 *screen.layerManager().getLayer(ResourceLayer::MENU)), 250 *screen.layerManager().getLayer(ResourceLayer::MENU)) ),
251 m_alpha(255) { 251 m_alpha(255) {
252 252
253 // setup mode menu 253 // setup mode menu
254 setupModeMenu(m_menu, *this); 254 setupModeMenu(*m_menu, *this);
255 _FB_USES_NLS; 255 _FB_USES_NLS;
256 using namespace FbTk; 256 using namespace FbTk;
257 // setup use pixmap item to reconfig iconbar and save resource on click 257 // setup use pixmap item to reconfig iconbar and save resource on click
@@ -261,15 +261,13 @@ IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme,
261 save_and_reconfig->add(reconfig); 261 save_and_reconfig->add(reconfig);
262 save_and_reconfig->add(save); 262 save_and_reconfig->add(save);
263 RefCount<Command<void> > s_and_reconfig(save_and_reconfig); 263 RefCount<Command<void> > s_and_reconfig(save_and_reconfig);
264 m_menu.insert(new FbTk::BoolMenuItem(_FB_XTEXT(Toolbar, ShowIcons, 264 m_menu->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Toolbar, ShowIcons,
265 "Show Pictures", "chooses if little icons are shown next to title in the iconbar"), 265 "Show Pictures", "chooses if little icons are shown next to title in the iconbar"),
266 m_rc_use_pixmap, s_and_reconfig)); 266 m_rc_use_pixmap, s_and_reconfig));
267 m_menu.updateMenu(); 267 m_menu->updateMenu();
268 // must be internal menu, otherwise toolbar main menu tries to delete it.
269 m_menu.setInternalMenu();
270 268
271 // add iconbar menu to toolbar menu 269 // add iconbar menu to toolbar menu
272 menu.insert(m_menu.label().logical(), &m_menu); 270 menu.insert(m_menu->label().logical(), FbTk::RefCount<FbTk::Menu>(m_menu));
273 271
274 // setup signals 272 // setup signals
275 m_tracker.join(theme.reconfigSig(), FbTk::MemFun(*this, &IconbarTool::themeReconfigured)); 273 m_tracker.join(theme.reconfigSig(), FbTk::MemFun(*this, &IconbarTool::themeReconfigured));
@@ -313,7 +311,7 @@ void IconbarTool::hide() {
313void IconbarTool::setAlignment(FbTk::Container::Alignment align) { 311void IconbarTool::setAlignment(FbTk::Container::Alignment align) {
314 *m_rc_alignment = align; 312 *m_rc_alignment = align;
315 update(ALIGN, NULL); 313 update(ALIGN, NULL);
316 m_menu.reconfigure(); 314 m_menu->reconfigure();
317} 315}
318 316
319void IconbarTool::setMode(string mode) { 317void IconbarTool::setMode(string mode) {
@@ -353,7 +351,7 @@ void IconbarTool::setMode(string mode) {
353 351
354 renderTheme(); 352 renderTheme();
355 353
356 m_menu.reconfigure(); 354 m_menu->reconfigure();
357} 355}
358 356
359unsigned int IconbarTool::width() const { 357unsigned int IconbarTool::width() const {
diff --git a/src/IconbarTool.hh b/src/IconbarTool.hh
index 90df5cf..754cd50 100644
--- a/src/IconbarTool.hh
+++ b/src/IconbarTool.hh
@@ -116,7 +116,7 @@ private:
116 FbTk::IntResource m_rc_client_width; ///< size of client button in LEFT/RIGHT mode 116 FbTk::IntResource m_rc_client_width; ///< size of client button in LEFT/RIGHT mode
117 FbTk::UIntResource m_rc_client_padding; ///< padding of the text 117 FbTk::UIntResource m_rc_client_padding; ///< padding of the text
118 FbTk::BoolResource m_rc_use_pixmap; ///< if iconbar should use win pixmap or not 118 FbTk::BoolResource m_rc_use_pixmap; ///< if iconbar should use win pixmap or not
119 FbMenu m_menu; 119 FbTk::RefCount<FbMenu> m_menu;
120 int m_alpha; 120 int m_alpha;
121}; 121};
122 122
diff --git a/src/MenuCreator.cc b/src/MenuCreator.cc
index 6a6accc..46f233d 100644
--- a/src/MenuCreator.cc
+++ b/src/MenuCreator.cc
@@ -66,10 +66,10 @@ using FbTk::AutoReloadHelper;
66 66
67namespace { 67namespace {
68 68
69std::auto_ptr<FbMenu> createStyleMenu(int screen_number, const string &label, 69FbTk::RefCount<FbTk::Menu> createStyleMenu(int screen_number, const string &label,
70 AutoReloadHelper *reloader, const string &directory) { 70 AutoReloadHelper *reloader, const string &directory) {
71 71
72 std::auto_ptr<FbMenu> menu(MenuCreator::createMenu(label, screen_number)); 72 FbTk::RefCount<FbMenu> menu(MenuCreator::createMenu(label, screen_number));
73 73
74 // perform shell style ~ home directory expansion 74 // perform shell style ~ home directory expansion
75 string stylesdir(FbTk::StringUtil::expandFilename(directory)); 75 string stylesdir(FbTk::StringUtil::expandFilename(directory));
@@ -107,11 +107,11 @@ std::auto_ptr<FbMenu> createStyleMenu(int screen_number, const string &label,
107 return menu; 107 return menu;
108} 108}
109 109
110std::auto_ptr<FbMenu> createRootCmdMenu(int screen_number, const string &label, 110FbTk::RefCount<FbTk::Menu> createRootCmdMenu(int screen_number, const string &label,
111 const string &directory, AutoReloadHelper *reloader, 111 const string &directory, AutoReloadHelper *reloader,
112 const string &cmd) { 112 const string &cmd) {
113 113
114 std::auto_ptr<FbMenu> menu(MenuCreator::createMenu(label, screen_number)); 114 FbTk::RefCount<FbMenu> menu(MenuCreator::createMenu(label, screen_number));
115 115
116 // perform shell style ~ home directory expansion 116 // perform shell style ~ home directory expansion
117 string rootcmddir(FbTk::StringUtil::expandFilename(directory)); 117 string rootcmddir(FbTk::StringUtil::expandFilename(directory));
@@ -267,8 +267,8 @@ insertMenuItem(lua::state &l, FbTk::Menu &menu, FbTk::StringConvertor &parent_co
267 int size = menu.insert(str_label); 267 int size = menu.insert(str_label);
268 menu.setItemEnabled(size-1, false); 268 menu.setItemEnabled(size-1, false);
269 } else if(str_key == "icons") { 269 } else if(str_key == "icons") {
270 FbTk::Menu *submenu = MenuCreator::createMenuType("iconmenu", screen_number); 270 FbTk::RefCount<FbTk::Menu> submenu = MenuCreator::createMenuType("iconmenu", screen_number);
271 if (submenu == 0) 271 if (! submenu)
272 return; 272 return;
273 if (str_label.empty()) 273 if (str_label.empty())
274 menu.insert(_FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), submenu); 274 menu.insert(_FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), submenu);
@@ -281,12 +281,12 @@ insertMenuItem(lua::state &l, FbTk::Menu &menu, FbTk::StringConvertor &parent_co
281 else 281 else
282 menu.insert(str_label, exit_cmd); 282 menu.insert(str_label, exit_cmd);
283 } else if (str_key == "config") { 283 } else if (str_key == "config") {
284 menu.insert(str_label, &screen->configMenu()); 284 menu.insert(str_label, FbTk::RefCount<FbTk::Menu>(screen->configMenu()) );
285 } else if(str_key == "menu") { 285 } else if(str_key == "menu") {
286 std::auto_ptr<FbMenu> t(MenuCreator::createMenu("", screen_number)); 286 FbTk::RefCount<FbTk::Menu> t(MenuCreator::createMenu("", screen_number));
287 l.pushvalue(-1); 287 l.pushvalue(-1);
288 createMenu_(*t, l, *conv, reloader); 288 createMenu_(*t, l, *conv, reloader);
289 menu.insert(str_label, t.release()); 289 menu.insert(str_label, t);
290 } else { 290 } else {
291 // items that have a parameter 291 // items that have a parameter
292 const string &str_cmd = getField(l, -1, "param"); 292 const string &str_cmd = getField(l, -1, "param");
@@ -301,16 +301,15 @@ insertMenuItem(lua::state &l, FbTk::Menu &menu, FbTk::StringConvertor &parent_co
301 menu.insert(new StyleMenuItem(str_label, str_cmd)); 301 menu.insert(new StyleMenuItem(str_label, str_cmd));
302 else if (str_key == "stylesdir") 302 else if (str_key == "stylesdir")
303 menu.insert(str_label, 303 menu.insert(str_label,
304 createStyleMenu(screen_number, str_label, reloader, str_cmd).release()); 304 createStyleMenu(screen_number, str_label, reloader, str_cmd));
305 else if (str_key == "wallpapers") { 305 else if (str_key == "wallpapers") {
306 string program = getField(l, -1, "program"); 306 string program = getField(l, -1, "program");
307 if(program.empty()) 307 if(program.empty())
308 program = realProgramName("fbsetbg"); 308 program = realProgramName("fbsetbg");
309 menu.insert(str_label, createRootCmdMenu(screen_number, str_label, str_cmd, 309 menu.insert(str_label, createRootCmdMenu(screen_number, str_label, str_cmd,
310 reloader, program).release() ); 310 reloader, program) );
311 } else if (str_key == "workspaces") { 311 } else if (str_key == "workspaces") {
312 screen->workspaceMenu().setInternalMenu(); 312 menu.insert(str_label, FbTk::RefCount<FbTk::Menu>(screen->workspaceMenu()) );
313 menu.insert(str_label, &screen->workspaceMenu());
314 } else { 313 } else {
315 // finally, try window-related commands 314 // finally, try window-related commands
316 MenuCreator::createWindowMenuItem(str_key, str_label, menu); 315 MenuCreator::createWindowMenuItem(str_key, str_label, menu);
@@ -396,17 +395,17 @@ void MenuCreator::createFromFile(const string &filename,
396 createMenu(inject_into, l, reloader); 395 createMenu(inject_into, l, reloader);
397} 396}
398 397
399FbMenu *MenuCreator::createMenuType(const string &type, int screen_num) { 398FbTk::RefCount<FbMenu> MenuCreator::createMenuType(const string &type, int screen_num) {
399 FbTk::RefCount<FbMenu> menu;
400 BScreen *screen = Fluxbox::instance()->findScreen(screen_num); 400 BScreen *screen = Fluxbox::instance()->findScreen(screen_num);
401 if (screen == 0) 401
402 return 0;
403 if (type == "iconmenu") 402 if (type == "iconmenu")
404 return new ClientMenu(*screen, screen->iconList(), 403 menu.reset(new ClientMenu(*screen, screen->iconList(),
405 true); // listen to icon list changes 404 true)); // listen to icon list changes
406 else if (type == "workspacemenu") 405 else if (type == "workspacemenu")
407 return new WorkspaceMenu(*screen); 406 menu.reset(new WorkspaceMenu(*screen));
408 407
409 return 0; 408 return menu;
410} 409}
411 410
412bool MenuCreator::createWindowMenuItem(const string &type, 411bool MenuCreator::createWindowMenuItem(const string &type,
@@ -494,10 +493,9 @@ bool MenuCreator::createWindowMenuItem(const string &type,
494 if (screen == 0) 493 if (screen == 0)
495 return false; 494 return false;
496 495
497 FbTk::Menu *submenu = 496 FbTk::RefCount<FbTk::Menu> submenu( new AlphaMenu(screen->menuTheme(),
498 new AlphaMenu(screen->menuTheme(),
499 screen->imageControl(), 497 screen->imageControl(),
500 *screen->layerManager().getLayer(ResourceLayer::MENU)); 498 *screen->layerManager().getLayer(ResourceLayer::MENU)) );
501 submenu->disableTitle(); 499 submenu->disableTitle();
502 menu.insert(label.empty() ? _FB_XTEXT(Configmenu, Transparency, "Transparency", 500 menu.insert(label.empty() ? _FB_XTEXT(Configmenu, Transparency, "Transparency",
503 "Menu containing various transparency options"): label, 501 "Menu containing various transparency options"): label,
@@ -515,17 +513,17 @@ bool MenuCreator::createWindowMenuItem(const string &type,
515 513
516 } else if (type == "sendto") { 514 } else if (type == "sendto") {
517 menu.insert(label.empty() ? _FB_XTEXT(Windowmenu, SendTo, "Send To...", "Send to menu item name"): 515 menu.insert(label.empty() ? _FB_XTEXT(Windowmenu, SendTo, "Send To...", "Send to menu item name"):
518 label, new SendToMenu(*Fluxbox::instance()->findScreen(menu.screenNumber()))); 516 label, FbTk::RefCount<FbTk::Menu>(new SendToMenu(*Fluxbox::instance()->findScreen(menu.screenNumber()))) );
519 } else if (type == "layer") { 517 } else if (type == "layer") {
520 BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber()); 518 BScreen *screen = Fluxbox::instance()->findScreen(menu.screenNumber());
521 if (screen == 0) 519 if (screen == 0)
522 return false; 520 return false;
523 521
524 FbTk::Menu *submenu = new LayerMenu(screen->menuTheme(), 522 FbTk::RefCount<FbTk::Menu> submenu( new LayerMenu(screen->menuTheme(),
525 screen->imageControl(), 523 screen->imageControl(),
526 *screen->layerManager().getLayer(ResourceLayer::MENU), 524 *screen->layerManager().getLayer(ResourceLayer::MENU),
527 &context, 525 &context,
528 false); 526 false) );
529 submenu->disableTitle(); 527 submenu->disableTitle();
530 menu.insert(label.empty()?_FB_XTEXT(Windowmenu, Layer, "Layer ...", "Layer menu"):label, submenu); 528 menu.insert(label.empty()?_FB_XTEXT(Windowmenu, Layer, "Layer ...", "Layer menu"):label, submenu);
531 529
diff --git a/src/MenuCreator.hh b/src/MenuCreator.hh
index 60f931d..cdbba0c 100644
--- a/src/MenuCreator.hh
+++ b/src/MenuCreator.hh
@@ -24,6 +24,7 @@
24#define MENUCREATOR_HH 24#define MENUCREATOR_HH
25 25
26#include "FbTk/FbString.hh" 26#include "FbTk/FbString.hh"
27#include "FbTk/RefCount.hh"
27 28
28#include <list> 29#include <list>
29#include <memory> 30#include <memory>
@@ -44,7 +45,7 @@ namespace MenuCreator {
44 void 45 void
45 createMenu(FbTk::Menu &inject_into, lua::state &l, FbTk::AutoReloadHelper *reloader = NULL); 46 createMenu(FbTk::Menu &inject_into, lua::state &l, FbTk::AutoReloadHelper *reloader = NULL);
46 FbMenu *createMenu(const std::string &label, int screen_num); 47 FbMenu *createMenu(const std::string &label, int screen_num);
47 FbMenu *createMenuType(const std::string &label, int screen_num); 48 FbTk::RefCount<FbMenu> createMenuType(const std::string &label, int screen_num);
48 void createFromFile(const std::string &filename, 49 void createFromFile(const std::string &filename,
49 FbTk::Menu &inject_into, 50 FbTk::Menu &inject_into,
50 FbTk::AutoReloadHelper *reloader = NULL); 51 FbTk::AutoReloadHelper *reloader = NULL);
diff --git a/src/Remember.cc b/src/Remember.cc
index 9b1233e..6364f37 100644
--- a/src/Remember.cc
+++ b/src/Remember.cc
@@ -312,10 +312,10 @@ private:
312 Remember::Attribute m_attrib; 312 Remember::Attribute m_attrib;
313}; 313};
314 314
315FbTk::Menu *createRememberMenu(BScreen &screen) { 315FbTk::RefCount<FbTk::Menu> createRememberMenu(BScreen &screen) {
316 // each fluxboxwindow has its own windowmenu 316 // each fluxboxwindow has its own windowmenu
317 // so we also create a remember menu just for it... 317 // so we also create a remember menu just for it...
318 FbTk::Menu *menu = screen.createMenu("Remember"); 318 FbTk::RefCount<FbTk::Menu> menu( screen.createMenu("Remember") );
319 319
320 // if enabled, then we want this to be a unavailable menu 320 // if enabled, then we want this to be a unavailable menu
321 /* 321 /*
diff --git a/src/Screen.cc b/src/Screen.cc
index ae31806..d19a0b4 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -42,7 +42,6 @@
42#include "FbTk/RadioMenuItem.hh" 42#include "FbTk/RadioMenuItem.hh"
43 43
44// menus 44// menus
45#include "FbMenu.hh"
46#include "LayerMenu.hh" 45#include "LayerMenu.hh"
47 46
48#include "MenuCreator.hh" 47#include "MenuCreator.hh"
@@ -453,7 +452,6 @@ BScreen::BScreen(FbTk::ResourceManager_base &rm,
453 m_current_workspace = m_workspaces_list.front(); 452 m_current_workspace = m_workspaces_list.front();
454 453
455 m_windowmenu.reset(createMenu("")); 454 m_windowmenu.reset(createMenu(""));
456 m_windowmenu->setInternalMenu();
457 m_windowmenu->setReloadHelper(new FbTk::AutoReloadHelper()); 455 m_windowmenu->setReloadHelper(new FbTk::AutoReloadHelper());
458 m_windowmenu->reloadHelper()->setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<BScreen>(*this, &BScreen::rereadWindowMenu))); 456 m_windowmenu->reloadHelper()->setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<BScreen>(*this, &BScreen::rereadWindowMenu)));
459 457
@@ -464,7 +462,6 @@ BScreen::BScreen(FbTk::ResourceManager_base &rm,
464 m_configmenu.reset(createMenu(_FB_XTEXT(Menu, Configuration, 462 m_configmenu.reset(createMenu(_FB_XTEXT(Menu, Configuration,
465 "Configuration", "Title of configuration menu"))); 463 "Configuration", "Title of configuration menu")));
466 setupConfigmenu(*m_configmenu.get()); 464 setupConfigmenu(*m_configmenu.get());
467 m_configmenu->setInternalMenu();
468 465
469 // check which desktop we should start on 466 // check which desktop we should start on
470 unsigned int first_desktop = 0; 467 unsigned int first_desktop = 0;
@@ -510,34 +507,7 @@ BScreen::~BScreen() {
510 // we need to destroy it before we destroy workspaces 507 // we need to destroy it before we destroy workspaces
511 m_workspacemenu.reset(0); 508 m_workspacemenu.reset(0);
512 509
513 if (m_extramenus.size()) { 510 m_extramenus.clear();
514 // check whether extramenus are included in windowmenu
515 // if not, we clean them ourselves
516 bool extramenus_in_windowmenu = false;
517 for (size_t i = 0, n = m_windowmenu->numberOfItems(); i < n; i++)
518 if (m_windowmenu->find(i)->submenu() == m_extramenus.begin()->second) {
519 extramenus_in_windowmenu = true;
520 break;
521 }
522
523 ExtraMenus::iterator mit = m_extramenus.begin();
524 ExtraMenus::iterator mit_end = m_extramenus.end();
525 for (; mit != mit_end; ++mit) {
526 // we set them to NOT internal so that they will be deleted when the
527 // menu is cleaned up. We can't delete them here because they are
528 // still in the menu
529 // (They need to be internal for most of the time so that if we
530 // rebuild the menu, then they won't be removed.
531 if (! extramenus_in_windowmenu) {
532 // not attached to our windowmenu
533 // so we clean it up
534 delete mit->second;
535 } else {
536 // let the parent clean it up
537 mit->second->setInternalMenu(false);
538 }
539 }
540 }
541 511
542 removeWorkspaceNames(); 512 removeWorkspaceNames();
543 using namespace FbTk::STLUtil; 513 using namespace FbTk::STLUtil;
@@ -565,9 +535,9 @@ BScreen::~BScreen() {
565 m_slit.reset(0); 535 m_slit.reset(0);
566 536
567 537
568 delete m_rootmenu.release(); 538 m_rootmenu.reset(0);
569 delete m_workspacemenu.release(); 539 m_workspacemenu.reset(0);
570 delete m_windowmenu.release(); 540 m_windowmenu.reset(0);
571 541
572 // TODO fluxgen: check if this is the right place 542 // TODO fluxgen: check if this is the right place
573 for (size_t i = 0; i < m_head_areas.size(); i++) 543 for (size_t i = 0; i < m_head_areas.size(); i++)
@@ -858,8 +828,8 @@ FbMenu *BScreen::createToggleMenu(const string &label) {
858 return menu; 828 return menu;
859} 829}
860 830
861void BScreen::addExtraWindowMenu(const FbTk::FbString &label, FbTk::Menu *menu) { 831void
862 menu->setInternalMenu(); 832BScreen::addExtraWindowMenu(const FbTk::FbString &label, const FbTk::RefCount<FbTk::Menu> &menu) {
863 menu->disableTitle(); 833 menu->disableTitle();
864 m_extramenus.push_back(make_pair(label, menu)); 834 m_extramenus.push_back(make_pair(label, menu));
865 rereadWindowMenu(); 835 rereadWindowMenu();
@@ -1403,7 +1373,7 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id,
1403} 1373}
1404 1374
1405void BScreen::initMenus() { 1375void BScreen::initMenus() {
1406 m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber())); 1376 m_workspacemenu = MenuCreator::createMenuType("workspacemenu", screenNumber());
1407 1377
1408 m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename()); 1378 m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename());
1409 m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename()); 1379 m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename());
@@ -1429,7 +1399,6 @@ void BScreen::rereadMenu() {
1429 FbTk::RefCount<FbTk::Command<void> > restart_fb(FbTk::CommandParser<void>::instance().parse("restart")); 1399 FbTk::RefCount<FbTk::Command<void> > restart_fb(FbTk::CommandParser<void>::instance().parse("restart"));
1430 FbTk::RefCount<FbTk::Command<void> > exit_fb(FbTk::CommandParser<void>::instance().parse("exit")); 1400 FbTk::RefCount<FbTk::Command<void> > exit_fb(FbTk::CommandParser<void>::instance().parse("exit"));
1431 FbTk::RefCount<FbTk::Command<void> > execute_xterm(FbTk::CommandParser<void>::instance().parse("exec xterm")); 1401 FbTk::RefCount<FbTk::Command<void> > execute_xterm(FbTk::CommandParser<void>::instance().parse("exec xterm"));
1432 m_rootmenu->setInternalMenu();
1433 m_rootmenu->insert("xterm", execute_xterm); 1402 m_rootmenu->insert("xterm", execute_xterm);
1434 m_rootmenu->insert(_FB_XTEXT(Menu, Reconfigure, "Reconfigure", 1403 m_rootmenu->insert(_FB_XTEXT(Menu, Reconfigure, "Reconfigure",
1435 "Reload Configuration command")), 1404 "Reload Configuration command")),
@@ -1460,16 +1429,16 @@ void BScreen::rereadWindowMenu() {
1460 MenuCreator::createMenu(*m_windowmenu, l, m_windowmenu->reloadHelper()); 1429 MenuCreator::createMenu(*m_windowmenu, l, m_windowmenu->reloadHelper());
1461} 1430}
1462 1431
1463void BScreen::addConfigMenu(const FbTk::FbString &label, FbTk::Menu &menu) { 1432void BScreen::addConfigMenu(const FbTk::FbString &label, const FbTk::RefCount<FbTk::Menu> &menu) {
1464 m_configmenu_list.push_back(make_pair(label, &menu)); 1433 m_configmenu_list.push_back(make_pair(label, menu));
1465 if (m_configmenu.get()) 1434 if (m_configmenu.get())
1466 setupConfigmenu(*m_configmenu.get()); 1435 setupConfigmenu(*m_configmenu.get());
1467} 1436}
1468 1437
1469void BScreen::removeConfigMenu(FbTk::Menu &menu) { 1438void BScreen::removeConfigMenu(const FbTk::RefCount<FbTk::Menu> &menu) {
1470 Configmenus::iterator erase_it = find_if(m_configmenu_list.begin(), 1439 Configmenus::iterator erase_it = find_if(m_configmenu_list.begin(),
1471 m_configmenu_list.end(), 1440 m_configmenu_list.end(),
1472 FbTk::Compose(bind2nd(equal_to<FbTk::Menu *>(), &menu), 1441 FbTk::Compose(bind2nd(equal_to<FbTk::RefCount<FbTk::Menu> >(), menu),
1473 FbTk::Select2nd<Configmenus::value_type>())); 1442 FbTk::Select2nd<Configmenus::value_type>()));
1474 if (erase_it != m_configmenu_list.end()) 1443 if (erase_it != m_configmenu_list.end())
1475 m_configmenu_list.erase(erase_it); 1444 m_configmenu_list.erase(erase_it);
@@ -1560,7 +1529,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1560 FbTk::FbString focusmenu_label = _FB_XTEXT(Configmenu, FocusModel, 1529 FbTk::FbString focusmenu_label = _FB_XTEXT(Configmenu, FocusModel,
1561 "Focus Model", 1530 "Focus Model",
1562 "Method used to give focus to windows"); 1531 "Method used to give focus to windows");
1563 FbTk::Menu *focus_menu = createMenu(focusmenu_label); 1532 FbTk::RefCount<FbTk::Menu> focus_menu( createMenu(focusmenu_label) );
1564 1533
1565#define _BOOLITEM(m,a, b, c, d, e, f) (m).insert(new FbTk::BoolMenuItem(_FB_XTEXT(a, b, c, d), e, f)) 1534#define _BOOLITEM(m,a, b, c, d, e, f) (m).insert(new FbTk::BoolMenuItem(_FB_XTEXT(a, b, c, d), e, f))
1566 1535
@@ -1628,7 +1597,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1628 1597
1629 FbTk::FbString maxmenu_label = _FB_XTEXT(Configmenu, MaxMenu, 1598 FbTk::FbString maxmenu_label = _FB_XTEXT(Configmenu, MaxMenu,
1630 "Maximize Options", "heading for maximization options"); 1599 "Maximize Options", "heading for maximization options");
1631 FbTk::Menu *maxmenu = createMenu(maxmenu_label); 1600 FbTk::RefCount<FbTk::Menu> maxmenu( createMenu(maxmenu_label) );
1632 1601
1633 _BOOLITEM(*maxmenu, Configmenu, FullMax, 1602 _BOOLITEM(*maxmenu, Configmenu, FullMax,
1634 "Full Maximization", "Maximise over slit, toolbar, etc", 1603 "Full Maximization", "Maximise over slit, toolbar, etc",
@@ -1654,9 +1623,9 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1654 FbTk::FbString tabmenu_label = _FB_XTEXT(Configmenu, TabMenu, 1623 FbTk::FbString tabmenu_label = _FB_XTEXT(Configmenu, TabMenu,
1655 "Tab Options", 1624 "Tab Options",
1656 "heading for tab-related options"); 1625 "heading for tab-related options");
1657 FbTk::Menu *tab_menu = createMenu(tabmenu_label); 1626 FbTk::RefCount<FbTk::Menu> tab_menu( createMenu(tabmenu_label) );
1658 FbTk::FbString tabplacement_label = _FB_XTEXT(Menu, Placement, "Placement", "Title of Placement menu"); 1627 FbTk::FbString tabplacement_label = _FB_XTEXT(Menu, Placement, "Placement", "Title of Placement menu");
1659 FbTk::Menu *tabplacement_menu = createToggleMenu(tabplacement_label); 1628 FbTk::RefCount<FbTk::Menu> tabplacement_menu( createToggleMenu(tabplacement_label) );
1660 1629
1661 tab_menu->insert(tabplacement_label, tabplacement_menu); 1630 tab_menu->insert(tabplacement_label, tabplacement_menu);
1662 1631
@@ -1724,7 +1693,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1724 FbTk::FbString alphamenu_label = _FB_XTEXT(Configmenu, Transparency, 1693 FbTk::FbString alphamenu_label = _FB_XTEXT(Configmenu, Transparency,
1725 "Transparency", 1694 "Transparency",
1726 "Menu containing various transparency options"); 1695 "Menu containing various transparency options");
1727 FbTk::Menu *alpha_menu = createMenu(alphamenu_label); 1696 FbTk::RefCount<FbTk::Menu> alpha_menu( createMenu(alphamenu_label) );
1728 1697
1729 if (FbTk::Transparent::haveComposite(true)) { 1698 if (FbTk::Transparent::haveComposite(true)) {
1730 static FbTk::SimpleAccessor<bool> s_pseudo(Fluxbox::instance()->getPseudoTrans()); 1699 static FbTk::SimpleAccessor<bool> s_pseudo(Fluxbox::instance()->getPseudoTrans());
diff --git a/src/Screen.hh b/src/Screen.hh
index 8c89ab2..3e062ac 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -25,6 +25,7 @@
25#ifndef SCREEN_HH 25#ifndef SCREEN_HH
26#define SCREEN_HH 26#define SCREEN_HH
27 27
28#include "FbMenu.hh"
28#include "FbWinFrame.hh" 29#include "FbWinFrame.hh"
29#include "FbRootWindow.hh" 30#include "FbRootWindow.hh"
30#include "RootTheme.hh" 31#include "RootTheme.hh"
@@ -56,7 +57,6 @@
56#include <map> 57#include <map>
57 58
58class ClientPattern; 59class ClientPattern;
59class FbMenu;
60class Focusable; 60class Focusable;
61class FluxboxWindow; 61class FluxboxWindow;
62class WinClient; 62class WinClient;
@@ -87,7 +87,7 @@ public:
87 87
88 typedef std::vector<Workspace *> Workspaces; 88 typedef std::vector<Workspace *> Workspaces;
89 typedef std::vector<std::string> WorkspaceNames; 89 typedef std::vector<std::string> WorkspaceNames;
90 typedef std::list<std::pair<FbTk::FbString, FbTk::Menu *> > ExtraMenus; 90 typedef std::list<std::pair<FbTk::FbString, FbTk::RefCount<FbTk::Menu> > > ExtraMenus;
91 91
92 BScreen(FbTk::ResourceManager_base &rm, 92 BScreen(FbTk::ResourceManager_base &rm,
93 const std::string &screenname, 93 const std::string &screenname,
@@ -114,8 +114,8 @@ public:
114 // menus 114 // menus
115 const FbMenu &rootMenu() const { return *m_rootmenu.get(); } 115 const FbMenu &rootMenu() const { return *m_rootmenu.get(); }
116 FbMenu &rootMenu() { return *m_rootmenu.get(); } 116 FbMenu &rootMenu() { return *m_rootmenu.get(); }
117 const FbMenu &configMenu() const { return *m_configmenu.get(); } 117 FbTk::RefCount<const FbMenu> configMenu() const { return m_configmenu; }
118 FbMenu &configMenu() { return *m_configmenu.get(); } 118 const FbTk::RefCount<FbMenu> &configMenu() { return m_configmenu; }
119 const FbMenu &windowMenu() const { return *m_windowmenu.get(); } 119 const FbMenu &windowMenu() const { return *m_windowmenu.get(); }
120 FbMenu &windowMenu() { return *m_windowmenu.get(); } 120 FbMenu &windowMenu() { return *m_windowmenu.get(); }
121 ExtraMenus &extraWindowMenus() { return m_extramenus; } 121 ExtraMenus &extraWindowMenus() { return m_extramenus; }
@@ -151,9 +151,9 @@ public:
151 Workspace *currentWorkspace() { return m_current_workspace; } 151 Workspace *currentWorkspace() { return m_current_workspace; }
152 const Workspace *currentWorkspace() const { return m_current_workspace; } 152 const Workspace *currentWorkspace() const { return m_current_workspace; }
153 /// @return the workspace menu 153 /// @return the workspace menu
154 const FbMenu &workspaceMenu() const { return *m_workspacemenu.get(); } 154 FbTk::RefCount<const FbMenu> workspaceMenu() const { return m_workspacemenu; }
155 /// @return the workspace menu 155 /// @return the workspace menu
156 FbMenu &workspaceMenu() { return *m_workspacemenu.get(); } 156 const FbTk::RefCount<FbMenu> &workspaceMenu() { return m_workspacemenu; }
157 /// @return focus control handler 157 /// @return focus control handler
158 const FocusControl &focusControl() const { return *m_focus_control; } 158 const FocusControl &focusControl() const { return *m_focus_control; }
159 /// @return focus control handler 159 /// @return focus control handler
@@ -247,10 +247,8 @@ public:
247 247
248 /** 248 /**
249 * For extras to add menus. 249 * For extras to add menus.
250 * These menus will be marked internal,
251 * and deleted when the window dies (as opposed to Screen
252 */ 250 */
253 void addExtraWindowMenu(const FbTk::FbString &label, FbTk::Menu *menu); 251 void addExtraWindowMenu(const FbTk::FbString &label, const FbTk::RefCount<FbTk::Menu> &menu);
254 252
255 int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; } 253 int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; }
256 254
@@ -444,8 +442,8 @@ public:
444 // for extras to add menus. These menus must be marked 442 // for extras to add menus. These menus must be marked
445 // internal for their safety, and __the extension__ must 443 // internal for their safety, and __the extension__ must
446 // delete and remove the menu itself (opposite to Window) 444 // delete and remove the menu itself (opposite to Window)
447 void addConfigMenu(const FbTk::FbString &label, FbTk::Menu &menu); 445 void addConfigMenu(const FbTk::FbString &label, const FbTk::RefCount<FbTk::Menu> &menu);
448 void removeConfigMenu(FbTk::Menu &menu); 446 void removeConfigMenu(const FbTk::RefCount<FbTk::Menu> &menu);
449 447
450 448
451 /// Adds a resource to managed resource list 449 /// Adds a resource to managed resource list
@@ -495,11 +493,11 @@ private:
495 bool root_colormap_installed, managed; 493 bool root_colormap_installed, managed;
496 494
497 std::auto_ptr<FbTk::ImageControl> m_image_control; 495 std::auto_ptr<FbTk::ImageControl> m_image_control;
498 std::auto_ptr<FbMenu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu; 496 FbTk::RefCount<FbMenu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu;
499 497
500 ExtraMenus m_extramenus; 498 ExtraMenus m_extramenus;
501 499
502 typedef std::list<std::pair<FbTk::FbString, FbTk::Menu *> > Configmenus; 500 typedef std::list<std::pair<FbTk::FbString, FbTk::RefCount<FbTk::Menu> > > Configmenus;
503 501
504 502
505 Configmenus m_configmenu_list; 503 Configmenus m_configmenu_list;
diff --git a/src/Slit.cc b/src/Slit.cc
index 210c2a5..f1e171d 100644
--- a/src/Slit.cc
+++ b/src/Slit.cc
@@ -227,12 +227,12 @@ void Slit::SlitClientsRes::pushToLua(lua::state &l) const {
227Slit::Slit(BScreen &scr, FbTk::Layer &layer) 227Slit::Slit(BScreen &scr, FbTk::Layer &layer)
228 : m_hidden(false), m_visible(false), 228 : m_hidden(false), m_visible(false),
229 m_screen(scr), 229 m_screen(scr),
230 m_clientlist_menu(scr.menuTheme(), 230 m_clientlist_menu(new FbMenu(scr.menuTheme(),
231 scr.imageControl(), 231 scr.imageControl(),
232 *scr.layerManager().getLayer(ResourceLayer::MENU)), 232 *scr.layerManager().getLayer(ResourceLayer::MENU)) ),
233 m_slitmenu(scr.menuTheme(), 233 m_slitmenu(new FbMenu(scr.menuTheme(),
234 scr.imageControl(), 234 scr.imageControl(),
235 *scr.layerManager().getLayer(ResourceLayer::MENU)), 235 *scr.layerManager().getLayer(ResourceLayer::MENU)) ),
236#ifdef XINERAMA 236#ifdef XINERAMA
237 m_xineramaheadmenu(0), 237 m_xineramaheadmenu(0),
238#endif // XINERAMA 238#endif // XINERAMA
@@ -729,7 +729,7 @@ void Slit::reconfigure() {
729 else if (!doAutoHide() && isHidden()) 729 else if (!doAutoHide() && isHidden())
730 toggleHidden(); // restore visible 730 toggleHidden(); // restore visible
731 731
732 m_slitmenu.reconfigure(); 732 m_slitmenu->reconfigure();
733 updateClientmenu(); 733 updateClientmenu();
734 updateStrut(); 734 updateStrut();
735 735
@@ -952,11 +952,11 @@ void Slit::buttonPressEvent(XButtonEvent &be) {
952 return; 952 return;
953 953
954 if (be.button == Button3) { 954 if (be.button == Button3) {
955 if (! m_slitmenu.isVisible()) { 955 if (! m_slitmenu->isVisible()) {
956 screen().placementStrategy() 956 screen().placementStrategy()
957 .placeAndShowMenu(m_slitmenu, be.x_root, be.y_root, false); 957 .placeAndShowMenu(*m_slitmenu, be.x_root, be.y_root, false);
958 } else 958 } else
959 m_slitmenu.hide(); 959 m_slitmenu->hide();
960 } 960 }
961} 961}
962 962
@@ -985,7 +985,7 @@ void Slit::leaveNotifyEvent(XCrossingEvent &ev) {
985 } else { 985 } else {
986 if (! m_timer.isTiming()) { 986 if (! m_timer.isTiming()) {
987 // the menu is open, keep it firing until it closes 987 // the menu is open, keep it firing until it closes
988 if (m_slitmenu.isVisible()) 988 if (m_slitmenu->isVisible())
989 m_timer.fireOnce(false); 989 m_timer.fireOnce(false);
990 m_timer.start(); 990 m_timer.start();
991 } 991 }
@@ -1048,7 +1048,7 @@ void Slit::clearWindow() {
1048 1048
1049void Slit::toggleHidden() { 1049void Slit::toggleHidden() {
1050 if (doAutoHide()) { 1050 if (doAutoHide()) {
1051 if (!m_slitmenu.isVisible()) { 1051 if (!m_slitmenu->isVisible()) {
1052 m_timer.fireOnce(true); 1052 m_timer.fireOnce(true);
1053 } else 1053 } else
1054 return; 1054 return;
@@ -1068,24 +1068,24 @@ void Slit::updateClientmenu() {
1068 _FB_USES_NLS; 1068 _FB_USES_NLS;
1069 1069
1070 // clear old items 1070 // clear old items
1071 m_clientlist_menu.removeAll(); 1071 m_clientlist_menu->removeAll();
1072 m_clientlist_menu.setLabel(_FB_XTEXT(Slit, ClientsMenu, "Clients", "Slit client menu")); 1072 m_clientlist_menu->setLabel(_FB_XTEXT(Slit, ClientsMenu, "Clients", "Slit client menu"));
1073 1073
1074 FbTk::RefCount<FbTk::Command<void> > cycle_up(new FbTk::SimpleCommand<Slit>(*this, &Slit::cycleClientsUp)); 1074 FbTk::RefCount<FbTk::Command<void> > cycle_up(new FbTk::SimpleCommand<Slit>(*this, &Slit::cycleClientsUp));
1075 FbTk::RefCount<FbTk::Command<void> > cycle_down(new FbTk::SimpleCommand<Slit>(*this, &Slit::cycleClientsDown)); 1075 FbTk::RefCount<FbTk::Command<void> > cycle_down(new FbTk::SimpleCommand<Slit>(*this, &Slit::cycleClientsDown));
1076 m_clientlist_menu.insert(_FB_XTEXT(Slit, CycleUp, "Cycle Up", "Cycle clients upwards"), cycle_up); 1076 m_clientlist_menu->insert(_FB_XTEXT(Slit, CycleUp, "Cycle Up", "Cycle clients upwards"), cycle_up);
1077 m_clientlist_menu.insert(_FB_XTEXT(Slit, CycleDown, "Cycle Down", "Cycle clients downwards"), cycle_down); 1077 m_clientlist_menu->insert(_FB_XTEXT(Slit, CycleDown, "Cycle Down", "Cycle clients downwards"), cycle_down);
1078 1078
1079 m_clientlist_menu.insert(new FbTk::MenuSeparator()); 1079 m_clientlist_menu->insert(new FbTk::MenuSeparator());
1080 1080
1081 FbTk::RefCount<FbTk::Command<void> > reconfig(new FbTk::SimpleCommand<Slit>(*this, &Slit::reconfigure)); 1081 FbTk::RefCount<FbTk::Command<void> > reconfig(new FbTk::SimpleCommand<Slit>(*this, &Slit::reconfigure));
1082 SlitClients::iterator it = m_client_list.begin(); 1082 SlitClients::iterator it = m_client_list.begin();
1083 for (; it != m_client_list.end(); ++it) { 1083 for (; it != m_client_list.end(); ++it) {
1084 if ((*it) != 0 && (*it)->window() != 0) 1084 if ((*it) != 0 && (*it)->window() != 0)
1085 m_clientlist_menu.insert(new SlitClientMenuItem(*this, *(*it), reconfig)); 1085 m_clientlist_menu->insert(new SlitClientMenuItem(*this, *(*it), reconfig));
1086 } 1086 }
1087 1087
1088 m_clientlist_menu.updateMenu(); 1088 m_clientlist_menu->updateMenu();
1089} 1089}
1090 1090
1091void Slit::saveClientList() { 1091void Slit::saveClientList() {
@@ -1112,39 +1112,35 @@ void Slit::setupMenu() {
1112 FbTk::RefCount<FbTk::Command<void> > save_and_reconfigure_slit(s_a_reconf_slit_macro); 1112 FbTk::RefCount<FbTk::Command<void> > save_and_reconfigure_slit(s_a_reconf_slit_macro);
1113 1113
1114 1114
1115 // it'll be freed by the slitmenu (since not marked internal) 1115 FbTk::RefCount<FbTk::Menu> placement_menu( new FbMenu(m_screen.menuTheme(),
1116 FbMenu *placement_menu = new FbMenu(m_screen.menuTheme(),
1117 m_screen.imageControl(), 1116 m_screen.imageControl(),
1118 *m_screen.layerManager().getLayer(::ResourceLayer::MENU)); 1117 *m_screen.layerManager().getLayer(::ResourceLayer::MENU)) );
1119 1118
1120 1119
1121 // setup base menu 1120 // setup base menu
1122 m_slitmenu.setLabel(_FB_XTEXT(Slit, Slit, "Slit", "The Slit")); 1121 m_slitmenu->setLabel(_FB_XTEXT(Slit, Slit, "Slit", "The Slit"));
1123 m_slitmenu.insert(_FB_XTEXT(Menu, Placement, "Placement", "Title of Placement menu"), 1122 m_slitmenu->insert(_FB_XTEXT(Menu, Placement, "Placement", "Title of Placement menu"),
1124 placement_menu); 1123 placement_menu);
1125 1124
1126 m_slitmenu.insert(_FB_XTEXT(Menu, Layer, "Layer...", "Title of Layer menu"), m_layermenu.get()); 1125 m_slitmenu->insert(_FB_XTEXT(Menu, Layer, "Layer...", "Title of Layer menu"),
1126 FbTk::RefCount<FbTk::Menu>(m_layermenu) );
1127 1127
1128#ifdef XINERAMA 1128#ifdef XINERAMA
1129 if (screen().hasXinerama()) { 1129 if (screen().hasXinerama()) {
1130 m_slitmenu.insert(_FB_XTEXT(Menu, OnHead, "On Head...", "Title of On Head menu"), 1130 m_xineramaheadmenu.reset( new XineramaHeadMenu<Slit>(
1131 m_xineramaheadmenu = 1131 screen().menuTheme(), screen(), screen().imageControl(),
1132 new XineramaHeadMenu<Slit>( 1132 *screen().layerManager().getLayer(::ResourceLayer::MENU), *this,
1133 screen().menuTheme(), 1133 _FB_XTEXT(Slit, OnHead, "Slit on Head", "Title of Slits On Head menu")) );
1134 screen(), 1134 m_slitmenu->insert(_FB_XTEXT(Menu, OnHead, "On Head...", "Title of On Head menu"),
1135 screen().imageControl(), 1135 FbTk::RefCount<FbTk::Menu>(m_xineramaheadmenu));
1136 *screen().layerManager().getLayer(::ResourceLayer::MENU),
1137 *this,
1138 _FB_XTEXT(Slit, OnHead, "Slit on Head", "Title of Slits On Head menu")
1139 ));
1140 } 1136 }
1141#endif //XINERAMA 1137#endif //XINERAMA
1142 1138
1143 m_slitmenu.insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, AutoHide, "Auto hide", "This thing automatically hides when not close by"), 1139 m_slitmenu->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, AutoHide, "Auto hide", "This thing automatically hides when not close by"),
1144 m_rc_auto_hide, 1140 m_rc_auto_hide,
1145 save_and_reconfigure_slit)); 1141 save_and_reconfigure_slit));
1146 1142
1147 m_slitmenu.insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, MaximizeOver,"Maximize Over", "Maximize over this thing when maximizing"), 1143 m_slitmenu->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, MaximizeOver,"Maximize Over", "Maximize over this thing when maximizing"),
1148 m_rc_maximize_over, 1144 m_rc_maximize_over,
1149 save_and_reconfigure_slit)); 1145 save_and_reconfigure_slit));
1150 1146
@@ -1152,7 +1148,7 @@ void Slit::setupMenu() {
1152 FbTk::MenuItem *alpha_menuitem = 1148 FbTk::MenuItem *alpha_menuitem =
1153 new FbTk::IntMenuItem(_FB_XTEXT(Common, Alpha, "Alpha", "Transparency level"), 1149 new FbTk::IntMenuItem(_FB_XTEXT(Common, Alpha, "Alpha", "Transparency level"),
1154 m_rc_alpha, 1150 m_rc_alpha,
1155 0, 255, m_slitmenu); 1151 0, 255, *m_slitmenu);
1156 // setup command for alpha value 1152 // setup command for alpha value
1157 MacroCommand *alpha_macrocmd = new MacroCommand(); 1153 MacroCommand *alpha_macrocmd = new MacroCommand();
1158 RefCount<Command<void> > alpha_cmd(new SimpleCommand<Slit>(*this, &Slit::updateAlpha)); 1154 RefCount<Command<void> > alpha_cmd(new SimpleCommand<Slit>(*this, &Slit::updateAlpha));
@@ -1161,17 +1157,15 @@ void Slit::setupMenu() {
1161 RefCount<Command<void> > set_alpha_cmd(alpha_macrocmd); 1157 RefCount<Command<void> > set_alpha_cmd(alpha_macrocmd);
1162 alpha_menuitem->setCommand(set_alpha_cmd); 1158 alpha_menuitem->setCommand(set_alpha_cmd);
1163 1159
1164 m_slitmenu.insert(alpha_menuitem); 1160 m_slitmenu->insert(alpha_menuitem);
1165 1161
1166 m_slitmenu.insert(_FB_XTEXT(Slit, ClientsMenu, "Clients", "Slit client menu"), &m_clientlist_menu); 1162 m_slitmenu->insert(_FB_XTEXT(Slit, ClientsMenu, "Clients", "Slit client menu"),
1167 m_slitmenu.updateMenu(); 1163 FbTk::RefCount<FbTk::Menu>(m_clientlist_menu) );
1164 m_slitmenu->updateMenu();
1168 1165
1169 // setup sub menu 1166 // setup sub menu
1170 placement_menu->setLabel(_FB_XTEXT(Slit, Placement, "Slit Placement", "Slit Placement")); 1167 placement_menu->setLabel(_FB_XTEXT(Slit, Placement, "Slit Placement", "Slit Placement"));
1171 placement_menu->setMinimumColumns(3); 1168 placement_menu->setMinimumColumns(3);
1172 m_layermenu->setInternalMenu();
1173 m_clientlist_menu.setInternalMenu();
1174 m_slitmenu.setInternalMenu();
1175 1169
1176 typedef pair<FbTk::FbString, Slit::Placement> PlacementP; 1170 typedef pair<FbTk::FbString, Slit::Placement> PlacementP;
1177 typedef list<PlacementP> Placements; 1171 typedef list<PlacementP> Placements;
diff --git a/src/Slit.hh b/src/Slit.hh
index 9384ad6..f12a740 100644
--- a/src/Slit.hh
+++ b/src/Slit.hh
@@ -117,7 +117,7 @@ public:
117 Placement placement() const { return *m_rc_placement; } 117 Placement placement() const { return *m_rc_placement; }
118 int getOnHead() const { return *m_rc_on_head; } 118 int getOnHead() const { return *m_rc_on_head; }
119 void saveOnHead(int head); 119 void saveOnHead(int head);
120 FbTk::Menu &menu() { return m_slitmenu; } 120 FbTk::Menu &menu() { return *m_slitmenu; }
121 121
122 const FbTk::FbWindow &window() const { return frame.window; } 122 const FbTk::FbWindow &window() const { return frame.window; }
123 123
@@ -147,10 +147,10 @@ private:
147 BScreen &m_screen; 147 BScreen &m_screen;
148 FbTk::Timer m_timer; 148 FbTk::Timer m_timer;
149 149
150 std::auto_ptr<LayerMenu> m_layermenu; 150 FbTk::RefCount<LayerMenu> m_layermenu;
151 FbMenu m_clientlist_menu, m_slitmenu; 151 FbTk::RefCount<FbMenu> m_clientlist_menu, m_slitmenu;
152#ifdef XINERAMA 152#ifdef XINERAMA
153 XineramaHeadMenu<Slit> *m_xineramaheadmenu; 153 FbTk::RefCount<XineramaHeadMenu<Slit> > m_xineramaheadmenu;
154#endif // XINERAMA 154#endif // XINERAMA
155 155
156 struct frame { 156 struct frame {
diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc
index 5da2777..35a0162 100644
--- a/src/ToolFactory.cc
+++ b/src/ToolFactory.cc
@@ -51,7 +51,7 @@ public:
51 51
52 m_tbar.screen() 52 m_tbar.screen()
53 .placementStrategy() 53 .placementStrategy()
54 .placeAndShowMenu(m_tbar.menu(), e.xbutton.x_root, e.xbutton.y_root, false); 54 .placeAndShowMenu(*m_tbar.menu(), e.xbutton.x_root, e.xbutton.y_root, false);
55 } 55 }
56private: 56private:
57 Toolbar &m_tbar; 57 Toolbar &m_tbar;
@@ -87,13 +87,13 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
87 witem->button().setOnClick(showmenu); 87 witem->button().setOnClick(showmenu);
88 item = witem; 88 item = witem;
89 } else if (name == "iconbar") { 89 } else if (name == "iconbar") {
90 item = new IconbarTool(parent, m_iconbar_theme, m_focused_iconbar_theme, m_unfocused_iconbar_theme, screen(), tbar.menu()); 90 item = new IconbarTool(parent, m_iconbar_theme, m_focused_iconbar_theme, m_unfocused_iconbar_theme, screen(), *tbar.menu());
91 } else if (name == "systemtray") { 91 } else if (name == "systemtray") {
92#ifdef USE_SYSTRAY 92#ifdef USE_SYSTRAY
93 item = new SystemTray(parent, dynamic_cast<ButtonTheme &>(*m_systray_theme), screen()); 93 item = new SystemTray(parent, dynamic_cast<ButtonTheme &>(*m_systray_theme), screen());
94#endif 94#endif
95 } else if (name == "clock") { 95 } else if (name == "clock") {
96 item = new ClockTool(parent, m_clock_theme, screen(), tbar.menu()); 96 item = new ClockTool(parent, m_clock_theme, screen(), *tbar.menu());
97 } else { 97 } else {
98 98
99 std::string cmd_str = name; 99 std::string cmd_str = name;
diff --git a/src/Toolbar.cc b/src/Toolbar.cc
index 4490a4b..0899988 100644
--- a/src/Toolbar.cc
+++ b/src/Toolbar.cc
@@ -118,7 +118,7 @@ public:
118 void click(int button, int time, unsigned int mods) { 118 void click(int button, int time, unsigned int mods) {
119 m_toolbar.setPlacement(m_place); 119 m_toolbar.setPlacement(m_place);
120 m_toolbar.reconfigure(); 120 m_toolbar.reconfigure();
121 m_toolbar.placementMenu().reconfigure(); 121 m_toolbar.placementMenu()->reconfigure();
122 Fluxbox::instance()->save_rc(); 122 Fluxbox::instance()->save_rc();
123 } 123 }
124private: 124private:
@@ -156,17 +156,17 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::Layer &layer, size_t width):
156 m_window_pm(0), 156 m_window_pm(0),
157 m_screen(scrn), 157 m_screen(scrn),
158 m_layeritem(frame.window, layer), 158 m_layeritem(frame.window, layer),
159 m_layermenu(scrn.menuTheme(), 159 m_layermenu(new LayerMenu(scrn.menuTheme(),
160 scrn.imageControl(), 160 scrn.imageControl(),
161 *scrn.layerManager().getLayer(ResourceLayer::MENU), 161 *scrn.layerManager().getLayer(ResourceLayer::MENU),
162 this, 162 this,
163 true), 163 true)),
164 m_placementmenu(scrn.menuTheme(), 164 m_placementmenu(new FbMenu(scrn.menuTheme(),
165 scrn.imageControl(), 165 scrn.imageControl(),
166 *scrn.layerManager().getLayer(ResourceLayer::MENU)), 166 *scrn.layerManager().getLayer(ResourceLayer::MENU))),
167 m_toolbarmenu(scrn.menuTheme(), 167 m_toolbarmenu(new FbMenu(scrn.menuTheme(),
168 scrn.imageControl(), 168 scrn.imageControl(),
169 *scrn.layerManager().getLayer(ResourceLayer::MENU)), 169 *scrn.layerManager().getLayer(ResourceLayer::MENU))),
170#ifdef XINERAMA 170#ifdef XINERAMA
171 m_xineramaheadmenu(0), 171 m_xineramaheadmenu(0),
172#endif // XINERAMA 172#endif // XINERAMA
@@ -205,12 +205,9 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::Layer &layer, size_t width):
205 205
206 moveToLayer(static_cast<int>(*m_rc_layernum)); 206 moveToLayer(static_cast<int>(*m_rc_layernum));
207 207
208 m_layermenu.setLabel(_FB_XTEXT(Toolbar, Layer, "Toolbar Layer", "Title of toolbar layer menu")); 208 m_layermenu->setLabel(_FB_XTEXT(Toolbar, Layer, "Toolbar Layer", "Title of toolbar layer menu"));
209 m_placementmenu.setLabel(_FB_XTEXT(Toolbar, Placement, "Toolbar Placement", "Title of toolbar placement menu")); 209 m_placementmenu->setLabel(_FB_XTEXT(Toolbar, Placement, "Toolbar Placement", "Title of toolbar placement menu"));
210 210
211 m_layermenu.setInternalMenu();
212 m_placementmenu.setInternalMenu();
213 m_toolbarmenu.setInternalMenu();
214 setupMenus(); 211 setupMenus();
215 // add menu to screen 212 // add menu to screen
216 screen().addConfigMenu(_FB_XTEXT(Toolbar, Toolbar, "Toolbar", "title of toolbar menu item"), menu()); 213 screen().addConfigMenu(_FB_XTEXT(Toolbar, Toolbar, "Toolbar", "title of toolbar menu item"), menu());
@@ -251,7 +248,7 @@ Toolbar::~Toolbar() {
251 // from the tools 248 // from the tools
252 screen().removeConfigMenu(menu()); 249 screen().removeConfigMenu(menu());
253 250
254 menu().removeAll(); 251 menu()->removeAll();
255 252
256 deleteItems(); 253 deleteItems();
257 clearStrut(); 254 clearStrut();
@@ -370,7 +367,7 @@ void Toolbar::reconfigure() {
370 // destroy tools and rebuild them 367 // destroy tools and rebuild them
371 deleteItems(); 368 deleteItems();
372 // they will be readded later 369 // they will be readded later
373 menu().removeAll(); 370 menu()->removeAll();
374 setupMenus(true); // rebuild menu but skip rebuild of placement menu 371 setupMenus(true); // rebuild menu but skip rebuild of placement menu
375 372
376 m_tools = tools; // copy values 373 m_tools = tools; // copy values
@@ -393,7 +390,7 @@ void Toolbar::reconfigure() {
393 } 390 }
394 391
395 } else { // just update the menu 392 } else { // just update the menu
396 menu().reconfigure(); 393 menu()->reconfigure();
397 } 394 }
398 395
399 frame.bevel_w = theme()->bevelWidth(); 396 frame.bevel_w = theme()->bevelWidth();
@@ -485,7 +482,7 @@ void Toolbar::buttonPressEvent(XButtonEvent &be) {
485 482
486 screen() 483 screen()
487 .placementStrategy() 484 .placementStrategy()
488 .placeAndShowMenu(menu(), be.x_root, be.y_root, false); 485 .placeAndShowMenu(*menu(), be.x_root, be.y_root, false);
489} 486}
490 487
491void Toolbar::enterNotifyEvent(XCrossingEvent &ce) { 488void Toolbar::enterNotifyEvent(XCrossingEvent &ce) {
@@ -528,7 +525,7 @@ void Toolbar::leaveNotifyEvent(XCrossingEvent &event) {
528 if (isHidden()) { 525 if (isHidden()) {
529 if (m_hide_timer.isTiming()) 526 if (m_hide_timer.isTiming())
530 m_hide_timer.stop(); 527 m_hide_timer.stop();
531 } else if (! menu().isVisible() && ! m_hide_timer.isTiming()) 528 } else if (! menu()->isVisible() && ! m_hide_timer.isTiming())
532 m_hide_timer.start(); 529 m_hide_timer.start();
533 530
534} 531}
@@ -742,7 +739,7 @@ void Toolbar::setupMenus(bool skip_new_placement) {
742 typedef RefCount<Command<void> > RefCommand; 739 typedef RefCount<Command<void> > RefCommand;
743 typedef SimpleCommand<Toolbar> ToolbarCommand; 740 typedef SimpleCommand<Toolbar> ToolbarCommand;
744 741
745 menu().setLabel(_FB_XTEXT(Toolbar, Toolbar, 742 menu()->setLabel(_FB_XTEXT(Toolbar, Toolbar,
746 "Toolbar", "Title of Toolbar menu")); 743 "Toolbar", "Title of Toolbar menu"));
747 744
748 RefCommand reconfig_toolbar(new ToolbarCommand(*this, &Toolbar::reconfigure)); 745 RefCommand reconfig_toolbar(new ToolbarCommand(*this, &Toolbar::reconfigure));
@@ -758,11 +755,11 @@ void Toolbar::setupMenus(bool skip_new_placement) {
758 visible_macro->add(reconfig_toolbar); 755 visible_macro->add(reconfig_toolbar);
759 visible_macro->add(save_resources); 756 visible_macro->add(save_resources);
760 RefCommand toggle_visible_cmd(visible_macro); 757 RefCommand toggle_visible_cmd(visible_macro);
761 menu().insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, Visible, 758 menu()->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, Visible,
762 "Visible", "Whether this item is visible"), 759 "Visible", "Whether this item is visible"),
763 m_rc_visible, toggle_visible_cmd)); 760 m_rc_visible, toggle_visible_cmd));
764 761
765 menu().insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, AutoHide, 762 menu()->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, AutoHide,
766 "Auto hide", "Toggle auto hide of toolbar"), 763 "Auto hide", "Toggle auto hide of toolbar"),
767 m_rc_auto_hide, 764 m_rc_auto_hide,
768 reconfig_toolbar_and_save_resource)); 765 reconfig_toolbar_and_save_resource));
@@ -772,29 +769,27 @@ void Toolbar::setupMenus(bool skip_new_placement) {
772 "Toolbar width percent", 769 "Toolbar width percent",
773 "Percentage of screen width taken by toolbar"), 770 "Percentage of screen width taken by toolbar"),
774 m_rc_width_percent, 771 m_rc_width_percent,
775 0, 100, menu()); // min/max value 772 0, 100, *menu()); // min/max value
776 773
777 774
778 toolbar_menuitem->setCommand(reconfig_toolbar_and_save_resource); 775 toolbar_menuitem->setCommand(reconfig_toolbar_and_save_resource);
779 menu().insert(toolbar_menuitem); 776 menu()->insert(toolbar_menuitem);
780 777
781 menu().insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, MaximizeOver, 778 menu()->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, MaximizeOver,
782 "Maximize Over", 779 "Maximize Over",
783 "Maximize over this thing when maximizing"), 780 "Maximize over this thing when maximizing"),
784 m_rc_maximize_over, 781 m_rc_maximize_over,
785 reconfig_toolbar_and_save_resource)); 782 reconfig_toolbar_and_save_resource));
786 menu().insert(_FB_XTEXT(Menu, Layer, "Layer...", "Title of Layer menu"), &layerMenu()); 783 menu()->insert(_FB_XTEXT(Menu, Layer, "Layer...", "Title of Layer menu"), layerMenu());
787#ifdef XINERAMA 784#ifdef XINERAMA
788 if (screen().hasXinerama()) { 785 if (screen().hasXinerama()) {
789 menu().insert(_FB_XTEXT(Menu, OnHead, "On Head...", "Title of On Head menu"), 786 m_xineramaheadmenu.reset( new XineramaHeadMenu<Toolbar>(screen().menuTheme(),
790 m_xineramaheadmenu = 787 screen(), screen().imageControl(),
791 new XineramaHeadMenu<Toolbar>(screen().menuTheme(), 788 *screen().layerManager().getLayer(::ResourceLayer::MENU), *this,
792 screen(), 789 _FB_XTEXT(Toolbar, OnHead, "Toolbar on Head",
793 screen().imageControl(), 790 "Title of toolbar on head menu")));
794 *screen().layerManager().getLayer(::ResourceLayer::MENU), 791 menu()->insert(_FB_XTEXT(Menu, OnHead, "On Head...", "Title of On Head menu"),
795 *this, 792 FbTk::RefCount<FbTk::Menu>(m_xineramaheadmenu) );
796 _FB_XTEXT(Toolbar, OnHead, "Toolbar on Head",
797 "Title of toolbar on head menu")));
798 } 793 }
799#endif // XINERAMA 794#endif // XINERAMA
800 795
@@ -824,28 +819,28 @@ void Toolbar::setupMenus(bool skip_new_placement) {
824 { _FB_XTEXT(Align, BottomRight, "Bottom Right", "Bottom Right"), Toolbar::BOTTOMRIGHT} 819 { _FB_XTEXT(Align, BottomRight, "Bottom Right", "Bottom Right"), Toolbar::BOTTOMRIGHT}
825 }; 820 };
826 821
827 placementMenu().setMinimumColumns(3); 822 placementMenu()->setMinimumColumns(3);
828 // create items in sub menu 823 // create items in sub menu
829 for (size_t i=0; i< sizeof(place_menu)/sizeof(PlacementP); ++i) { 824 for (size_t i=0; i< sizeof(place_menu)/sizeof(PlacementP); ++i) {
830 const PlacementP& p = place_menu[i]; 825 const PlacementP& p = place_menu[i];
831 if (p.label == "") { 826 if (p.label == "") {
832 placementMenu().insert(p.label); 827 placementMenu()->insert(p.label);
833 placementMenu().setItemEnabled(i, false); 828 placementMenu()->setItemEnabled(i, false);
834 } else 829 } else
835 placementMenu().insert(new PlaceToolbarMenuItem(p.label, *this, 830 placementMenu()->insert(new PlaceToolbarMenuItem(p.label, *this,
836 p.placement)); 831 p.placement));
837 } 832 }
838 } 833 }
839 834
840 menu().insert(_FB_XTEXT(Menu, Placement, "Placement", "Title of Placement menu"), &placementMenu()); 835 menu()->insert(_FB_XTEXT(Menu, Placement, "Placement", "Title of Placement menu"), placementMenu());
841 placementMenu().updateMenu(); 836 placementMenu()->updateMenu();
842 837
843 838
844 // this saves resources and clears the slit window to update alpha value 839 // this saves resources and clears the slit window to update alpha value
845 FbTk::MenuItem *alpha_menuitem = 840 FbTk::MenuItem *alpha_menuitem =
846 new FbTk::IntMenuItem(_FB_XTEXT(Common, Alpha, "Alpha", "Transparency level"), 841 new FbTk::IntMenuItem(_FB_XTEXT(Common, Alpha, "Alpha", "Transparency level"),
847 m_rc_alpha, 842 m_rc_alpha,
848 0, 255, menu()); 843 0, 255, *menu());
849 // setup command for alpha value 844 // setup command for alpha value
850 MacroCommand *alpha_macrocmd = new MacroCommand(); 845 MacroCommand *alpha_macrocmd = new MacroCommand();
851 RefCount<Command<void> > alpha_cmd(new SimpleCommand<Toolbar>(*this, &Toolbar::updateAlpha)); 846 RefCount<Command<void> > alpha_cmd(new SimpleCommand<Toolbar>(*this, &Toolbar::updateAlpha));
@@ -854,8 +849,8 @@ void Toolbar::setupMenus(bool skip_new_placement) {
854 RefCount<Command<void> > set_alpha_cmd(alpha_macrocmd); 849 RefCount<Command<void> > set_alpha_cmd(alpha_macrocmd);
855 alpha_menuitem->setCommand(set_alpha_cmd); 850 alpha_menuitem->setCommand(set_alpha_cmd);
856 851
857 menu().insert(alpha_menuitem); 852 menu()->insert(alpha_menuitem);
858 menu().updateMenu(); 853 menu()->updateMenu();
859} 854}
860 855
861void Toolbar::saveOnHead(int head) { 856void Toolbar::saveOnHead(int head) {
diff --git a/src/Toolbar.hh b/src/Toolbar.hh
index eca379b..b0aeb60 100644
--- a/src/Toolbar.hh
+++ b/src/Toolbar.hh
@@ -104,13 +104,13 @@ public:
104 104
105 int layerNumber() const { return const_cast<FbTk::LayerItem &>(m_layeritem).getLayerNum(); } 105 int layerNumber() const { return const_cast<FbTk::LayerItem &>(m_layeritem).getLayerNum(); }
106 106
107 const FbTk::Menu &menu() const { return m_toolbarmenu; } 107 FbTk::RefCount<const FbTk::Menu> menu() const { return m_toolbarmenu; }
108 FbTk::Menu &menu() { return m_toolbarmenu; } 108 FbTk::RefCount<FbTk::Menu> menu() { return m_toolbarmenu; }
109 FbTk::Menu &placementMenu() { return m_placementmenu; } 109 FbTk::RefCount<FbTk::Menu> placementMenu() { return m_placementmenu; }
110 const FbTk::Menu &placementMenu() const { return m_placementmenu; } 110 FbTk::RefCount<const FbTk::Menu> placementMenu() const { return m_placementmenu; }
111 111
112 FbTk::Menu &layerMenu() { return m_layermenu; } 112 FbTk::RefCount<FbTk::Menu> layerMenu() { return m_layermenu; }
113 const FbTk::Menu &layerMenu() const { return m_layermenu; } 113 FbTk::RefCount<const FbTk::Menu> layerMenu() const { return m_layermenu; }
114 114
115 /// are we hidden? 115 /// are we hidden?
116 bool isHidden() const { return m_hidden; } 116 bool isHidden() const { return m_hidden; }
@@ -165,10 +165,10 @@ private:
165 FbTk::Timer m_hide_timer; ///< timer to for auto hide toolbar 165 FbTk::Timer m_hide_timer; ///< timer to for auto hide toolbar
166 166
167 FbTk::LayerItem m_layeritem; ///< layer item, must be declared before layermenu 167 FbTk::LayerItem m_layeritem; ///< layer item, must be declared before layermenu
168 LayerMenu m_layermenu; 168 FbTk::RefCount<LayerMenu> m_layermenu;
169 FbMenu m_placementmenu, m_toolbarmenu; 169 FbTk::RefCount<FbMenu> m_placementmenu, m_toolbarmenu;
170#ifdef XINERAMA 170#ifdef XINERAMA
171 XineramaHeadMenu<Toolbar> *m_xineramaheadmenu; 171 FbTk::RefCount<XineramaHeadMenu<Toolbar> > m_xineramaheadmenu;
172#endif // XINERAMA 172#endif // XINERAMA
173 173
174 174
diff --git a/src/Workspace.cc b/src/Workspace.cc
index a162b4c..8b3c411 100644
--- a/src/Workspace.cc
+++ b/src/Workspace.cc
@@ -65,17 +65,15 @@ using std::string;
65 65
66Workspace::Workspace(BScreen &scrn, const string &name, unsigned int id): 66Workspace::Workspace(BScreen &scrn, const string &name, unsigned int id):
67 m_screen(scrn), 67 m_screen(scrn),
68 m_clientmenu(scrn, m_windowlist, false), 68 m_clientmenu(new ClientMenu(scrn, m_windowlist, false) ),
69 m_name(name), 69 m_name(name),
70 m_id(id) { 70 m_id(id) {
71 71
72 m_clientlist_sig.connect(FbTk::MemFun(m_clientmenu, 72 m_clientlist_sig.connect(FbTk::MemFun(*m_clientmenu,
73 &ClientMenu::refreshMenu)); 73 &ClientMenu::refreshMenu));
74 74
75 menu().setInternalMenu();
76 setName(name); 75 setName(name);
77 76
78
79} 77}
80 78
81 79
@@ -145,7 +143,7 @@ void Workspace::removeAll(unsigned int dest) {
145 143
146 144
147void Workspace::reconfigure() { 145void Workspace::reconfigure() {
148 menu().reconfigure(); 146 menu()->reconfigure();
149 147
150 Windows::iterator it = m_windowlist.begin(); 148 Windows::iterator it = m_windowlist.begin();
151 Windows::iterator it_end = m_windowlist.end(); 149 Windows::iterator it_end = m_windowlist.end();
@@ -176,8 +174,8 @@ void Workspace::setName(const string &name) {
176 174
177 screen().updateWorkspaceName(m_id); 175 screen().updateWorkspaceName(m_id);
178 176
179 menu().setLabel(FbTk::BiDiString(m_name)); 177 menu()->setLabel(FbTk::BiDiString(m_name));
180 menu().updateMenu(); 178 menu()->updateMenu();
181} 179}
182 180
183/** 181/**
diff --git a/src/Workspace.hh b/src/Workspace.hh
index 2dabb3e..829bdf0 100644
--- a/src/Workspace.hh
+++ b/src/Workspace.hh
@@ -65,8 +65,8 @@ public:
65 BScreen &screen() { return m_screen; } 65 BScreen &screen() { return m_screen; }
66 const BScreen &screen() const { return m_screen; } 66 const BScreen &screen() const { return m_screen; }
67 67
68 FbTk::Menu &menu() { return m_clientmenu; } 68 FbTk::RefCount<FbTk::Menu> menu() { return m_clientmenu; }
69 const FbTk::Menu &menu() const { return m_clientmenu; } 69 FbTk::RefCount<const FbTk::Menu> menu() const { return m_clientmenu; }
70 /// name of this workspace 70 /// name of this workspace
71 const FbTk::FbString &name() const { return m_name; } 71 const FbTk::FbString &name() const { return m_name; }
72 /** 72 /**
@@ -86,7 +86,7 @@ private:
86 86
87 Windows m_windowlist; 87 Windows m_windowlist;
88 FbTk::Signal<> m_clientlist_sig; 88 FbTk::Signal<> m_clientlist_sig;
89 ClientMenu m_clientmenu; 89 FbTk::RefCount<ClientMenu> m_clientmenu;
90 90
91 FbTk::FbString m_name; ///< name of this workspace 91 FbTk::FbString m_name; ///< name of this workspace
92 unsigned int m_id; ///< id, obsolete, this should be in BScreen 92 unsigned int m_id; ///< id, obsolete, this should be in BScreen
diff --git a/src/WorkspaceMenu.cc b/src/WorkspaceMenu.cc
index d73947b..0b563aa 100644
--- a/src/WorkspaceMenu.cc
+++ b/src/WorkspaceMenu.cc
@@ -56,8 +56,7 @@ const unsigned int NR_STATIC_ITEMS = 6;
56void add_workspaces(WorkspaceMenu& menu, BScreen& screen) { 56void add_workspaces(WorkspaceMenu& menu, BScreen& screen) {
57 for (size_t i = 0; i < screen.numberOfWorkspaces(); ++i) { 57 for (size_t i = 0; i < screen.numberOfWorkspaces(); ++i) {
58 Workspace* w = screen.getWorkspace(i); 58 Workspace* w = screen.getWorkspace(i);
59 w->menu().setInternalMenu(); 59 FbTk::MultiButtonMenuItem* submenu = new FbTk::MultiButtonMenuItem(5, FbTk::BiDiString(w->name()), w->menu());
60 FbTk::MultiButtonMenuItem* submenu = new FbTk::MultiButtonMenuItem(5, FbTk::BiDiString(w->name()), &w->menu());
61 FbTk::RefCount<FbTk::Command<void> > jump_cmd(new JumpToWorkspaceCmd(w->workspaceID())); 60 FbTk::RefCount<FbTk::Command<void> > jump_cmd(new JumpToWorkspaceCmd(w->workspaceID()));
62 submenu->setCommand(3, jump_cmd); 61 submenu->setCommand(3, jump_cmd);
63 menu.insert(submenu, i + IDX_AFTER_ICONS); 62 menu.insert(submenu, i + IDX_AFTER_ICONS);
@@ -112,7 +111,7 @@ void WorkspaceMenu::init(BScreen &screen) {
112 111
113 setLabel(_FB_XTEXT(Workspace, MenuTitle, "Workspaces", "Title of main workspace menu")); 112 setLabel(_FB_XTEXT(Workspace, MenuTitle, "Workspaces", "Title of main workspace menu"));
114 insert(_FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"), 113 insert(_FB_XTEXT(Menu, Icons, "Icons", "Iconic windows menu title"),
115 MenuCreator::createMenuType("iconmenu", screen.screenNumber())); 114 FbTk::RefCount<FbTk::Menu>(MenuCreator::createMenuType("iconmenu", screen.screenNumber())) );
116 insert(new FbTk::MenuSeparator()); 115 insert(new FbTk::MenuSeparator());
117 116
118 ::add_workspaces(*this, screen); 117 ::add_workspaces(*this, screen);