]> Dogcows Code - chaz/openbox/blob - src/workspace.cc
new code for bindings/callbacks. much sexier. now passes python classes back to the...
[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 "bbscreen.hh"
31 #include "otk/util.hh"
32 #include "bbwindow.hh"
33 #include "workspace.hh"
34
35 namespace ob {
36
37 Workspace::Workspace(BScreen *scrn, unsigned int i) {
38 screen = scrn;
39 xatom = screen->getBlackbox()->getXAtom();
40
41 cascade_x = cascade_y = 0;
42 #ifdef XINERAMA
43 cascade_region = 0;
44 #endif // XINERAMA
45
46 id = i;
47
48 lastfocus = (BlackboxWindow *) 0;
49
50 readName();
51 }
52
53
54 void Workspace::addWindow(BlackboxWindow *w, bool place, bool sticky) {
55 assert(w != 0);
56
57 if (place) placeWindow(w);
58
59 stackingList.push_front(w);
60
61 if (! sticky)
62 w->setWorkspace(id);
63
64 if (! w->isNormal()) {
65 if (! sticky) {
66 // just give it some number, else bad things happen as it is assumed to
67 // not be on a workspace
68 w->setWindowNumber(0);
69 }
70 } else {
71 if (! sticky)
72 w->setWindowNumber(windowList.size());
73
74 windowList.push_back(w);
75
76 if (screen->doFocusNew() || (w->isTransient() && w->getTransientFor() &&
77 w->getTransientFor()->isFocused())) {
78 if (id != screen->getCurrentWorkspaceID()) {
79 /*
80 not on the focused workspace, so the window is not going to get focus
81 but if the user wants new windows focused, then it should get focus
82 when this workspace does become focused.
83 */
84 lastfocus = w;
85 }
86 }
87 }
88
89 if (! w->isDesktop())
90 raiseWindow(w);
91 else
92 lowerWindow(w);
93 }
94
95
96 void Workspace::removeWindow(BlackboxWindow *w, bool sticky) {
97 assert(w != 0);
98
99 stackingList.remove(w);
100
101 // pass focus to the next appropriate window
102 if ((w->isFocused() || w == lastfocus) &&
103 screen->getBlackbox()->state() != Openbox::State_Exiting) {
104 focusFallback(w);
105 }
106
107 if (! w->isNormal()) return;
108
109 BlackboxWindowList::iterator it, end = windowList.end();
110 int i;
111 for (i = 0, it = windowList.begin(); it != end; ++it, ++i)
112 if (*it == w)
113 break;
114 assert(it != end);
115
116 windowList.erase(it);
117 if (! sticky) {
118 BlackboxWindowList::iterator it = windowList.begin();
119 const BlackboxWindowList::iterator end = windowList.end();
120 unsigned int i = 0;
121 for (; it != end; ++it, ++i)
122 (*it)->setWindowNumber(i);
123 }
124
125 if (i == 0) {
126 cascade_x = cascade_y = 0;
127 #ifdef XINERAMA
128 cascade_region = 0;
129 #endif // XINERAMA
130 }
131 }
132
133
134 void Workspace::focusFallback(const BlackboxWindow *old_window) {
135 BlackboxWindow *newfocus = 0;
136
137 if (id == screen->getCurrentWorkspaceID()) {
138 // The window is on the visible workspace.
139
140 // if it's a transient, then try to focus its parent
141 if (old_window && old_window->isTransient()) {
142 newfocus = old_window->getTransientFor();
143
144 if (! newfocus ||
145 newfocus->isIconic() || // do not focus icons
146 newfocus->getWorkspaceNumber() != id || // or other workspaces
147 ! newfocus->setInputFocus())
148 newfocus = 0;
149 }
150
151 if (! newfocus) {
152 BlackboxWindowList::iterator it = stackingList.begin(),
153 end = stackingList.end();
154 for (; it != end; ++it) {
155 BlackboxWindow *tmp = *it;
156 if (tmp && tmp->isNormal() && tmp->setInputFocus()) {
157 // we found our new focus target
158 newfocus = tmp;
159 break;
160 }
161 }
162 }
163
164 screen->getBlackbox()->setFocusedWindow(newfocus);
165 } else {
166 // The window is not on the visible workspace.
167
168 if (old_window && lastfocus == old_window) {
169 // The window was the last-focus target, so we need to replace it.
170 BlackboxWindow *win = (BlackboxWindow*) 0;
171 if (! stackingList.empty())
172 win = stackingList.front();
173 setLastFocusedWindow(win);
174 }
175 }
176 }
177
178
179 void Workspace::removeAll(void) {
180 while (! windowList.empty())
181 windowList.front()->iconify();
182 }
183
184 void Workspace::showAll(void) {
185 BlackboxWindowList::iterator it = stackingList.begin();
186 const BlackboxWindowList::iterator end = stackingList.end();
187 for (; it != end; ++it) {
188 BlackboxWindow *bw = *it;
189 // sticky windows arent unmapped on a workspace change so we don't have ot
190 // map them, but sometimes on a restart, another app can unmap our sticky
191 // windows, so we map on startup always
192 if (! bw->isStuck() ||
193 screen->getBlackbox()->state() == Openbox::State_Starting)
194 bw->show();
195 }
196 }
197
198
199 void Workspace::hideAll(void) {
200 // withdraw in reverse order to minimize the number of Expose events
201
202 BlackboxWindowList lst(stackingList.rbegin(), stackingList.rend());
203
204 BlackboxWindowList::iterator it = lst.begin();
205 const BlackboxWindowList::iterator end = lst.end();
206 for (; it != end; ++it) {
207 BlackboxWindow *bw = *it;
208 // don't hide sticky windows, or they'll end up flickering on a workspace
209 // change
210 if (! bw->isStuck())
211 bw->withdraw();
212 }
213 }
214
215
216
217 /*
218 * returns the number of transients for win, plus the number of transients
219 * associated with each transient of win
220 */
221 static unsigned int countTransients(const BlackboxWindow * const win) {
222 BlackboxWindowList transients = win->getTransients();
223 if (transients.empty()) return 0;
224
225 unsigned int ret = transients.size();
226 BlackboxWindowList::const_iterator it = transients.begin(),
227 end = transients.end();
228 for (; it != end; ++it)
229 ret += countTransients(*it);
230
231 return ret;
232 }
233
234
235 /*
236 * puts the transients of win into the stack. windows are stacked above
237 * the window before it in the stackvector being iterated, meaning
238 * stack[0] is on bottom, stack[1] is above stack[0], stack[2] is above
239 * stack[1], etc...
240 */
241 void Workspace::raiseTransients(const BlackboxWindow * const win,
242 StackVector::iterator &stack) {
243 if (win->getTransients().empty()) return; // nothing to do
244
245 // put win's transients in the stack
246 BlackboxWindowList::const_iterator it, end = win->getTransients().end();
247 for (it = win->getTransients().begin(); it != end; ++it) {
248 BlackboxWindow *w = *it;
249 *stack++ = w->getFrameWindow();
250
251 if (! w->isIconic()) {
252 Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber());
253 wkspc->stackingList.remove(w);
254 wkspc->stackingList.push_front(w);
255 }
256 }
257
258 // put transients of win's transients in the stack
259 for (it = win->getTransients().begin(); it != end; ++it)
260 raiseTransients(*it, stack);
261 }
262
263
264 void Workspace::lowerTransients(const BlackboxWindow * const win,
265 StackVector::iterator &stack) {
266 if (win->getTransients().empty()) return; // nothing to do
267
268 // put transients of win's transients in the stack
269 BlackboxWindowList::const_reverse_iterator it,
270 end = win->getTransients().rend();
271 for (it = win->getTransients().rbegin(); it != end; ++it)
272 lowerTransients(*it, stack);
273
274 // put win's transients in the stack
275 for (it = win->getTransients().rbegin(); it != end; ++it) {
276 BlackboxWindow *w = *it;
277 *stack++ = w->getFrameWindow();
278
279 if (! w->isIconic()) {
280 Workspace *wkspc = screen->getWorkspace(w->getWorkspaceNumber());
281 wkspc->stackingList.remove(w);
282 wkspc->stackingList.push_back(w);
283 }
284 }
285 }
286
287
288 void Workspace::raiseWindow(BlackboxWindow *w) {
289 BlackboxWindow *win = w;
290
291 if (win->isDesktop()) return;
292
293 // walk up the transient_for's to the window that is not a transient
294 while (win->isTransient() && win->getTransientFor())
295 win = win->getTransientFor();
296
297 // get the total window count (win and all transients)
298 unsigned int i = 1 + countTransients(win);
299
300 // stack the window with all transients above
301 StackVector stack_vector(i);
302 StackVector::iterator stack = stack_vector.begin();
303
304 *(stack++) = win->getFrameWindow();
305 if (! (win->isIconic() || win->isDesktop())) {
306 Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber());
307 wkspc->stackingList.remove(win);
308 wkspc->stackingList.push_front(win);
309 }
310
311 raiseTransients(win, stack);
312
313 screen->raiseWindows(&stack_vector[0], stack_vector.size());
314 }
315
316
317 void Workspace::lowerWindow(BlackboxWindow *w) {
318 BlackboxWindow *win = w;
319
320 // walk up the transient_for's to the window that is not a transient
321 while (win->isTransient() && win->getTransientFor())
322 win = win->getTransientFor();
323
324 // get the total window count (win and all transients)
325 unsigned int i = 1 + countTransients(win);
326
327 // stack the window with all transients above
328 StackVector stack_vector(i);
329 StackVector::iterator stack = stack_vector.begin();
330
331 lowerTransients(win, stack);
332
333 *(stack++) = win->getFrameWindow();
334 if (! (win->isIconic() || win->isDesktop())) {
335 Workspace *wkspc = screen->getWorkspace(win->getWorkspaceNumber());
336 wkspc->stackingList.remove(win);
337 wkspc->stackingList.push_back(win);
338 }
339
340 screen->lowerWindows(&stack_vector[0], stack_vector.size());
341 }
342
343
344 void Workspace::reconfigure(void) {
345 std::for_each(windowList.begin(), windowList.end(),
346 std::mem_fun(&BlackboxWindow::reconfigure));
347 }
348
349
350 BlackboxWindow *Workspace::getWindow(unsigned int index) {
351 if (index < windowList.size()) {
352 BlackboxWindowList::iterator it = windowList.begin();
353 while (index-- > 0) // increment to index
354 ++it;
355 return *it;
356 }
357
358 return 0;
359 }
360
361
362 BlackboxWindow*
363 Workspace::getNextWindowInList(BlackboxWindow *w) {
364 BlackboxWindowList::iterator it = std::find(windowList.begin(),
365 windowList.end(),
366 w);
367 assert(it != windowList.end()); // window must be in list
368 ++it; // next window
369 if (it == windowList.end())
370 return windowList.front(); // if we walked off the end, wrap around
371
372 return *it;
373 }
374
375
376 BlackboxWindow* Workspace::getPrevWindowInList(BlackboxWindow *w) {
377 BlackboxWindowList::iterator it = std::find(windowList.begin(),
378 windowList.end(),
379 w);
380 assert(it != windowList.end()); // window must be in list
381 if (it == windowList.begin())
382 return windowList.back(); // if we walked of the front, wrap around
383
384 return *(--it);
385 }
386
387
388 BlackboxWindow* Workspace::getTopWindowOnStack(void) const {
389 assert(! stackingList.empty());
390 return stackingList.front();
391 }
392
393
394 unsigned int Workspace::getCount(void) const {
395 return windowList.size();
396 }
397
398
399 void Workspace::appendStackOrder(BlackboxWindowList &stack_order) const {
400 BlackboxWindowList::const_reverse_iterator it = stackingList.rbegin();
401 const BlackboxWindowList::const_reverse_iterator end = stackingList.rend();
402 for (; it != end; ++it)
403 // don't add desktop wnidows, or sticky windows more than once
404 if (! ( (*it)->isDesktop() ||
405 ((*it)->isStuck() && id != screen->getCurrentWorkspaceID())))
406 stack_order.push_back(*it);
407 }
408
409
410 bool Workspace::isCurrent(void) const {
411 return (id == screen->getCurrentWorkspaceID());
412 }
413
414
415 bool Workspace::isLastWindow(const BlackboxWindow *w) const {
416 return (w == windowList.back());
417 }
418
419
420 void Workspace::setCurrent(void) {
421 screen->changeWorkspaceID(id);
422 }
423
424
425 void Workspace::readName(void) {
426 otk::OBProperty::StringVect namesList;
427 unsigned long numnames = id + 1;
428
429 // attempt to get from the _NET_WM_DESKTOP_NAMES property
430 if (xatom->get(screen->getRootWindow(), otk::OBProperty::net_desktop_names,
431 otk::OBProperty::utf8, &numnames, &namesList) &&
432 namesList.size() > id) {
433 name = namesList[id];
434
435 } else {
436 /*
437 Use a default name. This doesn't actually change the class. That will
438 happen after the setName changes the root property, and that change
439 makes its way back to this function.
440 */
441 string tmp = "Workspace %d";
442 assert(tmp.length() < 32);
443 char default_name[32];
444 sprintf(default_name, tmp.c_str(), id + 1);
445
446 setName(default_name); // save this into the _NET_WM_DESKTOP_NAMES property
447 }
448 }
449
450
451 void Workspace::setName(const string& new_name) {
452 // set the _NET_WM_DESKTOP_NAMES property with the new name
453 otk::OBProperty::StringVect namesList;
454 unsigned long numnames = (unsigned) -1;
455 if (xatom->get(screen->getRootWindow(),
456 otk::OBProperty::net_desktop_names,
457 otk::OBProperty::utf8, &numnames, &namesList) &&
458 namesList.size() > id)
459 namesList[id] = new_name;
460 else
461 namesList.push_back(new_name);
462
463 xatom->set(screen->getRootWindow(), otk::OBProperty::net_desktop_names,
464 otk::OBProperty::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->getWindowStyle()->getBorderWidth(),
609 curr->frameRect().height() + screen->getWindowStyle()->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->getWindowStyle()->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.069347 seconds and 4 git commands to generate.