aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsimonb <simonb>2006-03-22 12:23:17 (GMT)
committersimonb <simonb>2006-03-22 12:23:17 (GMT)
commitfe4a7db228d69bc9a66ed948f218ef489b2cedaf (patch)
tree5ee59c4862b04871dbd6f5112278682e4b005e47
parentda365bb4c99edf1a18e1f8db285f8c2dcee2c5e3 (diff)
downloadfluxbox-fe4a7db228d69bc9a66ed948f218ef489b2cedaf.zip
fluxbox-fe4a7db228d69bc9a66ed948f218ef489b2cedaf.tar.bz2
external tabs features and bugfixes
-rw-r--r--ChangeLog9
-rw-r--r--nls/fluxbox-nls.hh3
-rw-r--r--src/Container.cc14
-rw-r--r--src/FbWinFrame.cc90
-rw-r--r--src/FbWinFrame.hh15
-rw-r--r--src/Screen.cc235
-rw-r--r--src/Screen.hh13
-rw-r--r--src/Window.cc107
-rw-r--r--src/Window.hh3
9 files changed, 417 insertions, 72 deletions
diff --git a/ChangeLog b/ChangeLog
index 6a5919e..1073ad7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
1(Format: Year/Month/Day) 1(Format: Year/Month/Day)
2Changes for 0.9.16: 2Changes for 0.9.16:
3*06/03/22:
4 * More external tabs work (Simon)
5 - Can now be placed TopLeft/TopRight/BottomLeft/BottomRight
6 - New "Tab Options" config menu, with (efficient) runtime updating
7 - edge snapping includes tabs
8 - decoration fixes where some missed the tab option
9 - label text color was not updated
10 Screen.hh/cc Window.hh/cc FbWinFrame.hh/cc Container.cc
11 fluxbox-nls.hh
3*06/03/20: 12*06/03/20:
4 * Fix placement config (some compilers resulted in ignoring of 13 * Fix placement config (some compilers resulted in ignoring of
5 placement policy setting), and a minor ext. tabs placement bug 14 placement policy setting), and a minor ext. tabs placement bug
diff --git a/nls/fluxbox-nls.hh b/nls/fluxbox-nls.hh
index 21fbd88..fe70b64 100644
--- a/nls/fluxbox-nls.hh
+++ b/nls/fluxbox-nls.hh
@@ -72,7 +72,8 @@ enum {
72 ConfigmenuTransparency = 18, 72 ConfigmenuTransparency = 18,
73 ConfigmenuFocusedAlpha = 19, 73 ConfigmenuFocusedAlpha = 19,
74 ConfigmenuUnfocusedAlpha = 20, 74 ConfigmenuUnfocusedAlpha = 20,
75 ConfigmenuExternalTabs = 21, 75 ConfigmenuTabMenu = 21,
76 ConfigmenuTabsInTitlebar = 22,
76 77
77 EwmhSet = 5, 78 EwmhSet = 5,
78 EwmhOutOfMemoryClientList = 1, 79 EwmhOutOfMemoryClientList = 1,
diff --git a/src/Container.cc b/src/Container.cc
index 9cef92c..76d8d52 100644
--- a/src/Container.cc
+++ b/src/Container.cc
@@ -264,10 +264,16 @@ void Container::setMaxSizePerClient(unsigned int size) {
264} 264}
265 265
266void Container::setMaxTotalSize(unsigned int size) { 266void Container::setMaxTotalSize(unsigned int size) {
267 if (m_max_total_size == size)
268 return;
269
270 unsigned int old = m_max_total_size;
267 m_max_total_size = size; 271 m_max_total_size = size;
268 272
269 if (m_max_total_size && width() > m_max_total_size) { 273 if (m_max_total_size && width() > m_max_total_size) {
270 resize(m_max_total_size, height()); 274 resize(m_max_total_size, height());
275 } else if (!m_max_total_size && old) { // going from restricted to unrestricted
276 repositionItems();
271 } else { 277 } else {
272 // this is a bit of duplication from repositionItems 278 // this is a bit of duplication from repositionItems
273 // for when we are allowed to grow ourself 279 // for when we are allowed to grow ourself
@@ -286,7 +292,6 @@ void Container::setMaxTotalSize(unsigned int size) {
286 if (preferred_width != width()) 292 if (preferred_width != width())
287 repositionItems(); 293 repositionItems();
288 } 294 }
289
290 } 295 }
291} 296}
292 297
@@ -381,7 +386,10 @@ void Container::repositionItems() {
381 } 386 }
382 if (total_width != width()) { 387 if (total_width != width()) {
383 // calling Container::resize here risks infinite loops 388 // calling Container::resize here risks infinite loops
384 FbTk::FbWindow::resize(total_width, height()); 389 if (align == RIGHT)
390 FbTk::FbWindow::moveResize(x() - (total_width - width()), y(), total_width, height());
391 else
392 FbTk::FbWindow::resize(total_width, height());
385 } 393 }
386 } 394 }
387 395
@@ -396,7 +404,7 @@ void Container::repositionItems() {
396 int direction = 1; 404 int direction = 1;
397 if (align == RIGHT) { 405 if (align == RIGHT) {
398 direction = -1; 406 direction = -1;
399 next_x = total_width - max_width_per_client + borderW; 407 next_x = total_width - max_width_per_client - borderW;
400 } 408 }
401 409
402 for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) { 410 for (; it != it_end; ++it, next_x += direction*(max_width_per_client + borderW + extra)) {
diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc
index ec74f4b..5ccfe12 100644
--- a/src/FbWinFrame.cc
+++ b/src/FbWinFrame.cc
@@ -80,6 +80,7 @@ FbWinFrame::FbWinFrame(BScreen &screen, FbWinFrameTheme &theme, FbTk::ImageContr
80 EnterWindowMask | LeaveWindowMask), 80 EnterWindowMask | LeaveWindowMask),
81 m_bevel(1), 81 m_bevel(1),
82 m_use_titlebar(true), 82 m_use_titlebar(true),
83 m_tabplacement(BOTTOMRIGHT),
83 m_use_tabs(true), 84 m_use_tabs(true),
84 m_use_handle(true), 85 m_use_handle(true),
85 m_focused(false), 86 m_focused(false),
@@ -126,9 +127,11 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
126 if (tabmode == NOTSET) 127 if (tabmode == NOTSET)
127 tabmode = m_tabmode; 128 tabmode = m_tabmode;
128 129
130 m_tabmode = tabmode;
131
129 // reparent tab container 132 // reparent tab container
130 if (tabmode == EXTERNAL) { 133 if (tabmode == EXTERNAL) {
131 134 m_label.show();
132 m_tab_container.setBorderWidth(m_window.borderWidth()); 135 m_tab_container.setBorderWidth(m_window.borderWidth());
133 m_tab_container.setBorderColor(theme().border().color()); 136 m_tab_container.setBorderColor(theme().border().color());
134 m_tab_container.setEventMask( 137 m_tab_container.setEventMask(
@@ -141,15 +144,35 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
141 GrabModeSync, GrabModeSync, None, None); 144 GrabModeSync, GrabModeSync, None, None);
142 XUngrabButton(m_tab_container.display(), Button1, Mod1Mask|Mod2Mask|Mod3Mask, m_tab_container.window()); 145 XUngrabButton(m_tab_container.display(), Button1, Mod1Mask|Mod2Mask|Mod3Mask, m_tab_container.window());
143 146
147 int tabx, taby;
148 switch (m_tabplacement) {
149 case TOPLEFT:
150 m_tab_container.setAlignment(Container::LEFT);
151 tabx = x();
152 taby = y() - yOffset();
153 break;
154 case TOPRIGHT:
155 m_tab_container.setAlignment(Container::RIGHT);
156 tabx = x() + width() - m_tab_container.width();
157 taby = y() - yOffset();
158 break;
159 case BOTTOMLEFT:
160 m_tab_container.setAlignment(Container::LEFT);
161 tabx = x();
162 taby = y() + height() + m_window.borderWidth();
163 break;
164 case BOTTOMRIGHT:
165 m_tab_container.setAlignment(Container::RIGHT);
166 tabx = x() + width() - m_tab_container.width();
167 taby = y() + height() + m_window.borderWidth();
168 break;
169 }
170
144 if (m_tab_container.parent()->window() != m_screen.rootWindow().window()) { 171 if (m_tab_container.parent()->window() != m_screen.rootWindow().window()) {
145 int tabx = x();
146 // one borderwidth only, so the adjacent borders overlab
147 int taby = y() - m_tab_container.height() - m_tab_container.borderWidth();
148 m_tab_container.reparent(m_screen.rootWindow(), tabx, taby); 172 m_tab_container.reparent(m_screen.rootWindow(), tabx, taby);
149 m_layeritem.addWindow(m_tab_container); 173 m_layeritem.addWindow(m_tab_container);
150 } 174 }
151 175
152 m_tab_container.setAlignment(Container::LEFT);
153 m_tab_container.setMaxSizePerClient(64); //!!TODO make this a setting 176 m_tab_container.setMaxSizePerClient(64); //!!TODO make this a setting
154 m_tab_container.setMaxTotalSize(window().width()); 177 m_tab_container.setMaxTotalSize(window().width());
155 178
@@ -162,23 +185,24 @@ bool FbWinFrame::setTabMode(TabMode tabmode) {
162 } 185 }
163 186
164 } else { 187 } else {
188 m_tab_container.setAlignment(Container::RELATIVE);
165 if (m_tab_container.parent()->window() == m_screen.rootWindow().window()) { 189 if (m_tab_container.parent()->window() == m_screen.rootWindow().window()) {
166 m_layeritem.removeWindow(m_tab_container); 190 m_layeritem.removeWindow(m_tab_container);
167 m_tab_container.reparent(m_titlebar, m_label.x(), m_label.y()); 191 m_tab_container.reparent(m_titlebar, m_label.x(), m_label.y());
192 m_tab_container.resize(m_label.width(), m_label.height());
168 m_tab_container.raise(); 193 m_tab_container.raise();
169 } 194 }
170 m_tab_container.setBorderWidth(0); 195 m_tab_container.setBorderWidth(0);
171 m_tab_container.setMaxTotalSize(0); 196 m_tab_container.setMaxTotalSize(0);
172 m_tab_container.setMaxSizePerClient(0); 197 m_tab_container.setMaxSizePerClient(0);
173 m_tab_container.setAlignment(Container::RELATIVE);
174 if (!m_use_tabs) 198 if (!m_use_tabs)
175 m_tab_container.show(); 199 m_tab_container.show();
176 else 200 else
177 ret = false; 201 ret = false;
202 m_label.hide();
178// reconfigure(); 203// reconfigure();
179 } 204 }
180 205
181 m_tabmode = tabmode;
182 return true; 206 return true;
183} 207}
184 208
@@ -286,7 +310,7 @@ void FbWinFrame::moveResize(int x, int y, unsigned int width, unsigned int heigh
286 m_window.resize(width, height); 310 m_window.resize(width, height);
287 } 311 }
288 312
289 if (move) 313 if (move || resize && m_tabplacement != TOPLEFT)
290 alignTabs(); 314 alignTabs();
291 315
292 if (resize) { 316 if (resize) {
@@ -306,8 +330,30 @@ void FbWinFrame::quietMoveResize(int x, int y,
306} 330}
307 331
308void FbWinFrame::alignTabs() { 332void FbWinFrame::alignTabs() {
309 if (m_tabmode == EXTERNAL) 333 if (m_tabmode != EXTERNAL)
310 m_tab_container.move(m_window.x(), m_window.y() - m_tab_container.height() - m_tab_container.borderWidth()); 334 return;
335
336 int tabx = 0, taby = 0;
337 switch (m_tabplacement) {
338 case TOPLEFT:
339 tabx = x();
340 taby = y() - yOffset();
341 break;
342 case TOPRIGHT:
343 tabx = x() + width() - m_tab_container.width();
344 taby = y() - yOffset();
345 break;
346 case BOTTOMLEFT:
347 tabx = x();
348 taby = y() + height() + m_window.borderWidth();
349 break;
350 case BOTTOMRIGHT:
351 tabx = x() + width() - m_tab_container.width();
352 taby = y() + height() + m_window.borderWidth();
353 break;
354 }
355
356 m_tab_container.move(tabx, taby);
311} 357}
312 358
313void FbWinFrame::notifyMoved(bool clear) { 359void FbWinFrame::notifyMoved(bool clear) {
@@ -1077,6 +1123,9 @@ void FbWinFrame::applyTitlebar() {
1077 m_titlebar.setAlpha(alpha); 1123 m_titlebar.setAlpha(alpha);
1078 m_label.setAlpha(alpha); 1124 m_label.setAlpha(alpha);
1079 1125
1126 if (externalTabMode())
1127 m_label.setGC(m_focused?theme().labelTextFocusGC():theme().labelTextUnfocusGC());
1128
1080 if (label_pm != 0) 1129 if (label_pm != 0)
1081 m_label.setBackgroundPixmap(label_pm); 1130 m_label.setBackgroundPixmap(label_pm);
1082 else 1131 else
@@ -1398,6 +1447,7 @@ void FbWinFrame::applyFocusLabel(FbTk::TextButton &button) {
1398} 1447}
1399 1448
1400void FbWinFrame::applyActiveLabel(FbTk::TextButton &button) { 1449void FbWinFrame::applyActiveLabel(FbTk::TextButton &button) {
1450
1401 button.setBorderWidth(1); 1451 button.setBorderWidth(1);
1402 button.setGC(theme().labelTextActiveGC()); 1452 button.setGC(theme().labelTextActiveGC());
1403 button.setJustify(theme().justify()); 1453 button.setJustify(theme().justify());
@@ -1544,16 +1594,26 @@ void FbWinFrame::gravityTranslate(int &x, int &y, unsigned int width, unsigned i
1544} 1594}
1545 1595
1546int FbWinFrame::heightOffset() const { 1596int FbWinFrame::heightOffset() const {
1547 if (m_tabmode == EXTERNAL && m_use_tabs) 1597 if (m_tabmode != EXTERNAL || !m_use_tabs)
1548 return m_tab_container.height() + m_window.borderWidth();
1549 else
1550 return 0; 1598 return 0;
1599
1600 // same height offset for top and bottom tabs
1601 return m_tab_container.height() + m_window.borderWidth();
1551} 1602}
1552 1603
1553int FbWinFrame::yOffset() const { 1604int FbWinFrame::yOffset() const {
1554 if (m_tabmode == EXTERNAL && m_use_tabs) 1605 if (m_tabmode != EXTERNAL || !m_use_tabs)
1606 return 0;
1607
1608 switch (m_tabplacement) {
1609 case TOPLEFT:
1610 case TOPRIGHT:
1555 return m_tab_container.height() + m_window.borderWidth(); 1611 return m_tab_container.height() + m_window.borderWidth();
1556 else 1612 break;
1613 case BOTTOMLEFT:
1614 case BOTTOMRIGHT:
1557 return 0; 1615 return 0;
1616 break;
1617 }
1558} 1618}
1559 1619
diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh
index 5b6b287..10cd98f 100644
--- a/src/FbWinFrame.hh
+++ b/src/FbWinFrame.hh
@@ -59,6 +59,17 @@ public:
59 // STRICTINTERNAL means it doesn't go external automatically when no titlebar 59 // STRICTINTERNAL means it doesn't go external automatically when no titlebar
60 enum TabMode { NOTSET = 0, INTERNAL = 1, EXTERNAL }; 60 enum TabMode { NOTSET = 0, INTERNAL = 1, EXTERNAL };
61 61
62 /// Toolbar placement on the screen
63 enum TabPlacement{
64 // top and bottom placement
65 TOPLEFT = 1, BOTTOMLEFT,
66 TOPRIGHT, BOTTOMRIGHT
67 // left and right placement
68// LEFTBOTTOM, LEFTTOP,
69// RIGHTBOTTOM, RIGHTTOP
70 };
71
72
62 typedef FbTk::TextButton *ButtonId; ///< defines a button id 73 typedef FbTk::TextButton *ButtonId; ///< defines a button id
63 74
64 /// create a top level window 75 /// create a top level window
@@ -114,6 +125,7 @@ public:
114 inline void setFocusTitle(const std::string &str) { m_label.setText(str); } 125 inline void setFocusTitle(const std::string &str) { m_label.setText(str); }
115 void setDoubleClickTime(unsigned int time); 126 void setDoubleClickTime(unsigned int time);
116 bool setTabMode(TabMode tabmode); 127 bool setTabMode(TabMode tabmode);
128 inline void setTabPlacement(TabPlacement tabplacement) { m_tabplacement = tabplacement; alignTabs(); }
117 129
118 /// add a button to the left of the label 130 /// add a button to the left of the label
119 void addLeftButton(FbTk::Button *btn); 131 void addLeftButton(FbTk::Button *btn);
@@ -222,7 +234,7 @@ public:
222 unsigned int titlebarHeight() const { return m_titlebar.height(); } 234 unsigned int titlebarHeight() const { return m_titlebar.height(); }
223 /// @return size of button 235 /// @return size of button
224 unsigned int buttonHeight() const; 236 unsigned int buttonHeight() const;
225 bool externalTabMode() const { return m_tabmode == EXTERNAL; } 237 bool externalTabMode() const { return m_tabmode == EXTERNAL && m_use_tabs; }
226 238
227 inline const FbTk::XLayerItem &layerItem() const { return m_layeritem; } 239 inline const FbTk::XLayerItem &layerItem() const { return m_layeritem; }
228 inline FbTk::XLayerItem &layerItem() { return m_layeritem; } 240 inline FbTk::XLayerItem &layerItem() { return m_layeritem; }
@@ -355,6 +367,7 @@ private:
355 //@} 367 //@}
356 368
357 TabMode m_tabmode; 369 TabMode m_tabmode;
370 TabPlacement m_tabplacement;
358 371
359 bool m_need_render; 372 bool m_need_render;
360 int m_button_size; ///< size for all titlebar buttons 373 int m_button_size; ///< size for all titlebar buttons
diff --git a/src/Screen.cc b/src/Screen.cc
index 464b41f..851e407 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -156,9 +156,93 @@ int anotherWMRunning(Display *display, XErrorEvent *) {
156} 156}
157 157
158 158
159class TabPlacementMenuItem: public FbTk::MenuItem {
160public:
161 TabPlacementMenuItem(const char * label, BScreen &screen, FbWinFrame::TabPlacement place, FbTk::RefCount<FbTk::Command> &cmd):
162 FbTk::MenuItem(label, cmd),
163 m_screen(screen),
164 m_place(place) { }
165
166 bool isEnabled() const { return m_screen.getTabPlacement() != m_place; }
167 void click(int button, int time) {
168 m_screen.saveTabPlacement(m_place);
169 FbTk::MenuItem::click(button, time);
170 }
171
172
173private:
174 BScreen &m_screen;
175 FbWinFrame::TabPlacement m_place;
176};
159 177
160} // end anonymous namespace 178} // end anonymous namespace
161 179
180
181
182namespace FbTk {
183
184template<>
185void FbTk::Resource<FbWinFrame::TabPlacement>::
186setFromString(const char *strval) {
187 if (strcasecmp(strval, "TopLeft")==0)
188 m_value = FbWinFrame::TOPLEFT;
189 else if (strcasecmp(strval, "BottomLeft")==0)
190 m_value = FbWinFrame::BOTTOMLEFT;
191 else if (strcasecmp(strval, "TopRight")==0)
192 m_value = FbWinFrame::TOPRIGHT;
193 else if (strcasecmp(strval, "BottomRight")==0)
194 m_value = FbWinFrame::BOTTOMRIGHT;
195 /*
196 else if (strcasecmp(strval, "LeftTop") == 0)
197 m_value = FbWinFrame::LEFTTOP;
198 else if (strcasecmp(strval, "LeftBottom") == 0)
199 m_value = FbWinFrame::LEFTBOTTOM;
200 else if (strcasecmp(strval, "RightTop") == 0)
201 m_value = FbWinFrame::RIGHTTOP;
202 else if (strcasecmp(strval, "RightBottom") == 0)
203 m_value = FbWinFrame::RIGHTBOTTOM;
204 */
205 else
206 setDefaultValue();
207}
208
209template<>
210string FbTk::Resource<FbWinFrame::TabPlacement>::
211getString() const {
212 switch (m_value) {
213 case FbWinFrame::TOPLEFT:
214 return string("TopLeft");
215 break;
216 case FbWinFrame::BOTTOMLEFT:
217 return string("BottomLeft");
218 break;
219 case FbWinFrame::TOPRIGHT:
220 return string("TopRight");
221 break;
222 case FbWinFrame::BOTTOMRIGHT:
223 return string("BottomRight");
224 break;
225/*
226 case FbWinFrame::LEFTTOP:
227 return string("LeftTop");
228 break;
229 case FbWinFrame::LEFTBOTTOM:
230 return string("LeftBottom");
231 break;
232 case FbWinFrame::RIGHTTOP:
233 return string("RightTop");
234 break;
235 case FbWinFrame::RIGHTBOTTOM:
236 return string("RightBottom");
237 break;
238*/
239 }
240 //default string
241 return string("TopLeft");
242}
243} // end namespace FbTk
244
245
162BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm, 246BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
163 const std::string &scrname, 247 const std::string &scrname,
164 const std::string &altscrname): 248 const std::string &altscrname):
@@ -176,6 +260,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
176 decorate_transient(rm, false, scrname+".decorateTransient", altscrname+".DecorateTransient"), 260 decorate_transient(rm, false, scrname+".decorateTransient", altscrname+".DecorateTransient"),
177 rootcommand(rm, "", scrname+".rootCommand", altscrname+".RootCommand"), 261 rootcommand(rm, "", scrname+".rootCommand", altscrname+".RootCommand"),
178 resize_model(rm, BOTTOMRESIZE, scrname+".resizeMode", altscrname+".ResizeMode"), 262 resize_model(rm, BOTTOMRESIZE, scrname+".resizeMode", altscrname+".ResizeMode"),
263 tab_placement(rm, FbWinFrame::TOPLEFT, scrname+".tab.placement", altscrname+".Tab.Placement"),
179 windowmenufile(rm, "", scrname+".windowMenu", altscrname+".WindowMenu"), 264 windowmenufile(rm, "", scrname+".windowMenu", altscrname+".WindowMenu"),
180 follow_model(rm, IGNORE_OTHER_WORKSPACES, scrname+".followModel", altscrname+".followModel"), 265 follow_model(rm, IGNORE_OTHER_WORKSPACES, scrname+".followModel", altscrname+".followModel"),
181 workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"), 266 workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"),
@@ -202,7 +287,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
202 altscrname+".overlay.CapStyle"), 287 altscrname+".overlay.CapStyle"),
203 scroll_action(rm, "", scrname+".windowScrollAction", altscrname+".WindowScrollAction"), 288 scroll_action(rm, "", scrname+".windowScrollAction", altscrname+".WindowScrollAction"),
204 scroll_reverse(rm, false, scrname+".windowScrollReverse", altscrname+".WindowScrollReverse"), 289 scroll_reverse(rm, false, scrname+".windowScrollReverse", altscrname+".WindowScrollReverse"),
205 default_external_tabs(rm, false /* TODO: autoconf option? */ , scrname+".externalTabs", altscrname+".ExternalTabs") { 290 default_internal_tabs(rm, false /* TODO: autoconf option? */ , scrname+".tabs.intitlebar", altscrname+".Tabs.InTitlebar") {
206 291
207 292
208} 293}
@@ -330,7 +415,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
330 } 415 }
331 416
332 m_current_workspace = m_workspaces_list.front(); 417 m_current_workspace = m_workspaces_list.front();
333 418
334 419
335 //!! TODO: we shouldn't do this more than once, but since slit handles their 420 //!! TODO: we shouldn't do this more than once, but since slit handles their
336 // own resources we must do this. 421 // own resources we must do this.
@@ -626,6 +711,15 @@ FbTk::Menu *BScreen::createMenu(const std::string &label) {
626 711
627 return menu; 712 return menu;
628} 713}
714FbTk::Menu *BScreen::createToggleMenu(const std::string &label) {
715 FbTk::Menu *menu = new ToggleMenu(menuTheme(),
716 imageControl(),
717 *layerManager().getLayer(Layer::MENU));
718 if (!label.empty())
719 menu->setLabel(label.c_str());
720
721 return menu;
722}
629 723
630void BScreen::addExtraWindowMenu(const char *label, FbTk::Menu *menu) { 724void BScreen::addExtraWindowMenu(const char *label, FbTk::Menu *menu) {
631 menu->setInternalMenu(); 725 menu->setInternalMenu();
@@ -794,6 +888,26 @@ void BScreen::reconfigure() {
794 FbTk::ThemeManager::instance().load(fluxbox->getStyleFilename(), 888 FbTk::ThemeManager::instance().load(fluxbox->getStyleFilename(),
795 fluxbox->getStyleOverlayFilename(), 889 fluxbox->getStyleOverlayFilename(),
796 m_root_theme->screenNum()); 890 m_root_theme->screenNum());
891
892 reconfigureTabs();
893}
894
895void BScreen::reconfigureTabs() {
896 Workspaces::iterator w_it = getWorkspacesList().begin();
897 const Workspaces::iterator w_it_end = getWorkspacesList().end();
898 for (; w_it != w_it_end; ++w_it) {
899 if ((*w_it)->windowList().size()) {
900 Workspace::Windows::iterator win_it = (*w_it)->windowList().begin();
901 const Workspace::Windows::iterator win_it_end = (*w_it)->windowList().end();
902 for (; win_it != win_it_end; ++win_it) {
903 (*win_it)->frame().setTabPlacement(*resource.tab_placement);
904 if (*resource.default_internal_tabs)
905 (*win_it)->frame().setTabMode(FbWinFrame::INTERNAL);
906 else
907 (*win_it)->frame().setTabMode(FbWinFrame::EXTERNAL);
908 }
909 }
910 }
797} 911}
798 912
799 913
@@ -1454,12 +1568,21 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1454 menu.removeAll(); 1568 menu.removeAll();
1455 1569
1456 FbTk::MacroCommand *s_a_reconf_macro = new FbTk::MacroCommand(); 1570 FbTk::MacroCommand *s_a_reconf_macro = new FbTk::MacroCommand();
1457 FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(*Fluxbox::instance(), 1571 FbTk::MacroCommand *s_a_reconftabs_macro = new FbTk::MacroCommand();
1458 &Fluxbox::save_rc)); 1572 FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
1573 *Fluxbox::instance(),
1574 &Fluxbox::save_rc));
1459 FbTk::RefCount<FbTk::Command> reconf_cmd(CommandParser::instance().parseLine("reconfigure")); 1575 FbTk::RefCount<FbTk::Command> reconf_cmd(CommandParser::instance().parseLine("reconfigure"));
1576
1577 FbTk::RefCount<FbTk::Command> reconftabs_cmd(new FbTk::SimpleCommand<BScreen>(
1578 *this,
1579 &BScreen::reconfigureTabs));
1460 s_a_reconf_macro->add(saverc_cmd); 1580 s_a_reconf_macro->add(saverc_cmd);
1461 s_a_reconf_macro->add(reconf_cmd); 1581 s_a_reconf_macro->add(reconf_cmd);
1582 s_a_reconftabs_macro->add(saverc_cmd);
1583 s_a_reconftabs_macro->add(reconftabs_cmd);
1462 FbTk::RefCount<FbTk::Command> save_and_reconfigure(s_a_reconf_macro); 1584 FbTk::RefCount<FbTk::Command> save_and_reconfigure(s_a_reconf_macro);
1585 FbTk::RefCount<FbTk::Command> save_and_reconftabs(s_a_reconftabs_macro);
1463 // create focus menu 1586 // create focus menu
1464 // we don't set this to internal menu so will 1587 // we don't set this to internal menu so will
1465 // be deleted toghether with the parent 1588 // be deleted toghether with the parent
@@ -1468,6 +1591,9 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1468 "Method used to give focus to windows"); 1591 "Method used to give focus to windows");
1469 FbTk::Menu *focus_menu = createMenu(focusmenu_label ? focusmenu_label : ""); 1592 FbTk::Menu *focus_menu = createMenu(focusmenu_label ? focusmenu_label : "");
1470 1593
1594#define _BOOLITEM(m,a, b, c, d, e, f) (m).insert(new BoolMenuItem(_FBTEXT(a, b, c, d), e, f))
1595
1596
1471#define _FOCUSITEM(a, b, c, d, e) \ 1597#define _FOCUSITEM(a, b, c, d, e) \
1472 focus_menu->insert(new FocusModelMenuItem(_FBTEXT(a, b, c, d), focusControl(), \ 1598 focus_menu->insert(new FocusModelMenuItem(_FBTEXT(a, b, c, d), focusControl(), \
1473 e, save_and_reconfigure)) 1599 e, save_and_reconfigure))
@@ -1498,6 +1624,84 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1498 focus_menu->updateMenu(); 1624 focus_menu->updateMenu();
1499 1625
1500 menu.insert(focusmenu_label, focus_menu); 1626 menu.insert(focusmenu_label, focus_menu);
1627
1628 // END focus menu
1629
1630 // BEGIN tab menu
1631
1632 const char *tabmenu_label = _FBTEXT(Configmenu, TabMenu,
1633 "Tab Options",
1634 "heading for tab-related options");
1635 FbTk::Menu *tab_menu = createMenu(tabmenu_label ? tabmenu_label : "");
1636 const char *tabplacement_label = _FBTEXT(Menu, Placement, "Placement", "Title of Placement menu");
1637 FbTk::Menu *tabplacement_menu = createToggleMenu(tabplacement_label);
1638
1639 tab_menu->insert(tabplacement_label, tabplacement_menu);
1640
1641 _BOOLITEM(*tab_menu,Configmenu, TabsInTitlebar,
1642 "Tabs in Titlebar", "Tabs in Titlebar",
1643 *resource.default_internal_tabs, save_and_reconftabs);
1644
1645 typedef pair<const char*, FbWinFrame::TabPlacement> PlacementP;
1646 typedef list<PlacementP> Placements;
1647 Placements place_menu;
1648
1649 // menu is 3 wide, 5 down
1650 place_menu.push_back(PlacementP(_FBTEXT(Align, TopLeft, "Top Left", "Top Left"), FbWinFrame::TOPLEFT));
1651 place_menu.push_back(PlacementP(_FBTEXT(Align, BottomLeft, "Bottom Left", "Bottom Left"), FbWinFrame::BOTTOMLEFT));
1652 place_menu.push_back(PlacementP(_FBTEXT(Align, TopRight, "Top Right", "Top Right"), FbWinFrame::TOPRIGHT));
1653 place_menu.push_back(PlacementP(_FBTEXT(Align, BottomRight, "Bottom Right", "Bottom Right"), FbWinFrame::BOTTOMRIGHT));
1654
1655/*
1656 place_menu.push_back(PlacementP(_FBTEXT(Align, LeftTop, "Left Top", "Left Top"), FbWinFrame::LEFTTOP));
1657 place_menu.push_back(PlacementP(_FBTEXT(Align, LeftBottom, "Left Bottom", "Left Bottom"), FbWinFrame::LEFTBOTTOM));
1658 place_menu.push_back(PlacementP(_FBTEXT(Align, RightTop, "Right Top", "Right Top"), FbWinFrame::RIGHTTOP));
1659 place_menu.push_back(PlacementP(_FBTEXT(Align, RightBottom, "Right Bottom", "Right Bottom"), FbWinFrame::RIGHTBOTTOM));
1660*/
1661
1662 tabplacement_menu->setMinimumSublevels(2);
1663 // create items in sub menu
1664 size_t i=0;
1665 while (!place_menu.empty()) {
1666 i++;
1667 const char *str = place_menu.front().first;
1668 FbWinFrame::TabPlacement placement = place_menu.front().second;
1669
1670 if (str == 0) {
1671 tabplacement_menu->insert("");
1672 tabplacement_menu->setItemEnabled(i, false);
1673 } else {
1674 tabplacement_menu->insert(new TabPlacementMenuItem(str, *this, placement, save_and_reconftabs));
1675 }
1676 place_menu.pop_front();
1677 }
1678 tabplacement_menu->updateMenu();
1679
1680 menu.insert(tabmenu_label, tab_menu);
1681
1682#undef _FOCUSITEM
1683
1684 focus_menu->insert(new TabFocusModelMenuItem("ClickTabFocus", focusControl(),
1685 FocusControl::CLICKTABFOCUS,
1686 save_and_reconfigure));
1687 focus_menu->insert(new TabFocusModelMenuItem("MouseTabFocus", focusControl(),
1688 FocusControl::MOUSETABFOCUS,
1689 save_and_reconfigure));
1690
1691
1692 focus_menu->insert(new BoolMenuItem(_FBTEXT(Configmenu,
1693 AutoRaise,
1694 "Auto Raise",
1695 "Auto Raise windows on sloppy"),
1696 *resource.auto_raise,
1697 save_and_reconfigure));
1698
1699 focus_menu->updateMenu();
1700
1701 menu.insert(focusmenu_label, focus_menu);
1702
1703 // end tab menu
1704
1501#ifdef SLIT 1705#ifdef SLIT
1502 if (slit() != 0) { 1706 if (slit() != 0) {
1503 slit()->menu().setInternalMenu(); 1707 slit()->menu().setInternalMenu();
@@ -1510,20 +1714,18 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1510 for (; it != it_end; ++it) 1714 for (; it != it_end; ++it)
1511 menu.insert(it->first, it->second); 1715 menu.insert(it->first, it->second);
1512 1716
1513#define _BOOLITEM(a, b, c, d, e, f) menu.insert(new BoolMenuItem(_FBTEXT(a, b, c, d), e, f)) 1717 _BOOLITEM(menu, Configmenu, ImageDithering,
1514
1515 _BOOLITEM(Configmenu, ImageDithering,
1516 "Image Dithering", "Image Dithering", 1718 "Image Dithering", "Image Dithering",
1517 *resource.image_dither, save_and_reconfigure); 1719 *resource.image_dither, save_and_reconfigure);
1518 _BOOLITEM(Configmenu, OpaqueMove, 1720 _BOOLITEM(menu, Configmenu, OpaqueMove,
1519 "Opaque Window Moving", 1721 "Opaque Window Moving",
1520 "Window Moving with whole window visible (as opposed to outline moving)", 1722 "Window Moving with whole window visible (as opposed to outline moving)",
1521 *resource.opaque_move, saverc_cmd); 1723 *resource.opaque_move, saverc_cmd);
1522 _BOOLITEM(Configmenu, FullMax, 1724 _BOOLITEM(menu, Configmenu, FullMax,
1523 "Full Maximization", "Maximise over slit, toolbar, etc", 1725 "Full Maximization", "Maximise over slit, toolbar, etc",
1524 *resource.full_max, saverc_cmd); 1726 *resource.full_max, saverc_cmd);
1525 try { 1727 try {
1526 _BOOLITEM(Configmenu, FocusNew, 1728 _BOOLITEM(menu, Configmenu, FocusNew,
1527 "Focus New Windows", "Focus newly created windows", 1729 "Focus New Windows", "Focus newly created windows",
1528 *m_resource_manager.getResource<bool>(name() + ".focusNewWindows"), 1730 *m_resource_manager.getResource<bool>(name() + ".focusNewWindows"),
1529 saverc_cmd); 1731 saverc_cmd);
@@ -1532,7 +1734,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1532 } 1734 }
1533 1735
1534 try { 1736 try {
1535 _BOOLITEM(Configmenu, FocusLast, 1737 _BOOLITEM(menu, Configmenu, FocusLast,
1536 "Focus Last Window on Workspace", "Focus Last Window on Workspace", 1738 "Focus Last Window on Workspace", "Focus Last Window on Workspace",
1537 *resourceManager().getResource<bool>(name() + ".focusLastWindow"), 1739 *resourceManager().getResource<bool>(name() + ".focusLastWindow"),
1538 saverc_cmd); 1740 saverc_cmd);
@@ -1540,20 +1742,17 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
1540 cerr<<e.what()<<endl; 1742 cerr<<e.what()<<endl;
1541 } 1743 }
1542 1744
1543 _BOOLITEM(Configmenu, WorkspaceWarping, 1745 _BOOLITEM(menu, Configmenu, WorkspaceWarping,
1544 "Workspace Warping", 1746 "Workspace Warping",
1545 "Workspace Warping - dragging windows to the edge and onto the next workspace", 1747 "Workspace Warping - dragging windows to the edge and onto the next workspace",
1546 *resource.workspace_warping, saverc_cmd); 1748 *resource.workspace_warping, saverc_cmd);
1547 _BOOLITEM(Configmenu, DesktopWheeling, 1749 _BOOLITEM(menu, Configmenu, DesktopWheeling,
1548 "Desktop MouseWheel Switching", "Workspace switching using mouse wheel", 1750 "Desktop MouseWheel Switching", "Workspace switching using mouse wheel",
1549 *resource.desktop_wheeling, saverc_cmd); 1751 *resource.desktop_wheeling, saverc_cmd);
1550 _BOOLITEM(Configmenu, DecorateTransient, 1752 _BOOLITEM(menu, Configmenu, DecorateTransient,
1551 "Decorate Transient Windows", "Decorate Transient Windows", 1753 "Decorate Transient Windows", "Decorate Transient Windows",
1552 *resource.decorate_transient, saverc_cmd); 1754 *resource.decorate_transient, saverc_cmd);
1553 _BOOLITEM(Configmenu, ExternalTabs, 1755 _BOOLITEM(menu, Configmenu, ClickRaises,
1554 "Use External Tabs (experimental)", "Use External Tabs (experimental)",
1555 *resource.default_external_tabs, saverc_cmd);
1556 _BOOLITEM(Configmenu, ClickRaises,
1557 "Click Raises", "Click Raises", 1756 "Click Raises", "Click Raises",
1558 *resource.click_raises, saverc_cmd); 1757 *resource.click_raises, saverc_cmd);
1559 1758
diff --git a/src/Screen.hh b/src/Screen.hh
index 9fcff11..738fe1a 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -27,7 +27,7 @@
27#ifndef SCREEN_HH 27#ifndef SCREEN_HH
28#define SCREEN_HH 28#define SCREEN_HH
29 29
30 30#include "FbWinFrame.hh"
31#include "FbRootWindow.hh" 31#include "FbRootWindow.hh"
32#include "MenuTheme.hh" 32#include "MenuTheme.hh"
33#include "PlacementStrategy.hh" 33#include "PlacementStrategy.hh"
@@ -132,13 +132,15 @@ public:
132 ExtraMenus &extraWindowMenus() { return m_extramenus; } 132 ExtraMenus &extraWindowMenus() { return m_extramenus; }
133 const ExtraMenus &extraWindowMenus() const { return m_extramenus; } 133 const ExtraMenus &extraWindowMenus() const { return m_extramenus; }
134 134
135 FbWinFrame::TabPlacement getTabPlacement() const { return *resource.tab_placement; }
136
135 ResizeModel getResizeModel() const { return *resource.resize_model; } 137 ResizeModel getResizeModel() const { return *resource.resize_model; }
136 138
137 inline FollowModel getFollowModel() const { return *resource.follow_model; } 139 inline FollowModel getFollowModel() const { return *resource.follow_model; }
138 140
139 inline const std::string &getScrollAction() const { return *resource.scroll_action; } 141 inline const std::string &getScrollAction() const { return *resource.scroll_action; }
140 inline const bool getScrollReverse() const { return *resource.scroll_reverse; } 142 inline const bool getScrollReverse() const { return *resource.scroll_reverse; }
141 inline const bool getDefaultExternalTabs() const { return *resource.default_external_tabs; } 143 inline const bool getDefaultInternalTabs() const { return *resource.default_internal_tabs; }
142 144
143 inline Slit *slit() { return m_slit.get(); } 145 inline Slit *slit() { return m_slit.get(); }
144 inline const Slit *slit() const { return m_slit.get(); } 146 inline const Slit *slit() const { return m_slit.get(); }
@@ -203,6 +205,7 @@ public:
203 void update(FbTk::Subject *subj); 205 void update(FbTk::Subject *subj);
204 206
205 FbTk::Menu *createMenu(const std::string &label); 207 FbTk::Menu *createMenu(const std::string &label);
208 FbTk::Menu *createToggleMenu(const std::string &label);
206 void hideMenus(); 209 void hideMenus();
207 // for extras to add menus. 210 // for extras to add menus.
208 // These menus will be marked internal, 211 // These menus will be marked internal,
@@ -218,6 +221,8 @@ public:
218 void setRootColormapInstalled(bool r) { root_colormap_installed = r; } 221 void setRootColormapInstalled(bool r) { root_colormap_installed = r; }
219 void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; } 222 void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; }
220 223
224 void saveTabPlacement(FbWinFrame::TabPlacement place) { *resource.tab_placement = place; }
225
221 void saveWorkspaces(int w) { *resource.workspaces = w; } 226 void saveWorkspaces(int w) { *resource.workspaces = w; }
222 227
223 void saveMenu(FbTk::Menu &menu) { m_rootmenu_list.push_back(&menu); } 228 void saveMenu(FbTk::Menu &menu) { m_rootmenu_list.push_back(&menu); }
@@ -275,6 +280,7 @@ public:
275 280
276 281
277 void reconfigure(); 282 void reconfigure();
283 void reconfigureTabs();
278 void rereadMenu(); 284 void rereadMenu();
279 void shutdown(); 285 void shutdown();
280 /// show position window centered on the screen with "X x Y" text 286 /// show position window centered on the screen with "X x Y" text
@@ -434,6 +440,7 @@ private:
434 antialias, auto_raise, click_raises, decorate_transient; 440 antialias, auto_raise, click_raises, decorate_transient;
435 FbTk::Resource<std::string> rootcommand; 441 FbTk::Resource<std::string> rootcommand;
436 FbTk::Resource<ResizeModel> resize_model; 442 FbTk::Resource<ResizeModel> resize_model;
443 FbTk::Resource<FbWinFrame::TabPlacement> tab_placement;
437 FbTk::Resource<std::string> windowmenufile; 444 FbTk::Resource<std::string> windowmenufile;
438 FbTk::Resource<FollowModel> follow_model; 445 FbTk::Resource<FollowModel> follow_model;
439 bool ordered_dither; 446 bool ordered_dither;
@@ -447,7 +454,7 @@ private:
447 FbTk::Resource<FbTk::GContext::CapStyle> gc_cap_style; 454 FbTk::Resource<FbTk::GContext::CapStyle> gc_cap_style;
448 FbTk::Resource<std::string> scroll_action; 455 FbTk::Resource<std::string> scroll_action;
449 FbTk::Resource<bool> scroll_reverse; 456 FbTk::Resource<bool> scroll_reverse;
450 FbTk::Resource<bool> default_external_tabs; 457 FbTk::Resource<bool> default_internal_tabs;
451 458
452 } resource; 459 } resource;
453 460
diff --git a/src/Window.cc b/src/Window.cc
index f28f6ab..e1cf224 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -394,10 +394,11 @@ void FluxboxWindow::init() {
394 394
395 frame().setUseShape(!m_shaped); 395 frame().setUseShape(!m_shaped);
396 396
397 if (screen().getDefaultExternalTabs()) { 397 frame().setTabPlacement(screen().getTabPlacement());
398 frame().setTabMode(FbWinFrame::EXTERNAL); 398 if (screen().getDefaultInternalTabs()) {
399 } else {
400 frame().setTabMode(FbWinFrame::INTERNAL); 399 frame().setTabMode(FbWinFrame::INTERNAL);
400 } else {
401 frame().setTabMode(FbWinFrame::EXTERNAL);
401 } 402 }
402 403
403 //!! TODO init of client should be better 404 //!! TODO init of client should be better
@@ -3049,20 +3050,28 @@ void FluxboxWindow::setDecoration(Decoration decoration, bool apply) {
3049 case DECOR_NORMAL: 3050 case DECOR_NORMAL:
3050 decorations.titlebar = decorations.border = decorations.handle = 3051 decorations.titlebar = decorations.border = decorations.handle =
3051 decorations.iconify = decorations.maximize = 3052 decorations.iconify = decorations.maximize =
3052 decorations.menu = true; 3053 decorations.menu = decorations.tab = true;
3054 functions.resize = functions.move = functions.iconify =
3055 functions.maximize = true;
3056 break;
3057
3058 case DECOR_TAB:
3059 decorations.border = decorations.iconify = decorations.maximize =
3060 decorations.menu = decorations.tab = true;
3061 decorations.titlebar = decorations.handle = false;
3053 functions.resize = functions.move = functions.iconify = 3062 functions.resize = functions.move = functions.iconify =
3054 functions.maximize = true; 3063 functions.maximize = true;
3055 break; 3064 break;
3056 3065
3057 case DECOR_TINY: 3066 case DECOR_TINY:
3058 decorations.titlebar = decorations.iconify = decorations.menu = 3067 decorations.titlebar = decorations.iconify = decorations.menu =
3059 functions.move = functions.iconify = true; 3068 functions.move = functions.iconify = decorations.tab = true;
3060 decorations.border = decorations.handle = decorations.maximize = 3069 decorations.border = decorations.handle = decorations.maximize =
3061 functions.resize = functions.maximize = false; 3070 functions.resize = functions.maximize = false;
3062 break; 3071 break;
3063 3072
3064 case DECOR_TOOL: 3073 case DECOR_TOOL:
3065 decorations.titlebar = decorations.menu = functions.move = true; 3074 decorations.titlebar = decorations.tab = decorations.menu = functions.move = true;
3066 decorations.iconify = decorations.border = decorations.handle = 3075 decorations.iconify = decorations.border = decorations.handle =
3067 decorations.maximize = functions.resize = functions.maximize = 3076 decorations.maximize = functions.resize = functions.maximize =
3068 functions.iconify = false; 3077 functions.iconify = false;
@@ -3110,7 +3119,7 @@ void FluxboxWindow::applyDecorations(bool initial) {
3110 if (decorations.titlebar) { 3119 if (decorations.titlebar) {
3111 bool change = frame().showTitlebar(); 3120 bool change = frame().showTitlebar();
3112 client_move |= change; 3121 client_move |= change;
3113 if (change && !screen().getDefaultExternalTabs()) { 3122 if (change && screen().getDefaultInternalTabs()) {
3114 client_move |= frame().setTabMode(FbWinFrame::INTERNAL); 3123 client_move |= frame().setTabMode(FbWinFrame::INTERNAL);
3115 } 3124 }
3116 } else { 3125 } else {
@@ -3357,42 +3366,56 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
3357 int right = orig_left + width() + 2 * borderW; 3366 int right = orig_left + width() + 2 * borderW;
3358 int bottom = orig_top + height() + 2 * borderW; 3367 int bottom = orig_top + height() + 2 * borderW;
3359 3368
3369 // test against tabs too
3370 bool i_have_tabs = frame().externalTabMode();
3371 int xoff,yoff,woff,hoff;
3372 if (i_have_tabs) {
3373 xoff = xOffset();
3374 yoff = yOffset();
3375 woff = widthOffset();
3376 hoff = heightOffset();
3377 }
3378
3379
3360 ///////////////////////////////////// 3380 /////////////////////////////////////
3361 // begin by checking the screen (or Xinerama head) edges 3381 // begin by checking the screen (or Xinerama head) edges
3362 3382
3363 int h; 3383 int starth = 0;
3364 if (screen().numHeads() > 0) { 3384
3365 // head "0" == whole screen width + height, which we skip since the 3385 // head "0" == whole screen width + height, which we skip since the
3366 // sum of all the heads covers those edges 3386 // sum of all the heads covers those edges, if >1 head
3367 for (h = 1; h <= screen().numHeads(); h++) { 3387 if (screen().numHeads() > 0)
3368 snapToWindow(dx, dy, left, right, top, bottom, 3388 starth=1;
3389
3390 for (int h=starth; h <= screen().numHeads(); h++) {
3391 snapToWindow(dx, dy, left, right, top, bottom,
3392 screen().maxLeft(h),
3393 screen().maxRight(h),
3394 screen().maxTop(h),
3395 screen().maxBottom(h));
3396
3397 if (i_have_tabs)
3398 snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff,
3369 screen().maxLeft(h), 3399 screen().maxLeft(h),
3370 screen().maxRight(h), 3400 screen().maxRight(h),
3371 screen().maxTop(h), 3401 screen().maxTop(h),
3372 screen().maxBottom(h)); 3402 screen().maxBottom(h));
3373 } 3403 }
3374 for (h = 1; h <= screen().numHeads(); h++) { 3404 for (int h=starth; h <= screen().numHeads(); h++) {
3375 snapToWindow(dx, dy, left, right, top, bottom, 3405 snapToWindow(dx, dy, left, right, top, bottom,
3406 screen().getHeadX(h),
3407 screen().getHeadX(h) + screen().getHeadWidth(h),
3408 screen().getHeadY(h),
3409 screen().getHeadY(h) + screen().getHeadHeight(h));
3410
3411 if (i_have_tabs)
3412 snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff,
3376 screen().getHeadX(h), 3413 screen().getHeadX(h),
3377 screen().getHeadX(h) + screen().getHeadWidth(h), 3414 screen().getHeadX(h) + screen().getHeadWidth(h),
3378 screen().getHeadY(h), 3415 screen().getHeadY(h),
3379 screen().getHeadY(h) + screen().getHeadHeight(h)); 3416 screen().getHeadY(h) + screen().getHeadHeight(h));
3380 }
3381 } else {
3382 snapToWindow(dx, dy, left, right, top, bottom,
3383 screen().maxLeft(0),
3384 screen().maxRight(0),
3385 screen().maxTop(0),
3386 screen().maxBottom(0));
3387
3388 snapToWindow(dx, dy, left, right, top, bottom,
3389 screen().getHeadX(0),
3390 screen().getHeadX(0) + screen().getHeadWidth(0),
3391 screen().getHeadY(0),
3392 screen().getHeadY(0) + screen().getHeadHeight(0));
3393 } 3417 }
3394 3418
3395
3396 ///////////////////////////////////// 3419 /////////////////////////////////////
3397 // now check window edges 3420 // now check window edges
3398 3421
@@ -3415,6 +3438,30 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
3415 (*it)->x() + (*it)->width() + 2 * bw, 3438 (*it)->x() + (*it)->width() + 2 * bw,
3416 (*it)->y(), 3439 (*it)->y(),
3417 (*it)->y() + (*it)->height() + 2 * bw); 3440 (*it)->y() + (*it)->height() + 2 * bw);
3441
3442 if (i_have_tabs)
3443 snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff,
3444 (*it)->x(),
3445 (*it)->x() + (*it)->width() + 2 * bw,
3446 (*it)->y(),
3447 (*it)->y() + (*it)->height() + 2 * bw);
3448
3449 // also snap to the box containing the tabs (don't bother with actual
3450 // tab edges, since they're dynamic
3451 if ((*it)->frame().externalTabMode())
3452 snapToWindow(dx, dy, left, right, top, bottom,
3453 (*it)->x() - (*it)->xOffset(),
3454 (*it)->x() - (*it)->xOffset() + (*it)->width() + 2 * bw + (*it)->widthOffset(),
3455 (*it)->y() - (*it)->yOffset(),
3456 (*it)->y() - (*it)->yOffset() + (*it)->height() + 2 * bw + (*it)->heightOffset());
3457
3458 if (i_have_tabs)
3459 snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff,
3460 (*it)->x() - (*it)->xOffset(),
3461 (*it)->x() - (*it)->xOffset() + (*it)->width() + 2 * bw + (*it)->widthOffset(),
3462 (*it)->y() - (*it)->yOffset(),
3463 (*it)->y() - (*it)->yOffset() + (*it)->height() + 2 * bw + (*it)->heightOffset());
3464
3418 } 3465 }
3419 3466
3420 // commit 3467 // commit
diff --git a/src/Window.hh b/src/Window.hh
index 9ad9594..44214c7 100644
--- a/src/Window.hh
+++ b/src/Window.hh
@@ -62,7 +62,8 @@ public:
62 DECOR_NONE=0, ///< no decor at all 62 DECOR_NONE=0, ///< no decor at all
63 DECOR_NORMAL, ///< normal normal 63 DECOR_NORMAL, ///< normal normal
64 DECOR_TINY, ///< tiny decoration 64 DECOR_TINY, ///< tiny decoration
65 DECOR_TOOL ///< decor tool 65 DECOR_TOOL, ///< decor tool
66 DECOR_TAB ///< decor tab (border + tab)
66 }; 67 };
67 68
68 /// Motif wm Hints 69 /// Motif wm Hints