]> Dogcows Code - chaz/openbox/blob - src/Workspace.cc
move an assert to its proper place
[chaz/openbox] / src / Workspace.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Workspace.cc for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a
7 // copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 // DEALINGS IN THE SOFTWARE.
23
24 #ifdef HAVE_CONFIG_H
25 # include "../config.h"
26 #endif // HAVE_CONFIG_H
27
28 extern "C" {
29 #include <X11/Xlib.h>
30 #include <X11/Xatom.h>
31
32 #ifdef HAVE_STDIO_H
33 # include <stdio.h>
34 #endif // HAVE_STDIO_H
35
36 #ifdef HAVE_STRING_H
37 # include <string.h>
38 #endif // HAVE_STRING_H
39 }
40
41 #include <assert.h>
42
43 #include <functional>
44 #include <string>
45
46 using std::string;
47
48 #include "i18n.hh"
49 #include "blackbox.hh"
50 #include "Clientmenu.hh"
51 #include "Netizen.hh"
52 #include "Screen.hh"
53 #include "Toolbar.hh"
54 #include "Util.hh"
55 #include "Window.hh"
56 #include "Workspace.hh"
57 #include "Windowmenu.hh"
58 #include "XAtom.hh"
59
60
61 Workspace::Workspace(BScreen *scrn, unsigned int i) {
62 screen = scrn;
63 xatom = screen->getBlackbox()->getXAtom();
64
65 cascade_x = cascade_y = 32;
66
67 id = i;
68
69 clientmenu = new Clientmenu(this);
70
71 lastfocus = (BlackboxWindow *) 0;
72
73 readName();
74 }
75
76
77 void Workspace::addWindow(BlackboxWindow *w, bool place) {
78 assert(w != 0);
79
80 if (place) placeWindow(w);
81
82 stackingList.push_front(w);
83
84 if (w->isNormal()) {
85 w->setWorkspace(id);
86 w->setWindowNumber(windowList.size());
87
88 windowList.push_back(w);
89
90 clientmenu->insert(w->getTitle());
91 clientmenu->update();
92
93 screen->updateNetizenWindowAdd(w->getClientWindow(), id);
94
95 if (id != screen->getCurrentWorkspaceID() &&
96 screen->doFocusNew()) {
97 /*
98 not on the focused workspace, so the window is not going to get focus
99 but if the user wants new windows focused, then it should get focus
100 when this workspace does become focused.
101 */
102 lastfocus = w;
103 }
104 }
105
106 if (! w->isDesktop())
107 raiseWindow(w);
108 else
109 lowerWindow(w);
110 }
111
112
113 void Workspace::removeWindow(BlackboxWindow *w) {
114 assert(w != 0);
115
116 stackingList.remove(w);
117
118 // pass focus to the next appropriate window
119 if ((w->isFocused() || w == lastfocus) &&
120 ! screen->getBlackbox()->doShutdown()) {
121 focusFallback(w);
122
123 // if the window is sticky, then it needs to be removed on all other
124 // workspaces too!
125 if (w->isStuck()) {
126 for (unsigned int i = 0; i < screen->getWorkspaceCount(); ++i)
127 if (i != id)
128 screen->getWorkspace(i)->focusFallback(w);
129 }
130 }
131
132 if (! w->isNormal()) return;
133
134 windowList.remove(w);
135 clientmenu->remove(w->getWindowNumber());
136 clientmenu->update();
137
138 screen->updateNetizenWindowDel(w->getClientWindow());
139
140 BlackboxWindowList::iterator it = windowList.begin();
141 const BlackboxWindowList::iterator end = windowList.end();
142 unsigned int i = 0;
143 for (; it != end; ++it, ++i)
144 (*it)->setWindowNumber(i);
145
146 if (i == 0)
147 cascade_x = cascade_y = 32;
148 }
149
150
151 void Workspace::focusFallback(const BlackboxWindow *old_window) {
152 BlackboxWindow *newfocus = 0;
153
154 if (id == screen->getCurrentWorkspaceID()) {
155 // The window is on the visible workspace.
156
157 // if it's a transient, then try to focus its parent
158 if (old_window && old_window->isTransient()) {
159 newfocus = old_window->getTransientFor();
160
161 if (! newfocus ||
162 newfocus->isIconic() || // do not focus icons
163 newfocus->getWorkspaceNumber() != id || // or other workspaces
164 ! newfocus->setInputFocus())
165 newfocus = 0;
166 }
167
168 if (! newfocus) {
169 BlackboxWindowList::iterator it = stackingList.begin(),
170 end = stackingList.end();
171 for (; it != end; ++it) {
172 BlackboxWindow *tmp = *it;
173 if (tmp && tmp->isNormal() && tmp->setInputFocus()) {
174 // we found our new focus target
175 newfocus = tmp;
176 break;
177 }
178 }
179 }
180
181 screen->getBlackbox()->setFocusedWindow(newfocus);
182 } else {
183 // The window is not on the visible workspace.
184
185 if (old_window && lastfocus == old_window) {
186 // The window was the last-focus target, so we need to replace it.
187 BlackboxWindow *win = (BlackboxWindow*) 0;
188 if (! stackingList.empty())
189 win = stackingList.front();
190 setLastFocusedWindow(win);
191 }
192 }
193 }
194
195
196 void Workspace::showAll(void) {
197 BlackboxWindowList::iterator it = stackingList.begin();
198 const BlackboxWindowList::iterator end = stackingList.end();
199 for (; it != end; ++it) {
200 BlackboxWindow *bw = *it;
201 if (! bw->isStuck())
202 bw->show();
203 }
204 }
205
206
207 void Workspace::hideAll(void) {
208 // withdraw in reverse order to minimize the number of Expose events
209 BlackboxWindowList::reverse_iterator it = stackingList.rbegin();
210 const BlackboxWindowList::reverse_iterator end = stackingList.rend();
211 while (it != end) {
212 BlackboxWindow *bw = *it;
213 ++it; // withdraw removes the current item from the list so we need the next
214 // iterator before that happens
215 if (! bw->isStuck())
216 bw->withdraw();
217 }
218 }
219
220
221 void Workspace::removeAll(void) {
222 while (! windowList.empty())
223 windowList.front()->iconify();
224 }
225
226
227 /*
228 * returns the number of transients for win, plus the number of transients
229 * associated with each transient of win
230 */
231 static int countTransients(const BlackboxWindow * const win) {
232 int ret = win->getTransients().size();
233 if (ret > 0) {
234 BlackboxWindowList::const_iterator it, end = win->getTransients().end();
235 for (it = win->getTransients().begin(); it != end; ++it) {
236 ret += countTransients(*it);
237 }
238 }
239 return ret;
240 }
241
242
243 /*
244 * puts the transients of win into the stack. windows are stacked above
245 * the window before it in the stackvector being iterated, meaning
246 * stack[0] is on bottom, stack[1] is above stack[0], stack[2] is above
247 * stack[1], etc...
248 */
249 void Workspace::raiseTransients(const BlackboxWindow * const win,
250 StackVector::iterator &stack) {
251 if (win->getTransients().size() == 0) return; // nothing to do
252
253 // put win's transients in the stack
254 BlackboxWindowList::const_iterator it, end = win->getTransients().end();
255 for (it = win->getTransients().begin(); it != end; ++it) {
256 *stack++ = (*it)->getFrameWindow();
257 screen->updateNetizenWindowRaise((*it)->getClientWindow());
258
259 if (! (*it)->isIconic()) {
260 Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber());
261 wkspc->stackingList.remove((*it));
262 wkspc->stackingList.push_front((*it));
263 }
264 }
265
266 // put transients of win's transients in the stack
267 for (it = win->getTransients().begin(); it != end; ++it) {
268 raiseTransients(*it, stack);
269 }
270 }
271
272
273 void Workspace::lowerTransients(const BlackboxWindow * const win,
274 StackVector::iterator &stack) {
275 if (win->getTransients().size() == 0) return; // nothing to do
276
277 // put transients of win's transients in the stack
278 BlackboxWindowList::const_reverse_iterator it,
279 end = win->getTransients().rend();
280 for (it = win->getTransients().rbegin(); it != end; ++it) {
281 lowerTransients(*it, stack);
282 }
283
284 // put win's transients in the stack
285 for (it = win->getTransients().rbegin(); it != end; ++it) {
286 *stack++ = (*it)->getFrameWindow();
287 screen->updateNetizenWindowLower((*it)->getClientWindow());
288
289 if (! (*it)->isIconic()) {
290 Workspace *wkspc = screen->getWorkspace((*it)->getWorkspaceNumber());
291 wkspc->stackingList.remove((*it));
292 wkspc->stackingList.push_back((*it));
293 }
294 }
295 }
296
297
298 void Workspace::raiseWindow(BlackboxWindow *w) {
299 BlackboxWindow *win = w;
300
301 if (win->isDesktop()) return;
302
303 // walk up the transient_for's to the window that is not a transient
304 while (win->isTransient() && ! win->isDesktop()) {
305 if (! win->getTransientFor()) break;
306 win = win->getTransientFor();
307 }
308
309 // get the total window count (win and all transients)
310 unsigned int i = 1 + countTransients(win);
311
312 // stack the window with all transients above
313 StackVector stack_vector(i);
314 StackVector::iterator stack = stack_vector.begin();
315
316 *(stack++) = win->getFrameWindow();
317 screen->updateNetizenWindowRaise(win->getClientWindow());
318 if (! (win->isIconic() || win->isDesktop())) {
319 Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber());
320 wkspc->stackingList.remove(win);
321 wkspc->stackingList.push_front(win);
322 }
323
324 raiseTransients(win, stack);
325
326 screen->raiseWindows(&stack_vector[0], stack_vector.size());
327 }
328
329
330 void Workspace::lowerWindow(BlackboxWindow *w) {
331 BlackboxWindow *win = w;
332
333 // walk up the transient_for's to the window that is not a transient
334 while (win->isTransient() && ! win->isDesktop()) {
335 if (! win->getTransientFor()) break;
336 win = win->getTransientFor();
337 }
338
339 // get the total window count (win and all transients)
340 unsigned int i = 1 + countTransients(win);
341
342 // stack the window with all transients above
343 StackVector stack_vector(i);
344 StackVector::iterator stack = stack_vector.begin();
345
346 lowerTransients(win, stack);
347
348 *(stack++) = win->getFrameWindow();
349 screen->updateNetizenWindowLower(win->getClientWindow());
350 if (! (win->isIconic() || win->isDesktop())) {
351 Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber());
352 wkspc->stackingList.remove(win);
353 wkspc->stackingList.push_back(win);
354 }
355
356 screen->lowerWindows(&stack_vector[0], stack_vector.size());
357 }
358
359
360 void Workspace::reconfigure(void) {
361 clientmenu->reconfigure();
362 std::for_each(windowList.begin(), windowList.end(),
363 std::mem_fun(&BlackboxWindow::reconfigure));
364 }
365
366
367 BlackboxWindow *Workspace::getWindow(unsigned int index) {
368 if (index < windowList.size()) {
369 BlackboxWindowList::iterator it = windowList.begin();
370 for(; index > 0; --index, ++it); /* increment to index */
371 return *it;
372 }
373 return 0;
374 }
375
376
377 BlackboxWindow*
378 Workspace::getNextWindowInList(BlackboxWindow *w) {
379 BlackboxWindowList::iterator it = std::find(windowList.begin(),
380 windowList.end(),
381 w);
382 assert(it != windowList.end()); // window must be in list
383 ++it; // next window
384 if (it == windowList.end())
385 return windowList.front(); // if we walked off the end, wrap around
386
387 return *it;
388 }
389
390
391 BlackboxWindow* Workspace::getPrevWindowInList(BlackboxWindow *w) {
392 BlackboxWindowList::iterator it = std::find(windowList.begin(),
393 windowList.end(),
394 w);
395 assert(it != windowList.end()); // window must be in list
396 if (it == windowList.begin())
397 return windowList.back(); // if we walked of the front, wrap around
398
399 return *(--it);
400 }
401
402
403 BlackboxWindow* Workspace::getTopWindowOnStack(void) const {
404 return stackingList.front();
405 }
406
407
408 void Workspace::sendWindowList(Netizen &n) {
409 BlackboxWindowList::iterator it = windowList.begin(),
410 end = windowList.end();
411 for(; it != end; ++it)
412 n.sendWindowAdd((*it)->getClientWindow(), getID());
413 }
414
415
416 unsigned int Workspace::getCount(void) const {
417 return windowList.size();
418 }
419
420
421 void Workspace::appendStackOrder(BlackboxWindowList &stack_order) const {
422 BlackboxWindowList::const_reverse_iterator it = stackingList.rbegin();
423 const BlackboxWindowList::const_reverse_iterator end = stackingList.rend();
424 for (; it != end; ++it)
425 if ((*it)->isNormal())
426 stack_order.push_back(*it);
427 }
428
429
430 bool Workspace::isCurrent(void) const {
431 return (id == screen->getCurrentWorkspaceID());
432 }
433
434
435 bool Workspace::isLastWindow(const BlackboxWindow* const w) const {
436 return (w == windowList.back());
437 }
438
439
440 void Workspace::setCurrent(void) {
441 screen->changeWorkspaceID(id);
442 }
443
444
445 void Workspace::readName(void) {
446 XAtom::StringVect namesList;
447 unsigned long numnames = id + 1;
448
449 // attempt to get from the _NET_WM_DESKTOP_NAMES property
450 if (xatom->getValue(screen->getRootWindow(), XAtom::net_desktop_names,
451 XAtom::utf8, numnames, namesList) &&
452 namesList.size() > id) {
453 name = namesList[id];
454
455 clientmenu->setLabel(name);
456 clientmenu->update();
457 } else {
458 /*
459 Use a default name. This doesn't actually change the class. That will
460 happen after the setName changes the root property, and that change
461 makes its way back to this function.
462 */
463 string tmp =i18n(WorkspaceSet, WorkspaceDefaultNameFormat,
464 "Workspace %d");
465 assert(tmp.length() < 32);
466 char default_name[32];
467 sprintf(default_name, tmp.c_str(), id + 1);
468
469 setName(default_name); // save this into the _NET_WM_DESKTOP_NAMES property
470 }
471 }
472
473
474 void Workspace::setName(const string& new_name) {
475 // set the _NET_WM_DESKTOP_NAMES property with the new name
476 XAtom::StringVect namesList;
477 unsigned long numnames = (unsigned) -1;
478 if (xatom->getValue(screen->getRootWindow(), XAtom::net_desktop_names,
479 XAtom::utf8, numnames, namesList) &&
480 namesList.size() > id)
481 namesList[id] = new_name;
482 else
483 namesList.push_back(new_name);
484
485 xatom->setValue(screen->getRootWindow(), XAtom::net_desktop_names,
486 XAtom::utf8, namesList);
487 }
488
489
490 /*
491 * Calculate free space available for window placement.
492 */
493 typedef std::vector<Rect> rectList;
494
495 static rectList calcSpace(const Rect &win, const rectList &spaces) {
496 Rect isect, extra;
497 rectList result;
498 rectList::const_iterator siter, end = spaces.end();
499 for (siter = spaces.begin(); siter != end; ++siter) {
500 const Rect &curr = *siter;
501
502 if(! win.intersects(curr)) {
503 result.push_back(curr);
504 continue;
505 }
506
507 /* Use an intersection of win and curr to determine the space around
508 * curr that we can use.
509 *
510 * NOTE: the spaces calculated can overlap.
511 */
512 isect = curr & win;
513
514 // left
515 extra.setCoords(curr.left(), curr.top(),
516 isect.left() - 1, curr.bottom());
517 if (extra.valid()) result.push_back(extra);
518
519 // top
520 extra.setCoords(curr.left(), curr.top(),
521 curr.right(), isect.top() - 1);
522 if (extra.valid()) result.push_back(extra);
523
524 // right
525 extra.setCoords(isect.right() + 1, curr.top(),
526 curr.right(), curr.bottom());
527 if (extra.valid()) result.push_back(extra);
528
529 // bottom
530 extra.setCoords(curr.left(), isect.bottom() + 1,
531 curr.right(), curr.bottom());
532 if (extra.valid()) result.push_back(extra);
533 }
534 return result;
535 }
536
537
538 static bool rowRLBT(const Rect &first, const Rect &second) {
539 if (first.bottom() == second.bottom())
540 return first.right() > second.right();
541 return first.bottom() > second.bottom();
542 }
543
544 static bool rowRLTB(const Rect &first, const Rect &second) {
545 if (first.y() == second.y())
546 return first.right() > second.right();
547 return first.y() < second.y();
548 }
549
550 static bool rowLRBT(const Rect &first, const Rect &second) {
551 if (first.bottom() == second.bottom())
552 return first.x() < second.x();
553 return first.bottom() > second.bottom();
554 }
555
556 static bool rowLRTB(const Rect &first, const Rect &second) {
557 if (first.y() == second.y())
558 return first.x() < second.x();
559 return first.y() < second.y();
560 }
561
562 static bool colLRTB(const Rect &first, const Rect &second) {
563 if (first.x() == second.x())
564 return first.y() < second.y();
565 return first.x() < second.x();
566 }
567
568 static bool colLRBT(const Rect &first, const Rect &second) {
569 if (first.x() == second.x())
570 return first.bottom() > second.bottom();
571 return first.x() < second.x();
572 }
573
574 static bool colRLTB(const Rect &first, const Rect &second) {
575 if (first.right() == second.right())
576 return first.y() < second.y();
577 return first.right() > second.right();
578 }
579
580 static bool colRLBT(const Rect &first, const Rect &second) {
581 if (first.right() == second.right())
582 return first.bottom() > second.bottom();
583 return first.right() > second.right();
584 }
585
586
587 bool Workspace::smartPlacement(Rect& win) {
588 rectList spaces;
589
590 //initially the entire screen is free
591 #ifdef XINERAMA
592 if (screen->isXineramaActive() &&
593 screen->getBlackbox()->doXineramaPlacement()) {
594 RectList availableAreas = screen->allAvailableAreas();
595 RectList::iterator it, end = availableAreas.end();
596
597 for (it = availableAreas.begin(); it != end; ++it)
598 spaces.push_back(*it);
599 } else
600 #endif // XINERAMA
601 spaces.push_back(screen->availableArea());
602
603 //Find Free Spaces
604 BlackboxWindowList::const_iterator wit = windowList.begin(),
605 end = windowList.end();
606 Rect tmp;
607 for (; wit != end; ++wit) {
608 const BlackboxWindow* const curr = *wit;
609
610 if (curr->isShaded() && screen->getPlaceIgnoreShaded()) continue;
611 if (curr->isMaximizedFull() && screen->getPlaceIgnoreMaximized()) continue;
612
613 tmp.setRect(curr->frameRect().x(), curr->frameRect().y(),
614 curr->frameRect().width() + screen->getBorderWidth(),
615 curr->frameRect().height() + screen->getBorderWidth());
616
617 spaces = calcSpace(tmp, spaces);
618 }
619
620 if (screen->getPlacementPolicy() == BScreen::RowSmartPlacement) {
621 if(screen->getRowPlacementDirection() == BScreen::LeftRight) {
622 if(screen->getColPlacementDirection() == BScreen::TopBottom)
623 std::sort(spaces.begin(), spaces.end(), rowLRTB);
624 else
625 std::sort(spaces.begin(), spaces.end(), rowLRBT);
626 } else {
627 if(screen->getColPlacementDirection() == BScreen::TopBottom)
628 std::sort(spaces.begin(), spaces.end(), rowRLTB);
629 else
630 std::sort(spaces.begin(), spaces.end(), rowRLBT);
631 }
632 } else {
633 if(screen->getColPlacementDirection() == BScreen::TopBottom) {
634 if(screen->getRowPlacementDirection() == BScreen::LeftRight)
635 std::sort(spaces.begin(), spaces.end(), colLRTB);
636 else
637 std::sort(spaces.begin(), spaces.end(), colRLTB);
638 } else {
639 if(screen->getRowPlacementDirection() == BScreen::LeftRight)
640 std::sort(spaces.begin(), spaces.end(), colLRBT);
641 else
642 std::sort(spaces.begin(), spaces.end(), colRLBT);
643 }
644 }
645
646 rectList::const_iterator sit = spaces.begin(), spaces_end = spaces.end();
647 for(; sit != spaces_end; ++sit) {
648 if (sit->width() >= win.width() && sit->height() >= win.height())
649 break;
650 }
651
652 if (sit == spaces_end)
653 return False;
654
655 //set new position based on the empty space found
656 const Rect& where = *sit;
657 win.setX(where.x());
658 win.setY(where.y());
659
660 // adjust the location() based on left/right and top/bottom placement
661 if (screen->getPlacementPolicy() == BScreen::RowSmartPlacement) {
662 if (screen->getRowPlacementDirection() == BScreen::RightLeft)
663 win.setX(where.right() - win.width());
664 if (screen->getColPlacementDirection() == BScreen::BottomTop)
665 win.setY(where.bottom() - win.height());
666 } else {
667 if (screen->getColPlacementDirection() == BScreen::BottomTop)
668 win.setY(win.y() + where.height() - win.height());
669 if (screen->getRowPlacementDirection() == BScreen::RightLeft)
670 win.setX(win.x() + where.width() - win.width());
671 }
672 return True;
673 }
674
675
676 bool Workspace::underMousePlacement(Rect &win) {
677 int x, y, rx, ry;
678 Window c, r;
679 unsigned int m;
680 XQueryPointer(screen->getBlackbox()->getXDisplay(), screen->getRootWindow(),
681 &r, &c, &rx, &ry, &x, &y, &m);
682
683 Rect area;
684 #ifdef XINERAMA
685 if (screen->isXineramaActive() &&
686 screen->getBlackbox()->doXineramaPlacement()) {
687 RectList availableAreas = screen->allAvailableAreas();
688 RectList::iterator it, end = availableAreas.end();
689
690 for (it = availableAreas.begin(); it != end; ++it)
691 if (it->contains(rx, ry)) break;
692 assert(it != end); // the mouse isn't inside an area?
693 area = *it;
694 } else
695 #endif // XINERAMA
696 area = screen->availableArea();
697
698 x = rx - win.width() / 2;
699 y = ry - win.height() / 2;
700
701 if (x < area.x())
702 x = area.x();
703 if (y < area.y())
704 y = area.y();
705 if (x + win.width() > area.x() + area.width())
706 x = area.x() + area.width() - win.width();
707 if (y + win.height() > area.y() + area.height())
708 y = area.y() + area.height() - win.height();
709
710 win.setX(x);
711 win.setY(y);
712
713 return True;
714 }
715
716
717 bool Workspace::cascadePlacement(Rect &win) {
718 const Rect &availableArea = screen->availableArea();
719
720 if ((cascade_x > static_cast<signed>(availableArea.width() / 2)) ||
721 (cascade_y > static_cast<signed>(availableArea.height() / 2)))
722 cascade_x = cascade_y = 32;
723
724 if (cascade_x == 32) {
725 cascade_x += availableArea.x();
726 cascade_y += availableArea.y();
727 }
728
729 win.setPos(cascade_x, cascade_y);
730
731 return True;
732 }
733
734
735 void Workspace::placeWindow(BlackboxWindow *win) {
736 Rect new_win(0, 0, win->frameRect().width(), win->frameRect().height());
737 bool placed = False;
738
739 switch (screen->getPlacementPolicy()) {
740 case BScreen::RowSmartPlacement:
741 case BScreen::ColSmartPlacement:
742 placed = smartPlacement(new_win);
743 break;
744 case BScreen::UnderMousePlacement:
745 case BScreen::ClickMousePlacement:
746 placed = underMousePlacement(new_win);
747 default:
748 break; // handled below
749 } // switch
750
751 if (placed == False) {
752 cascadePlacement(new_win);
753 cascade_x += win->getTitleHeight() + (screen->getBorderWidth() * 2);
754 cascade_y += win->getTitleHeight() + (screen->getBorderWidth() * 2);
755 }
756
757 // make sure the placement was valid
758 assert(screen->availableArea().contains(new_win));
759
760 win->configure(new_win.x(), new_win.y(), new_win.width(), new_win.height());
761 }
This page took 0.078025 seconds and 5 git commands to generate.