diff options
author | simonb <simonb> | 2006-03-22 12:23:17 (GMT) |
---|---|---|
committer | simonb <simonb> | 2006-03-22 12:23:17 (GMT) |
commit | fe4a7db228d69bc9a66ed948f218ef489b2cedaf (patch) | |
tree | 5ee59c4862b04871dbd6f5112278682e4b005e47 | |
parent | da365bb4c99edf1a18e1f8db285f8c2dcee2c5e3 (diff) | |
download | fluxbox-fe4a7db228d69bc9a66ed948f218ef489b2cedaf.zip fluxbox-fe4a7db228d69bc9a66ed948f218ef489b2cedaf.tar.bz2 |
external tabs features and bugfixes
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | nls/fluxbox-nls.hh | 3 | ||||
-rw-r--r-- | src/Container.cc | 14 | ||||
-rw-r--r-- | src/FbWinFrame.cc | 90 | ||||
-rw-r--r-- | src/FbWinFrame.hh | 15 | ||||
-rw-r--r-- | src/Screen.cc | 235 | ||||
-rw-r--r-- | src/Screen.hh | 13 | ||||
-rw-r--r-- | src/Window.cc | 107 | ||||
-rw-r--r-- | src/Window.hh | 3 |
9 files changed, 417 insertions, 72 deletions
@@ -1,5 +1,14 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 0.9.16: | 2 | Changes 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 | ||
266 | void Container::setMaxTotalSize(unsigned int size) { | 266 | void 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 | ||
308 | void FbWinFrame::alignTabs() { | 332 | void 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 | ||
313 | void FbWinFrame::notifyMoved(bool clear) { | 359 | void 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 | ||
1400 | void FbWinFrame::applyActiveLabel(FbTk::TextButton &button) { | 1449 | void 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 | ||
1546 | int FbWinFrame::heightOffset() const { | 1596 | int 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 | ||
1553 | int FbWinFrame::yOffset() const { | 1604 | int 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 | ||
159 | class TabPlacementMenuItem: public FbTk::MenuItem { | ||
160 | public: | ||
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 | |||
173 | private: | ||
174 | BScreen &m_screen; | ||
175 | FbWinFrame::TabPlacement m_place; | ||
176 | }; | ||
159 | 177 | ||
160 | } // end anonymous namespace | 178 | } // end anonymous namespace |
161 | 179 | ||
180 | |||
181 | |||
182 | namespace FbTk { | ||
183 | |||
184 | template<> | ||
185 | void FbTk::Resource<FbWinFrame::TabPlacement>:: | ||
186 | setFromString(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 | |||
209 | template<> | ||
210 | string FbTk::Resource<FbWinFrame::TabPlacement>:: | ||
211 | getString() 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 | |||
162 | BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm, | 246 | BScreen::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 | } |
714 | FbTk::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 | ||
630 | void BScreen::addExtraWindowMenu(const char *label, FbTk::Menu *menu) { | 724 | void 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 | |||
895 | void 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 |