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