aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfluxgen <fluxgen>2004-09-11 13:33:07 (GMT)
committerfluxgen <fluxgen>2004-09-11 13:33:07 (GMT)
commit37757769634c836895d205b0a5149ffffaae9bfb (patch)
tree0b61e2fe2c81474bbd8472e8b777eed61e769858
parentad63de0281bc32180b8f4e70f2570fbae4a0487a (diff)
downloadfluxbox_paul-37757769634c836895d205b0a5149ffffaae9bfb.zip
fluxbox_paul-37757769634c836895d205b0a5149ffffaae9bfb.tar.bz2
head specific strut, patch from Mathieu De Zutter
-rw-r--r--src/Screen.cc145
-rw-r--r--src/Screen.hh13
-rw-r--r--src/Slit.cc4
-rw-r--r--src/Toolbar.cc33
4 files changed, 116 insertions, 79 deletions
diff --git a/src/Screen.cc b/src/Screen.cc
index 8372f0f..e4ede29 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Screen.cc,v 1.289 2004/09/09 14:29:03 akir Exp $ 25// $Id: Screen.cc,v 1.290 2004/09/11 13:30:37 fluxgen Exp $
26 26
27 27
28#include "Screen.hh" 28#include "Screen.hh"
@@ -55,6 +55,7 @@
55#include "Strut.hh" 55#include "Strut.hh"
56#include "CommandParser.hh" 56#include "CommandParser.hh"
57#include "AtomHandler.hh" 57#include "AtomHandler.hh"
58#include "HeadArea.hh"
58 59
59 60
60#include "FbTk/I18n.hh" 61#include "FbTk/I18n.hh"
@@ -226,7 +227,6 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
226 m_name(screenname), 227 m_name(screenname),
227 m_altname(altscreenname), 228 m_altname(altscreenname),
228 m_resource_manager(rm), 229 m_resource_manager(rm),
229 m_available_workspace_area(new Strut(0, 0, 0, 0)),
230 m_xinerama_headinfo(0), 230 m_xinerama_headinfo(0),
231 m_shutdown(false) { 231 m_shutdown(false) {
232 232
@@ -250,6 +250,9 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
250 managed = running; 250 managed = running;
251 if (! managed) 251 if (! managed)
252 return; 252 return;
253
254 // TODO fluxgen: check if this is the right place
255 m_head_areas = new HeadArea[numHeads() ? numHeads() : 1];
253 256
254 _FB_USES_NLS; 257 _FB_USES_NLS;
255 258
@@ -434,6 +437,9 @@ BScreen::~BScreen() {
434 if (hasXinerama() && m_xinerama_headinfo) { 437 if (hasXinerama() && m_xinerama_headinfo) {
435 delete [] m_xinerama_headinfo; 438 delete [] m_xinerama_headinfo;
436 } 439 }
440
441 // TODO fluxgen: check if this is the right place
442 delete [] m_head_areas;
437} 443}
438 444
439void BScreen::initWindows() { 445void BScreen::initWindows() {
@@ -548,32 +554,36 @@ unsigned int BScreen::currentWorkspaceID() const {
548 return m_current_workspace->workspaceID(); 554 return m_current_workspace->workspaceID();
549} 555}
550 556
557const Strut* BScreen::availableWorkspaceArea(int head) const {
558 return m_head_areas[head ? head-1 : 0].availableWorkspaceArea();
559}
560
551unsigned int BScreen::maxLeft(int head) const { 561unsigned int BScreen::maxLeft(int head) const {
562
552 // we ignore strut if we're doing full maximization 563 // we ignore strut if we're doing full maximization
553 if (hasXinerama()) 564 if (hasXinerama())
554 return doFullMax() ? getHeadX(head) : 565 return doFullMax() ? getHeadX(head) :
555 getHeadX(head) + m_available_workspace_area->left(); 566 getHeadX(head) + availableWorkspaceArea(head)->left();
556 else 567 else
557 return doFullMax() ? 0 : m_available_workspace_area->left(); 568 return doFullMax() ? 0 : availableWorkspaceArea(head)->left();
558} 569}
559 570
560unsigned int BScreen::maxRight(int head) const { 571unsigned int BScreen::maxRight(int head) const {
561 // we ignore strut if we're doing full maximization 572 // we ignore strut if we're doing full maximization
562 if (hasXinerama()) 573 if (hasXinerama())
563 return doFullMax() ? getHeadX(head) + getHeadWidth(head) : 574 return doFullMax() ? getHeadX(head) + getHeadWidth(head) :
564 getHeadX(head) + getHeadWidth(head) - m_available_workspace_area->right(); 575 getHeadX(head) + getHeadWidth(head) - availableWorkspaceArea(head)->right();
565 else 576 else
566 return doFullMax() ? width() : width() - m_available_workspace_area->right(); 577 return doFullMax() ? width() : width() - availableWorkspaceArea(head)->right();
567} 578}
568 579
569unsigned int BScreen::maxTop(int head) const { 580unsigned int BScreen::maxTop(int head) const {
570
571 // we ignore strut if we're doing full maximization 581 // we ignore strut if we're doing full maximization
572 582
573 if (hasXinerama()) 583 if (hasXinerama())
574 return doFullMax() ? getHeadY(head) : getHeadY(head) + m_available_workspace_area->top(); 584 return doFullMax() ? getHeadY(head) : getHeadY(head) + availableWorkspaceArea(head)->top();
575 else 585 else
576 return doFullMax() ? 0 : m_available_workspace_area->top(); 586 return doFullMax() ? 0 : availableWorkspaceArea(head)->top();
577} 587}
578 588
579unsigned int BScreen::maxBottom(int head) const { 589unsigned int BScreen::maxBottom(int head) const {
@@ -581,9 +591,9 @@ unsigned int BScreen::maxBottom(int head) const {
581 591
582 if (hasXinerama()) 592 if (hasXinerama())
583 return doFullMax() ? getHeadY(head) + getHeadHeight(head) : 593 return doFullMax() ? getHeadY(head) + getHeadHeight(head) :
584 getHeadY(head) + getHeadHeight(head) - m_available_workspace_area->bottom(); 594 getHeadY(head) + getHeadHeight(head) - availableWorkspaceArea(head)->bottom();
585 else 595 else
586 return doFullMax() ? height() : height() - m_available_workspace_area->bottom(); 596 return doFullMax() ? height() : height() - availableWorkspaceArea(head)->bottom();
587} 597}
588 598
589void BScreen::update(FbTk::Subject *subj) { 599void BScreen::update(FbTk::Subject *subj) {
@@ -1260,58 +1270,46 @@ FluxboxWindow *BScreen::createWindow(WinClient &client) {
1260 return win; 1270 return win;
1261} 1271}
1262 1272
1263Strut *BScreen::requestStrut(int left, int right, int top, int bottom) { 1273Strut *BScreen::requestStrut(int head, int left, int right, int top, int bottom) {
1264 Strut *str = new Strut(left, right, top, bottom); 1274 if (head > numHeads() && head != 1) {
1265 m_strutlist.push_back(str); 1275 // head does not exist (if head == 1, then numHeads() == 0,
1266 return str; 1276 // which means no xinerama, but there's a head after all
1267} 1277 head = numHeads();
1278 }
1268 1279
1269void BScreen::clearStrut(Strut *str) { 1280 int begin = head-1;
1270 if (str == 0) 1281 int end = head;
1271 return;
1272 // find strut and erase it
1273 std::list<Strut *>::iterator pos = find(m_strutlist.begin(),
1274 m_strutlist.end(),
1275 str);
1276 if (pos == m_strutlist.end())
1277 return;
1278 m_strutlist.erase(pos);
1279 delete str;
1280}
1281 1282
1282/// helper class for for_each in BScreen::updateAvailableWorkspaceArea() 1283 if (head == 0) { // all heads (or no xinerama)
1283namespace { 1284 begin = 0;
1284class MaxArea { 1285 end = (numHeads() ? numHeads() : 1);
1285public:
1286 MaxArea(Strut &max_area):m_max_area(max_area) { }
1287 void operator ()(const Strut *str) {
1288 static int left, right, bottom, top;
1289 left = std::max(m_max_area.left(), str->left());
1290 right = std::max(m_max_area.right(), str->right());
1291 bottom = std::max(m_max_area.bottom(), str->bottom());
1292 top = std::max(m_max_area.top(), str->top());
1293 m_max_area = Strut(left, right, top, bottom);
1294 } 1286 }
1295private:
1296 Strut &m_max_area;
1297};
1298 1287
1299} // end anonymous namespace 1288 Strut* next = 0;
1289 for (int i = begin; i != end; i++) {
1290 next = m_head_areas[i].requestStrut(i+1, left, right, top, bottom, next);
1291 }
1292
1293 return next;
1294}
1295
1296void BScreen::clearStrut(Strut *str) {
1297 if (str->next())
1298 clearStrut(str->next());
1299 int head = str->head() ? str->head() - 1 : 0;
1300 m_head_areas[head].clearStrut(str);
1301 // str is invalid now
1302}
1300 1303
1301void BScreen::updateAvailableWorkspaceArea() { 1304void BScreen::updateAvailableWorkspaceArea() {
1302 // find max of left, right, top and bottom and set avaible workspace area 1305 size_t n = (numHeads() ? numHeads() : 1);
1306 bool updated = false;
1303 1307
1304 // clear old area 1308 for (size_t i = 0; i < n; i++) {
1305 Strut oldarea = *(m_available_workspace_area.get()); 1309 updated = m_head_areas[i].updateAvailableWorkspaceArea() || updated;
1306 m_available_workspace_area.reset(new Strut(0, 0, 0, 0)); 1310 }
1307
1308 // calculate max area
1309 for_each(m_strutlist.begin(),
1310 m_strutlist.end(),
1311 MaxArea(*m_available_workspace_area.get()));
1312 1311
1313 // only notify if the area changed 1312 if (updated)
1314 if (oldarea == *(m_available_workspace_area.get()))
1315 m_workspace_area_sig.notify(); 1313 m_workspace_area_sig.notify();
1316} 1314}
1317 1315
@@ -2204,11 +2202,17 @@ void BScreen::initXinerama() {
2204 Display *display = FbTk::App::instance()->display(); 2202 Display *display = FbTk::App::instance()->display();
2205 2203
2206 if (!XineramaIsActive(display)) { 2204 if (!XineramaIsActive(display)) {
2205#ifdef DEBUG
2206 cerr<<"BScreen::initXinerama(): dont have Xinerama"<<endl;
2207#endif // DEBUG
2207 m_xinerama_avail = false; 2208 m_xinerama_avail = false;
2208 m_xinerama_headinfo = 0; 2209 m_xinerama_headinfo = 0;
2209 m_xinerama_num_heads = 0; 2210 m_xinerama_num_heads = 0;
2210 return; 2211 return;
2211 } 2212 }
2213#ifdef DEBUG
2214 cerr<<"BScreen::initXinerama(): have Xinerama"<<endl;
2215#endif // DEBUG
2212 m_xinerama_avail = true; 2216 m_xinerama_avail = true;
2213 2217
2214 XineramaScreenInfo *screen_info; 2218 XineramaScreenInfo *screen_info;
@@ -2222,6 +2226,10 @@ void BScreen::initXinerama() {
2222 m_xinerama_headinfo[i].width = screen_info[i].width; 2226 m_xinerama_headinfo[i].width = screen_info[i].width;
2223 m_xinerama_headinfo[i].height = screen_info[i].height; 2227 m_xinerama_headinfo[i].height = screen_info[i].height;
2224 } 2228 }
2229#ifdef DEBUG
2230 cerr<<"BScreen::initXinerama(): number of heads ="<<number<<endl;
2231#endif // DEBUG
2232
2225#else // XINERAMA 2233#else // XINERAMA
2226 // no xinerama 2234 // no xinerama
2227 m_xinerama_avail = false; 2235 m_xinerama_avail = false;
@@ -2308,6 +2316,31 @@ int BScreen::getHeadHeight(int head) const {
2308#endif // XINERAMA 2316#endif // XINERAMA
2309} 2317}
2310 2318
2319pair<int,int> BScreen::clampToHead(int head, int x, int y, int w, int h) const {
2320
2321 // if there are multiple heads, head=0 is not valid
2322 // a better way would be to search the closest head
2323 if (head == 0 && numHeads() != 0)
2324 head = 1;
2325
2326 int hx = getHeadX(head);
2327 int hy = getHeadY(head);
2328 int hw = getHeadWidth(head);
2329 int hh = getHeadHeight(head);
2330
2331 if (x + w > hx + hw)
2332 x = hx + hw - w;
2333 if (y + h > hy + hh)
2334 y = hy + hh - h;
2335
2336 if (x < hx)
2337 x = hx;
2338 if (y < hy)
2339 y = hy;
2340
2341 return make_pair(x,y);
2342}
2343
2311// TODO: when toolbar gets its resources moved into Toolbar.hh/cc, then 2344// TODO: when toolbar gets its resources moved into Toolbar.hh/cc, then
2312// this can be gone and a consistent interface for the two used 2345// this can be gone and a consistent interface for the two used
2313// on the actual objects 2346// on the actual objects
diff --git a/src/Screen.hh b/src/Screen.hh
index 076ee63..ad460a8 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Screen.hh,v 1.144 2004/09/09 14:29:04 akir Exp $ 25// $Id: Screen.hh,v 1.145 2004/09/11 13:29:35 fluxgen Exp $
26 26
27#ifndef SCREEN_HH 27#ifndef SCREEN_HH
28#define SCREEN_HH 28#define SCREEN_HH
@@ -61,6 +61,7 @@ class WinClient;
61class Workspace; 61class Workspace;
62class Strut; 62class Strut;
63class Slit; 63class Slit;
64class HeadArea;
64 65
65namespace FbTk { 66namespace FbTk {
66class Menu; 67class Menu;
@@ -304,6 +305,9 @@ public:
304 int getHeadWidth(int head) const; 305 int getHeadWidth(int head) const;
305 int getHeadHeight(int head) const; 306 int getHeadHeight(int head) const;
306 307
308 // returns the new (x,y) for a rectangle fitted on a head
309 std::pair<int,int> clampToHead(int head, int x, int y, int w, int h) const;
310
307 // magic to allow us to have "on head" placement (menu) without 311 // magic to allow us to have "on head" placement (menu) without
308 // the object really knowing about it. 312 // the object really knowing about it.
309 template <typename OnHeadObject> 313 template <typename OnHeadObject>
@@ -333,7 +337,7 @@ public:
333 FluxboxWindow *createWindow(WinClient &client); 337 FluxboxWindow *createWindow(WinClient &client);
334 void setupWindowActions(FluxboxWindow &win); 338 void setupWindowActions(FluxboxWindow &win);
335 /// request workspace space, i.e "don't maximize over this area" 339 /// request workspace space, i.e "don't maximize over this area"
336 Strut *requestStrut(int left, int right, int top, int bottom); 340 Strut *requestStrut(int head, int left, int right, int top, int bottom);
337 /// remove requested space and destroy strut 341 /// remove requested space and destroy strut
338 void clearStrut(Strut *strut); 342 void clearStrut(Strut *strut);
339 /// updates max avaible area for the workspace 343 /// updates max avaible area for the workspace
@@ -363,6 +367,8 @@ private:
363 void renderGeomWindow(); 367 void renderGeomWindow();
364 void renderPosWindow(); 368 void renderPosWindow();
365 369
370 const Strut* availableWorkspaceArea(int head) const;
371
366 ScreenSubject 372 ScreenSubject
367 m_clientlist_sig, ///< client signal 373 m_clientlist_sig, ///< client signal
368 m_iconlist_sig, ///< notify if a window gets iconified/deiconified 374 m_iconlist_sig, ///< notify if a window gets iconified/deiconified
@@ -455,13 +461,12 @@ private:
455 461
456 int m_xinerama_center_x, m_xinerama_center_y; 462 int m_xinerama_center_x, m_xinerama_center_y;
457 463
458 std::auto_ptr<Strut> m_available_workspace_area; 464 HeadArea *m_head_areas;
459 465
460 struct XineramaHeadInfo { 466 struct XineramaHeadInfo {
461 int x, y, width, height; 467 int x, y, width, height;
462 } *m_xinerama_headinfo; 468 } *m_xinerama_headinfo;
463 469
464 std::list<Strut *> m_strutlist;
465 bool m_shutdown; 470 bool m_shutdown;
466}; 471};
467 472
diff --git a/src/Slit.cc b/src/Slit.cc
index f960ac8..dc14d42 100644
--- a/src/Slit.cc
+++ b/src/Slit.cc
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Slit.cc,v 1.99 2004/08/31 19:27:21 akir Exp $ 25// $Id: Slit.cc,v 1.100 2004/09/11 13:31:36 fluxgen Exp $
26 26
27#include "Slit.hh" 27#include "Slit.hh"
28 28
@@ -407,7 +407,7 @@ void Slit::updateStrut() {
407 right = width(); 407 right = width();
408 break; 408 break;
409 } 409 }
410 m_strut = screen().requestStrut(left, right, top, bottom); 410 m_strut = screen().requestStrut(getOnHead(), left, right, top, bottom);
411 screen().updateAvailableWorkspaceArea(); 411 screen().updateAvailableWorkspaceArea();
412} 412}
413 413
diff --git a/src/Toolbar.cc b/src/Toolbar.cc
index 2c19518..d35e872 100644
--- a/src/Toolbar.cc
+++ b/src/Toolbar.cc
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Toolbar.cc,v 1.152 2004/08/31 19:38:42 akir Exp $ 25// $Id: Toolbar.cc,v 1.153 2004/09/11 13:33:07 fluxgen Exp $
26 26
27#include "Toolbar.hh" 27#include "Toolbar.hh"
28 28
@@ -328,7 +328,7 @@ void Toolbar::updateStrut() {
328 left = width(); 328 left = width();
329 break; 329 break;
330 }; 330 };
331 m_strut = screen().requestStrut(left, right, top, bottom); 331 m_strut = screen().requestStrut(getOnHead(), left, right, top, bottom);
332 screen().updateAvailableWorkspaceArea(); 332 screen().updateAvailableWorkspaceArea();
333} 333}
334 334
@@ -485,22 +485,21 @@ void Toolbar::buttonPressEvent(XButtonEvent &be) {
485 screen().hideMenus(); 485 screen().hideMenus();
486 486
487 if (! menu().isVisible()) { 487 if (! menu().isVisible()) {
488 int x, y;
489 488
490 x = be.x_root - (menu().width() / 2); 489 int head = screen().getHead(be.x_root, be.y_root);
491 y = be.y_root - (menu().height() / 2); 490 int borderw = menu().fbwindow().borderWidth();
492 491 pair<int, int> m = screen().clampToHead( head,
493 if (x < 0) 492 be.x_root - (menu().width() / 2),
494 x = 0; 493 be.y_root - (menu().titleWindow().height() / 2),
495 else if (x + menu().width() > screen().width()) 494 menu().width() + 2*borderw,
496 x = screen().width() - menu().width(); 495 menu().height() + 2*borderw);
497 496
498 if (y < 0) 497 menu().setScreen(
499 y = 0; 498 screen().getHeadX(head),
500 else if (y + menu().height() > screen().height()) 499 screen().getHeadY(head),
501 y = screen().height() - menu().height(); 500 screen().getHeadWidth(head),
502 501 screen().getHeadHeight(head));
503 menu().move(x, y); 502 menu().move(m.first, m.second);
504 menu().show(); 503 menu().show();
505 menu().grabInputFocus(); 504 menu().grabInputFocus();
506 } else 505 } else