moved placement strategies to different PlacementStrategy classes
This commit is contained in:
parent
d099e7673a
commit
b772fd969f
15 changed files with 905 additions and 366 deletions
75
src/CascadePlacement.cc
Normal file
75
src/CascadePlacement.cc
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// CascadePlacement.cc
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#include "CascadePlacement.hh"
|
||||||
|
|
||||||
|
#include "Window.hh"
|
||||||
|
#include "Screen.hh"
|
||||||
|
|
||||||
|
CascadePlacement::CascadePlacement(const BScreen &screen) {
|
||||||
|
// +1 ?
|
||||||
|
m_cascade_x = new int[screen.numHeads() + 1];
|
||||||
|
m_cascade_y = new int[screen.numHeads() + 1];
|
||||||
|
for (int i=0; i < screen.numHeads() + 1; i++) {
|
||||||
|
m_cascade_x[i] = 32 + screen.getHeadX(i);
|
||||||
|
m_cascade_y[i] = 32 + screen.getHeadY(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CascadePlacement::~CascadePlacement() {
|
||||||
|
delete [] m_cascade_x;
|
||||||
|
delete [] m_cascade_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CascadePlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist,
|
||||||
|
const FluxboxWindow &win,
|
||||||
|
int &place_x, int &place_y) {
|
||||||
|
|
||||||
|
int head = (signed) win.screen().getCurrHead();
|
||||||
|
int head_left = (signed) win.screen().maxLeft(head);
|
||||||
|
int head_right = (signed) win.screen().maxRight(head);
|
||||||
|
int head_top = (signed) win.screen().maxTop(head);
|
||||||
|
int head_bot = (signed) win.screen().maxBottom(head);
|
||||||
|
|
||||||
|
if ((m_cascade_x[head] > ((head_left + head_right) / 2)) ||
|
||||||
|
(m_cascade_y[head] > ((head_top + head_bot) / 2))) {
|
||||||
|
m_cascade_x[head] = head_left + 32;
|
||||||
|
m_cascade_y[head] = head_top + 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
place_x = m_cascade_x[head];
|
||||||
|
place_y = m_cascade_y[head];
|
||||||
|
|
||||||
|
// just one borderwidth, so they can share a borderwidth (looks better)
|
||||||
|
int titlebar_height =
|
||||||
|
win.titlebarHeight() + win.fbWindow().borderWidth();
|
||||||
|
if (titlebar_height < 4) // make sure it is not insignificant
|
||||||
|
titlebar_height = 32;
|
||||||
|
|
||||||
|
m_cascade_x[head] += titlebar_height;
|
||||||
|
m_cascade_y[head] += titlebar_height;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
45
src/CascadePlacement.hh
Normal file
45
src/CascadePlacement.hh
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// CascadePlacement.hh
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#ifndef CASCADEPLACEMENT_HH
|
||||||
|
#define CASCADEPLACEMENT_HH
|
||||||
|
|
||||||
|
#include "PlacementStrategy.hh"
|
||||||
|
#include "FbTk/NotCopyable.hh"
|
||||||
|
|
||||||
|
class BScreen;
|
||||||
|
|
||||||
|
class CascadePlacement: public PlacementStrategy,
|
||||||
|
private FbTk::NotCopyable {
|
||||||
|
public:
|
||||||
|
explicit CascadePlacement(const BScreen &screen);
|
||||||
|
~CascadePlacement();
|
||||||
|
bool placeWindow(const std::vector<FluxboxWindow *> &windowlist,
|
||||||
|
const FluxboxWindow &window,
|
||||||
|
int &place_x, int &place_y);
|
||||||
|
private:
|
||||||
|
int *m_cascade_x; ///< need a cascade for each head (Xinerama)
|
||||||
|
int *m_cascade_y; ///< need a cascade for each head (Xinerama)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CASCADEPLACEMENT_HH
|
136
src/ColSmartPlacement.cc
Normal file
136
src/ColSmartPlacement.cc
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
// ColSmartPlacement.cc
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#include "ColSmartPlacement.hh"
|
||||||
|
|
||||||
|
#include "Screen.hh"
|
||||||
|
#include "ScreenPlacement.hh"
|
||||||
|
#include "Window.hh"
|
||||||
|
|
||||||
|
bool ColSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist,
|
||||||
|
const FluxboxWindow &win,
|
||||||
|
int &place_x, int &place_y) {
|
||||||
|
|
||||||
|
// xinerama head constraints
|
||||||
|
int head = (signed) win.screen().getCurrHead();
|
||||||
|
int head_left = (signed) win.screen().maxLeft(head);
|
||||||
|
int head_right = (signed) win.screen().maxRight(head);
|
||||||
|
int head_top = (signed) win.screen().maxTop(head);
|
||||||
|
int head_bot = (signed) win.screen().maxBottom(head);
|
||||||
|
|
||||||
|
bool placed = false;
|
||||||
|
int next_x, next_y;
|
||||||
|
const ScreenPlacement &screen_placement =
|
||||||
|
dynamic_cast<const ScreenPlacement &>(win.screen().placementStrategy());
|
||||||
|
|
||||||
|
bool top_bot = screen_placement.colDirection() == ScreenPlacement::TOPBOTTOM;
|
||||||
|
bool left_right = screen_placement.rowDirection() == ScreenPlacement::LEFTRIGHT;
|
||||||
|
|
||||||
|
int test_x;
|
||||||
|
|
||||||
|
int win_w = win.width() + win.fbWindow().borderWidth()*2;
|
||||||
|
int win_h = win.height() + win.fbWindow().borderWidth()*2;
|
||||||
|
|
||||||
|
if (left_right)
|
||||||
|
test_x = head_left;
|
||||||
|
else
|
||||||
|
test_x = head_right - win_w;
|
||||||
|
|
||||||
|
int change_y = 1;
|
||||||
|
if (screen_placement.colDirection() == ScreenPlacement::BOTTOMTOP)
|
||||||
|
change_y = -1;
|
||||||
|
|
||||||
|
while (!placed &&
|
||||||
|
(left_right ? test_x + win_w <= head_right
|
||||||
|
: test_x >= head_left)) {
|
||||||
|
|
||||||
|
if (left_right)
|
||||||
|
next_x = head_right; // it will get shrunk
|
||||||
|
else
|
||||||
|
next_x = head_left-1;
|
||||||
|
|
||||||
|
int test_y;
|
||||||
|
if (top_bot)
|
||||||
|
test_y = head_top;
|
||||||
|
else
|
||||||
|
test_y = head_bot - win_h;
|
||||||
|
|
||||||
|
while (!placed &&
|
||||||
|
(top_bot ? test_y + win_h <= head_bot
|
||||||
|
: test_y >= head_top)) {
|
||||||
|
placed = true;
|
||||||
|
|
||||||
|
next_y = test_y + change_y;
|
||||||
|
|
||||||
|
std::vector<FluxboxWindow *>::const_iterator it =
|
||||||
|
windowlist.begin();
|
||||||
|
std::vector<FluxboxWindow *>::const_iterator it_end =
|
||||||
|
windowlist.end();
|
||||||
|
for (; it != it_end && placed; ++it) {
|
||||||
|
int curr_x = (*it)->x();
|
||||||
|
int curr_y = (*it)->y();
|
||||||
|
int curr_w = (*it)->width() + (*it)->fbWindow().borderWidth()*2;
|
||||||
|
int curr_h = (*it)->height() + (*it)->fbWindow().borderWidth()*2;
|
||||||
|
|
||||||
|
if (curr_x < test_x + win_w &&
|
||||||
|
curr_x + curr_w > test_x &&
|
||||||
|
curr_y < test_y + win_h &&
|
||||||
|
curr_y + curr_h > test_y) {
|
||||||
|
// this window is in the way
|
||||||
|
placed = false;
|
||||||
|
|
||||||
|
// we find the next y that we can go to (a window will be in the way
|
||||||
|
// all the way to its bottom)
|
||||||
|
if (top_bot) {
|
||||||
|
if (curr_y + curr_h > next_y)
|
||||||
|
next_y = curr_y + curr_h;
|
||||||
|
} else {
|
||||||
|
if (curr_y - win_h < next_y)
|
||||||
|
next_y = curr_y - win_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// but we can only go to the nearest x, since that is where the
|
||||||
|
// next time current windows in the way will change
|
||||||
|
if (left_right) {
|
||||||
|
if (curr_x + curr_w < next_x)
|
||||||
|
next_x = curr_x + curr_w;
|
||||||
|
} else {
|
||||||
|
if (curr_x - win_w > next_x)
|
||||||
|
next_x = curr_x - win_w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (placed) {
|
||||||
|
place_x = test_x;
|
||||||
|
place_y = test_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_y = next_y;
|
||||||
|
} // end while
|
||||||
|
|
||||||
|
test_x = next_x;
|
||||||
|
} // end while
|
||||||
|
|
||||||
|
return placed;
|
||||||
|
}
|
36
src/ColSmartPlacement.hh
Normal file
36
src/ColSmartPlacement.hh
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// ColSmartPlacement.hh
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#ifndef COLSMARTPLACEMENT_HH
|
||||||
|
#define COLSMARTPLACEMENT_HH
|
||||||
|
|
||||||
|
#include "PlacementStrategy.hh"
|
||||||
|
|
||||||
|
class ColSmartPlacement: public PlacementStrategy {
|
||||||
|
public:
|
||||||
|
bool placeWindow(const std::vector<FluxboxWindow *> &windowlist,
|
||||||
|
const FluxboxWindow &win,
|
||||||
|
int &place_x, int &place_y);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COLSMARTPLACEMENT_HH
|
|
@ -128,6 +128,11 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
|
||||||
Resources.cc \
|
Resources.cc \
|
||||||
WindowCmd.hh WindowCmd.cc \
|
WindowCmd.hh WindowCmd.cc \
|
||||||
FocusControl.hh FocusControl.cc \
|
FocusControl.hh FocusControl.cc \
|
||||||
|
CascadePlacement.hh CascadePlacement.cc \
|
||||||
|
ColSmartPlacement.hh ColSmartPlacement.cc \
|
||||||
|
RowSmartPlacement.hh RowSmartPlacement.cc \
|
||||||
|
ScreenPlacement.hh ScreenPlacement.cc \
|
||||||
|
UnderMousePlacement.hh UnderMousePlacement.cc \
|
||||||
${newwmspec_SOURCE} ${gnome_SOURCE} \
|
${newwmspec_SOURCE} ${gnome_SOURCE} \
|
||||||
${REMEMBER_SOURCE} ${TOOLBAR_SOURCE}
|
${REMEMBER_SOURCE} ${TOOLBAR_SOURCE}
|
||||||
|
|
||||||
|
|
155
src/RowSmartPlacement.cc
Normal file
155
src/RowSmartPlacement.cc
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
// RowSmartPlacement.cc
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#include "RowSmartPlacement.hh"
|
||||||
|
|
||||||
|
#include "Window.hh"
|
||||||
|
#include "Screen.hh"
|
||||||
|
#include "ScreenPlacement.hh"
|
||||||
|
|
||||||
|
bool RowSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist,
|
||||||
|
const FluxboxWindow &win,
|
||||||
|
int &place_x, int &place_y) {
|
||||||
|
|
||||||
|
bool placed = false;
|
||||||
|
int next_x, next_y;
|
||||||
|
|
||||||
|
// view (screen + head) constraints
|
||||||
|
int head = (signed) win.screen().getCurrHead();
|
||||||
|
int head_left = (signed) win.screen().maxLeft(head);
|
||||||
|
int head_right = (signed) win.screen().maxRight(head);
|
||||||
|
int head_top = (signed) win.screen().maxTop(head);
|
||||||
|
int head_bot = (signed) win.screen().maxBottom(head);
|
||||||
|
|
||||||
|
const ScreenPlacement &screen_placement =
|
||||||
|
dynamic_cast<const ScreenPlacement &>(win.screen().placementStrategy());
|
||||||
|
|
||||||
|
bool top_bot =
|
||||||
|
screen_placement.colDirection() == ScreenPlacement::TOPBOTTOM;
|
||||||
|
bool left_right =
|
||||||
|
screen_placement.rowDirection() == ScreenPlacement::LEFTRIGHT;
|
||||||
|
|
||||||
|
int change_x = 1, change_y = 1;
|
||||||
|
|
||||||
|
if (screen_placement.colDirection() == ScreenPlacement::BOTTOMTOP)
|
||||||
|
change_y = -1;
|
||||||
|
|
||||||
|
if (screen_placement.rowDirection() == ScreenPlacement::RIGHTLEFT)
|
||||||
|
change_x = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int win_h = win.height() + win.fbWindow().borderWidth()*2;
|
||||||
|
int win_w = win.width() + win.fbWindow().borderWidth()*2;
|
||||||
|
int test_y;
|
||||||
|
if (top_bot)
|
||||||
|
test_y = head_top;
|
||||||
|
else
|
||||||
|
test_y = head_bot - win_h;
|
||||||
|
|
||||||
|
while (!placed &&
|
||||||
|
(top_bot ? test_y + win_h <= head_bot
|
||||||
|
: test_y >= head_top)) {
|
||||||
|
|
||||||
|
int test_x;
|
||||||
|
if (left_right)
|
||||||
|
test_x = head_left;
|
||||||
|
else
|
||||||
|
test_x = head_right - win_w;
|
||||||
|
|
||||||
|
// The trick here is that we set it to the furthest away one,
|
||||||
|
// then the code brings it back down to the safest one that
|
||||||
|
// we can go to (i.e. the next untested area)
|
||||||
|
if (top_bot)
|
||||||
|
next_y = head_bot; // will be shrunk
|
||||||
|
else
|
||||||
|
next_y = head_top-1;
|
||||||
|
|
||||||
|
while (!placed &&
|
||||||
|
(left_right ? test_x + win_w <= head_right
|
||||||
|
: test_x >= head_left)) {
|
||||||
|
|
||||||
|
placed = true;
|
||||||
|
|
||||||
|
next_x = test_x + change_x;
|
||||||
|
|
||||||
|
std::vector<FluxboxWindow *>::const_iterator win_it =
|
||||||
|
windowlist.begin();
|
||||||
|
std::vector<FluxboxWindow *>::const_iterator win_it_end =
|
||||||
|
windowlist.end();
|
||||||
|
|
||||||
|
for (; win_it != win_it_end && placed; ++win_it) {
|
||||||
|
FluxboxWindow &window = **win_it;
|
||||||
|
|
||||||
|
int curr_x = window.x();
|
||||||
|
int curr_y = window.y();
|
||||||
|
int curr_w = window.width() + window.fbWindow().borderWidth()*2;
|
||||||
|
int curr_h = window.height() + window.fbWindow().borderWidth()*2;
|
||||||
|
|
||||||
|
if (curr_x < test_x + win_w &&
|
||||||
|
curr_x + curr_w > test_x &&
|
||||||
|
curr_y < test_y + win_h &&
|
||||||
|
curr_y + curr_h > test_y) {
|
||||||
|
// this window is in the way
|
||||||
|
placed = false;
|
||||||
|
|
||||||
|
// we find the next x that we can go to (a window will be in the way
|
||||||
|
// all the way to its far side)
|
||||||
|
if (left_right) {
|
||||||
|
if (curr_x + curr_w > next_x)
|
||||||
|
next_x = curr_x + curr_w;
|
||||||
|
} else {
|
||||||
|
if (curr_x - win_w < next_x)
|
||||||
|
next_x = curr_x - win_w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// but we can only go to the nearest y, since that is where the
|
||||||
|
// next time current windows in the way will change
|
||||||
|
if (top_bot) {
|
||||||
|
if (curr_y + curr_h < next_y)
|
||||||
|
next_y = curr_y + curr_h;
|
||||||
|
} else {
|
||||||
|
if (curr_y - win_h > next_y)
|
||||||
|
next_y = curr_y - win_h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (placed) {
|
||||||
|
place_x = test_x;
|
||||||
|
place_y = test_y;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
test_x = next_x;
|
||||||
|
} // end while
|
||||||
|
|
||||||
|
test_y = next_y;
|
||||||
|
} // end while
|
||||||
|
|
||||||
|
|
||||||
|
return placed;
|
||||||
|
}
|
37
src/RowSmartPlacement.hh
Normal file
37
src/RowSmartPlacement.hh
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// RowSmartPlacement.hh
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#ifndef ROWSMARTPLACEMENT_HH
|
||||||
|
#define ROWSMARTPLACEMENT_HH
|
||||||
|
|
||||||
|
#include "PlacementStrategy.hh"
|
||||||
|
|
||||||
|
class RowSmartPlacement: public PlacementStrategy {
|
||||||
|
public:
|
||||||
|
bool placeWindow(const std::vector<FluxboxWindow *> &windowlist,
|
||||||
|
const FluxboxWindow &win,
|
||||||
|
int &place_x, int &place_y);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ROWSMARTPLACEMENT_HH
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "Netizen.hh"
|
#include "Netizen.hh"
|
||||||
|
|
||||||
#include "FocusControl.hh"
|
#include "FocusControl.hh"
|
||||||
|
#include "ScreenPlacement.hh"
|
||||||
|
|
||||||
// themes
|
// themes
|
||||||
#include "FbWinFrameTheme.hh"
|
#include "FbWinFrameTheme.hh"
|
||||||
|
@ -184,9 +185,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
|
||||||
menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"),
|
menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"),
|
||||||
menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"),
|
menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"),
|
||||||
menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode"),
|
menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode"),
|
||||||
placement_policy(rm, ROWSMARTPLACEMENT, scrname+".windowPlacement", altscrname+".WindowPlacement"),
|
|
||||||
row_direction(rm, LEFTRIGHT, scrname+".rowPlacementDirection", altscrname+".RowPlacementDirection"),
|
|
||||||
col_direction(rm, TOPBOTTOM, scrname+".colPlacementDirection", altscrname+".ColPlacementDirection"),
|
|
||||||
gc_line_width(rm, 1, scrname+".overlay.lineWidth", altscrname+".Overlay.LineWidth"),
|
gc_line_width(rm, 1, scrname+".overlay.lineWidth", altscrname+".Overlay.LineWidth"),
|
||||||
gc_line_style(rm,
|
gc_line_style(rm,
|
||||||
FbTk::GContext::LINESOLID,
|
FbTk::GContext::LINESOLID,
|
||||||
|
@ -238,6 +237,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
||||||
m_name(screenname),
|
m_name(screenname),
|
||||||
m_altname(altscreenname),
|
m_altname(altscreenname),
|
||||||
m_focus_control(new FocusControl(*this)),
|
m_focus_control(new FocusControl(*this)),
|
||||||
|
m_placement_strategy(new ScreenPlacement(*this)),
|
||||||
m_xinerama_headinfo(0),
|
m_xinerama_headinfo(0),
|
||||||
m_shutdown(false) {
|
m_shutdown(false) {
|
||||||
|
|
||||||
|
@ -446,7 +446,10 @@ BScreen::~BScreen() {
|
||||||
|
|
||||||
// TODO fluxgen: check if this is the right place
|
// TODO fluxgen: check if this is the right place
|
||||||
delete [] m_head_areas;
|
delete [] m_head_areas;
|
||||||
|
|
||||||
delete m_focus_control;
|
delete m_focus_control;
|
||||||
|
delete m_placement_strategy;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BScreen::initWindows() {
|
void BScreen::initWindows() {
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "FbRootWindow.hh"
|
#include "FbRootWindow.hh"
|
||||||
#include "MenuTheme.hh"
|
#include "MenuTheme.hh"
|
||||||
|
#include "PlacementStrategy.hh"
|
||||||
|
|
||||||
#include "FbTk/Resource.hh"
|
#include "FbTk/Resource.hh"
|
||||||
#include "FbTk/Subject.hh"
|
#include "FbTk/Subject.hh"
|
||||||
|
@ -63,6 +64,7 @@ class Strut;
|
||||||
class Slit;
|
class Slit;
|
||||||
class HeadArea;
|
class HeadArea;
|
||||||
class FocusControl;
|
class FocusControl;
|
||||||
|
class PlacementStrategy;
|
||||||
|
|
||||||
namespace FbTk {
|
namespace FbTk {
|
||||||
class Menu;
|
class Menu;
|
||||||
|
@ -90,15 +92,6 @@ public:
|
||||||
QUADRANTRESIZE,
|
QUADRANTRESIZE,
|
||||||
DEFAULTRESIZE = BOTTOMRESIZE };
|
DEFAULTRESIZE = BOTTOMRESIZE };
|
||||||
|
|
||||||
enum PlacementPolicy {
|
|
||||||
ROWSMARTPLACEMENT,
|
|
||||||
COLSMARTPLACEMENT,
|
|
||||||
CASCADEPLACEMENT,
|
|
||||||
UNDERMOUSEPLACEMENT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum RowDirection { LEFTRIGHT, RIGHTLEFT};
|
|
||||||
enum ColumnDirection { TOPBOTTOM, BOTTOMTOP};
|
|
||||||
|
|
||||||
typedef std::vector<FluxboxWindow *> Icons;
|
typedef std::vector<FluxboxWindow *> Icons;
|
||||||
|
|
||||||
|
@ -218,10 +211,7 @@ public:
|
||||||
/// hide all windowmenus except the given one (if given)
|
/// hide all windowmenus except the given one (if given)
|
||||||
void hideWindowMenus(const FluxboxWindow* except= 0);
|
void hideWindowMenus(const FluxboxWindow* except= 0);
|
||||||
|
|
||||||
inline PlacementPolicy getPlacementPolicy() const { return *resource.placement_policy; }
|
|
||||||
inline int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; }
|
inline int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; }
|
||||||
inline RowDirection getRowPlacementDirection() const { return *resource.row_direction; }
|
|
||||||
inline ColumnDirection getColPlacementDirection() const { return *resource.col_direction; }
|
|
||||||
|
|
||||||
void setRootColormapInstalled(bool r) { root_colormap_installed = r; }
|
void setRootColormapInstalled(bool r) { root_colormap_installed = r; }
|
||||||
void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; }
|
void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; }
|
||||||
|
@ -249,7 +239,9 @@ public:
|
||||||
const std::string &altName() const { return m_altname; }
|
const std::string &altName() const { return m_altname; }
|
||||||
bool isShuttingdown() const { return m_shutdown; }
|
bool isShuttingdown() const { return m_shutdown; }
|
||||||
|
|
||||||
|
PlacementStrategy &placementStrategy() { return *m_placement_strategy; }
|
||||||
|
const PlacementStrategy &placementStrategy() const { return *m_placement_strategy; }
|
||||||
|
|
||||||
int addWorkspace();
|
int addWorkspace();
|
||||||
int removeLastWorkspace();
|
int removeLastWorkspace();
|
||||||
// scroll workspaces
|
// scroll workspaces
|
||||||
|
@ -442,9 +434,7 @@ private:
|
||||||
FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha,
|
FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha,
|
||||||
unfocused_alpha, menu_alpha, menu_delay, menu_delay_close;
|
unfocused_alpha, menu_alpha, menu_delay, menu_delay_close;
|
||||||
FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode;
|
FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode;
|
||||||
FbTk::Resource<PlacementPolicy> placement_policy;
|
|
||||||
FbTk::Resource<RowDirection> row_direction;
|
|
||||||
FbTk::Resource<ColumnDirection> col_direction;
|
|
||||||
FbTk::Resource<int> gc_line_width;
|
FbTk::Resource<int> gc_line_width;
|
||||||
FbTk::Resource<FbTk::GContext::LineStyle> gc_line_style;
|
FbTk::Resource<FbTk::GContext::LineStyle> gc_line_style;
|
||||||
FbTk::Resource<FbTk::GContext::JoinStyle> gc_join_style;
|
FbTk::Resource<FbTk::GContext::JoinStyle> gc_join_style;
|
||||||
|
@ -458,6 +448,7 @@ private:
|
||||||
const std::string m_name, m_altname;
|
const std::string m_name, m_altname;
|
||||||
|
|
||||||
FocusControl *m_focus_control;
|
FocusControl *m_focus_control;
|
||||||
|
PlacementStrategy *m_placement_strategy;
|
||||||
|
|
||||||
// This is a map of windows to clients for clients that had a left
|
// This is a map of windows to clients for clients that had a left
|
||||||
// window set, but that window wasn't present at the time
|
// window set, but that window wasn't present at the time
|
||||||
|
|
207
src/ScreenPlacement.cc
Normal file
207
src/ScreenPlacement.cc
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
// ScreenPlacement.cc
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#include "ScreenPlacement.hh"
|
||||||
|
|
||||||
|
|
||||||
|
#include "RowSmartPlacement.hh"
|
||||||
|
#include "UnderMousePlacement.hh"
|
||||||
|
#include "ColSmartPlacement.hh"
|
||||||
|
#include "CascadePlacement.hh"
|
||||||
|
|
||||||
|
#include "Screen.hh"
|
||||||
|
#include "Window.hh"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <exception>
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
|
ScreenPlacement::ScreenPlacement(BScreen &screen):
|
||||||
|
m_row_direction(screen.resourceManager(), LEFTRIGHT,
|
||||||
|
screen.name()+".rowPlacementDirection",
|
||||||
|
screen.altName()+".RowPlacementDirection"),
|
||||||
|
m_col_direction(screen.resourceManager(), TOPBOTTOM,
|
||||||
|
screen.name()+".colPlacementDirection",
|
||||||
|
screen.altName()+".ColPlacementDirection"),
|
||||||
|
m_placement_policy(screen.resourceManager(), ROWSMARTPLACEMENT,
|
||||||
|
screen.name()+".windowPlacement",
|
||||||
|
screen.altName()+".WindowPlacement"),
|
||||||
|
m_old_policy(*m_placement_policy),
|
||||||
|
m_strategy(new RowSmartPlacement())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScreenPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist,
|
||||||
|
const FluxboxWindow &win,
|
||||||
|
int &place_x, int &place_y) {
|
||||||
|
|
||||||
|
// check the resource placement and see if has changed
|
||||||
|
// and if so update the strategy
|
||||||
|
if (m_old_policy != *m_placement_policy) {
|
||||||
|
m_old_policy = *m_placement_policy;
|
||||||
|
switch (*m_placement_policy) {
|
||||||
|
case ROWSMARTPLACEMENT:
|
||||||
|
m_strategy.reset(new RowSmartPlacement());
|
||||||
|
break;
|
||||||
|
case COLSMARTPLACEMENT:
|
||||||
|
m_strategy.reset(new ColSmartPlacement());
|
||||||
|
break;
|
||||||
|
case CASCADEPLACEMENT:
|
||||||
|
m_strategy.reset(new CascadePlacement(win.screen()));
|
||||||
|
break;
|
||||||
|
case UNDERMOUSEPLACEMENT:
|
||||||
|
m_strategy.reset(new UnderMousePlacement());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// view (screen + head) constraints
|
||||||
|
int head = (signed) win.screen().getCurrHead();
|
||||||
|
int head_left = (signed) win.screen().maxLeft(head);
|
||||||
|
int head_right = (signed) win.screen().maxRight(head);
|
||||||
|
int head_top = (signed) win.screen().maxTop(head);
|
||||||
|
int head_bot = (signed) win.screen().maxBottom(head);
|
||||||
|
|
||||||
|
// start placement, top left corner
|
||||||
|
place_x = head_left;
|
||||||
|
place_y = head_top;
|
||||||
|
|
||||||
|
bool placed = false;
|
||||||
|
try {
|
||||||
|
placed = m_strategy->placeWindow(windowlist,
|
||||||
|
win,
|
||||||
|
place_x, place_y);
|
||||||
|
} catch (std::bad_cast cast) {
|
||||||
|
// This should not happen.
|
||||||
|
// If for some reason we change the PlacementStrategy in Screen
|
||||||
|
// from ScreenPlacement to something else then we might get
|
||||||
|
// bad_cast from some placement strategies.
|
||||||
|
cerr<<"Failed to place window: "<<cast.what()<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!placed) {
|
||||||
|
// Create fallback strategy, when we need it the first time
|
||||||
|
// This strategy must succeed!
|
||||||
|
if (m_fallback_strategy.get() == 0)
|
||||||
|
m_fallback_strategy.reset(new CascadePlacement(win.screen()));
|
||||||
|
|
||||||
|
m_fallback_strategy->placeWindow(windowlist,
|
||||||
|
win,
|
||||||
|
place_x, place_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int win_w = win.width() + win.fbWindow().borderWidth()*2,
|
||||||
|
win_h = win.height() + win.fbWindow().borderWidth()*2;
|
||||||
|
|
||||||
|
|
||||||
|
// make sure the window is inside our screen(head) area
|
||||||
|
if (place_x + win_w > head_right)
|
||||||
|
place_x = (head_right - win_w) / 2;
|
||||||
|
if (place_y + win_h > head_bot)
|
||||||
|
place_y = (head_bot - win_h) / 2;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////// Placement Resources
|
||||||
|
template <>
|
||||||
|
void FbTk::Resource<ScreenPlacement::PlacementPolicy>::setFromString(const char *str) {
|
||||||
|
if (strcasecmp("RowSmartPlacement", str) == 0)
|
||||||
|
*(*this) = ScreenPlacement::ROWSMARTPLACEMENT;
|
||||||
|
else if (strcasecmp("ColSmartPlacement", str) == 0)
|
||||||
|
*(*this) = ScreenPlacement::COLSMARTPLACEMENT;
|
||||||
|
else if (strcasecmp("UnderMousePlacement", str) == 0)
|
||||||
|
*(*this) = ScreenPlacement::UNDERMOUSEPLACEMENT;
|
||||||
|
else if (strcasecmp("CascadePlacement", str) == 0)
|
||||||
|
*(*this) = ScreenPlacement::CASCADEPLACEMENT;
|
||||||
|
else
|
||||||
|
setDefaultValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string FbTk::Resource<ScreenPlacement::PlacementPolicy>::getString() const {
|
||||||
|
switch (*(*this)) {
|
||||||
|
case ScreenPlacement::ROWSMARTPLACEMENT:
|
||||||
|
return "RowSmartPlacement";
|
||||||
|
case ScreenPlacement::COLSMARTPLACEMENT:
|
||||||
|
return "ColSmartPlacement";
|
||||||
|
case ScreenPlacement::UNDERMOUSEPLACEMENT:
|
||||||
|
return "UnderMousePlacement";
|
||||||
|
case ScreenPlacement::CASCADEPLACEMENT:
|
||||||
|
return "CascadePlacement";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "RowSmartPlacement";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FbTk::Resource<ScreenPlacement::RowDirection>::setFromString(const char *str) {
|
||||||
|
if (strcasecmp("LeftToRight", str) == 0)
|
||||||
|
*(*this) = ScreenPlacement::LEFTRIGHT;
|
||||||
|
else if (strcasecmp("RightToLeft", str) == 0)
|
||||||
|
*(*this) = ScreenPlacement::RIGHTLEFT;
|
||||||
|
else
|
||||||
|
setDefaultValue();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string FbTk::Resource<ScreenPlacement::RowDirection>::getString() const {
|
||||||
|
switch (*(*this)) {
|
||||||
|
case ScreenPlacement::LEFTRIGHT:
|
||||||
|
return "LeftToRight";
|
||||||
|
case ScreenPlacement::RIGHTLEFT:
|
||||||
|
return "RightToLeft";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "LeftToRight";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FbTk::Resource<ScreenPlacement::ColumnDirection>::setFromString(const char *str) {
|
||||||
|
if (strcasecmp("TopToBottom", str) == 0)
|
||||||
|
*(*this) = ScreenPlacement::TOPBOTTOM;
|
||||||
|
else if (strcasecmp("BottomToTop", str) == 0)
|
||||||
|
*(*this) = ScreenPlacement::BOTTOMTOP;
|
||||||
|
else
|
||||||
|
setDefaultValue();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string FbTk::Resource<ScreenPlacement::ColumnDirection>::getString() const {
|
||||||
|
switch (*(*this)) {
|
||||||
|
case ScreenPlacement::TOPBOTTOM:
|
||||||
|
return "TopToBottom";
|
||||||
|
case ScreenPlacement::BOTTOMTOP:
|
||||||
|
return "BottomToTop";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "TopToBottom";
|
||||||
|
}
|
77
src/ScreenPlacement.hh
Normal file
77
src/ScreenPlacement.hh
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// ScreenPlacement.hh
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#ifndef SCREENPLACEMENT_HH
|
||||||
|
#define SCREENPLACEMENT_HH
|
||||||
|
|
||||||
|
#include "PlacementStrategy.hh"
|
||||||
|
#include "FbTk/Resource.hh"
|
||||||
|
|
||||||
|
class BScreen;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main class for strategy handling
|
||||||
|
* This is a bridge between screen and
|
||||||
|
* the real placement strategy (rowcol, undermouse etc)
|
||||||
|
* The placeWindow function in this class is guaranteed to succeed.
|
||||||
|
* It holds a pointer to the real placement strategy which is
|
||||||
|
* called upon placeWindow, it also holds the placement resources
|
||||||
|
*/
|
||||||
|
class ScreenPlacement: public PlacementStrategy {
|
||||||
|
public:
|
||||||
|
enum PlacementPolicy {
|
||||||
|
ROWSMARTPLACEMENT,
|
||||||
|
COLSMARTPLACEMENT,
|
||||||
|
CASCADEPLACEMENT,
|
||||||
|
UNDERMOUSEPLACEMENT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RowDirection {
|
||||||
|
LEFTRIGHT, ///< from left to right
|
||||||
|
RIGHTLEFT ///< from right to left
|
||||||
|
};
|
||||||
|
enum ColumnDirection {
|
||||||
|
TOPBOTTOM, ///< from top to bottom
|
||||||
|
BOTTOMTOP ///< from bottom to top
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit ScreenPlacement(BScreen &screen);
|
||||||
|
/// placeWindow is guaranteed to succeed, ignore return value
|
||||||
|
/// @return true
|
||||||
|
bool placeWindow(const std::vector<FluxboxWindow *> &windowlist,
|
||||||
|
const FluxboxWindow &window,
|
||||||
|
int &place_x, int &place_y);
|
||||||
|
|
||||||
|
RowDirection rowDirection() const { return *m_row_direction; }
|
||||||
|
ColumnDirection colDirection() const { return *m_col_direction; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
FbTk::Resource<RowDirection> m_row_direction; ///< row direction resource
|
||||||
|
FbTk::Resource<ColumnDirection> m_col_direction; ///< column direction resource
|
||||||
|
FbTk::Resource<PlacementPolicy> m_placement_policy; ///< placement policy resource
|
||||||
|
PlacementPolicy m_old_policy; ///< holds old policy, used to determine if resources has changed
|
||||||
|
std::auto_ptr<PlacementStrategy> m_strategy; ///< main strategy
|
||||||
|
std::auto_ptr<PlacementStrategy> m_fallback_strategy; ///< a fallback strategy if the main strategy fails
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SCREENPLACEMENT_HH
|
|
@ -29,82 +29,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
template <>
|
|
||||||
void FbTk::Resource<BScreen::PlacementPolicy>::setFromString(const char *str) {
|
|
||||||
if (strcasecmp("RowSmartPlacement", str) == 0)
|
|
||||||
*(*this) = BScreen::ROWSMARTPLACEMENT;
|
|
||||||
else if (strcasecmp("ColSmartPlacement", str) == 0)
|
|
||||||
*(*this) = BScreen::COLSMARTPLACEMENT;
|
|
||||||
else if (strcasecmp("UnderMousePlacement", str) == 0)
|
|
||||||
*(*this) = BScreen::UNDERMOUSEPLACEMENT;
|
|
||||||
else if (strcasecmp("CascadePlacement", str) == 0)
|
|
||||||
*(*this) = BScreen::CASCADEPLACEMENT;
|
|
||||||
else
|
|
||||||
setDefaultValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
string FbTk::Resource<BScreen::PlacementPolicy>::getString() const {
|
|
||||||
switch (*(*this)) {
|
|
||||||
case BScreen::ROWSMARTPLACEMENT:
|
|
||||||
return "RowSmartPlacement";
|
|
||||||
case BScreen::COLSMARTPLACEMENT:
|
|
||||||
return "ColSmartPlacement";
|
|
||||||
case BScreen::UNDERMOUSEPLACEMENT:
|
|
||||||
return "UnderMousePlacement";
|
|
||||||
case BScreen::CASCADEPLACEMENT:
|
|
||||||
return "CascadePlacement";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "RowSmartPlacement";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
void FbTk::Resource<BScreen::RowDirection>::setFromString(const char *str) {
|
|
||||||
if (strcasecmp("LeftToRight", str) == 0)
|
|
||||||
*(*this) = BScreen::LEFTRIGHT;
|
|
||||||
else if (strcasecmp("RightToLeft", str) == 0)
|
|
||||||
*(*this) = BScreen::RIGHTLEFT;
|
|
||||||
else
|
|
||||||
setDefaultValue();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
string FbTk::Resource<BScreen::RowDirection>::getString() const {
|
|
||||||
switch (*(*this)) {
|
|
||||||
case BScreen::LEFTRIGHT:
|
|
||||||
return "LeftToRight";
|
|
||||||
case BScreen::RIGHTLEFT:
|
|
||||||
return "RightToLeft";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "LeftToRight";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <>
|
|
||||||
void FbTk::Resource<BScreen::ColumnDirection>::setFromString(const char *str) {
|
|
||||||
if (strcasecmp("TopToBottom", str) == 0)
|
|
||||||
*(*this) = BScreen::TOPBOTTOM;
|
|
||||||
else if (strcasecmp("BottomToTop", str) == 0)
|
|
||||||
*(*this) = BScreen::BOTTOMTOP;
|
|
||||||
else
|
|
||||||
setDefaultValue();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
string FbTk::Resource<BScreen::ColumnDirection>::getString() const {
|
|
||||||
switch (*(*this)) {
|
|
||||||
case BScreen::TOPBOTTOM:
|
|
||||||
return "TopToBottom";
|
|
||||||
case BScreen::BOTTOMTOP:
|
|
||||||
return "BottomToTop";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "TopToBottom";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
string FbTk::Resource<FbTk::MenuTheme::MenuMode>::getString() const {
|
string FbTk::Resource<FbTk::MenuTheme::MenuMode>::getString() const {
|
||||||
|
|
75
src/UnderMousePlacement.cc
Normal file
75
src/UnderMousePlacement.cc
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// UnderMousePlacement.cc
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#include "UnderMousePlacement.hh"
|
||||||
|
|
||||||
|
#include "FbTk/App.hh"
|
||||||
|
#include "Screen.hh"
|
||||||
|
#include "Window.hh"
|
||||||
|
|
||||||
|
bool UnderMousePlacement::placeWindow(const std::vector<FluxboxWindow *> &list,
|
||||||
|
const FluxboxWindow &win,
|
||||||
|
int &place_x, int &place_y) {
|
||||||
|
|
||||||
|
int root_x, root_y, ignore_i;
|
||||||
|
|
||||||
|
unsigned int ignore_ui;
|
||||||
|
|
||||||
|
Window ignore_w;
|
||||||
|
|
||||||
|
XQueryPointer(FbTk::App::instance()->display(),
|
||||||
|
win.screen().rootWindow().window(), &ignore_w,
|
||||||
|
&ignore_w, &root_x, &root_y,
|
||||||
|
&ignore_i, &ignore_i, &ignore_ui);
|
||||||
|
|
||||||
|
// 2*border = border on each side of the screen
|
||||||
|
int win_w = win.width() + win.fbWindow().borderWidth()*2,
|
||||||
|
win_h = win.height() + win.fbWindow().borderWidth()*2;
|
||||||
|
|
||||||
|
int test_x = root_x - (win_w / 2);
|
||||||
|
int test_y = root_y - (win_h / 2);
|
||||||
|
|
||||||
|
// keep the window inside the screen
|
||||||
|
int head = (signed) win.screen().getCurrHead();
|
||||||
|
int head_left = (signed) win.screen().maxLeft(head);
|
||||||
|
int head_right = (signed) win.screen().maxRight(head);
|
||||||
|
int head_top = (signed) win.screen().maxTop(head);
|
||||||
|
int head_bot = (signed) win.screen().maxBottom(head);
|
||||||
|
|
||||||
|
if (test_x < head_left)
|
||||||
|
test_x = head_left;
|
||||||
|
|
||||||
|
if (test_x + win_w > head_right)
|
||||||
|
test_x = head_right - win_w;
|
||||||
|
|
||||||
|
if (test_y < head_top)
|
||||||
|
test_y = head_top;
|
||||||
|
|
||||||
|
if (test_y + win_h > head_bot)
|
||||||
|
test_y = head_bot - win_h;
|
||||||
|
|
||||||
|
place_x = test_x;
|
||||||
|
place_y = test_y;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
36
src/UnderMousePlacement.hh
Normal file
36
src/UnderMousePlacement.hh
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// UnderMousePlacement.hh
|
||||||
|
// Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
#ifndef UNDERMOUSEPLACEMENT_HH
|
||||||
|
#define UNDERMOUSEPLACEMENT_HH
|
||||||
|
|
||||||
|
#include "PlacementStrategy.hh"
|
||||||
|
|
||||||
|
class UnderMousePlacement: public PlacementStrategy {
|
||||||
|
public:
|
||||||
|
bool placeWindow(const std::vector<FluxboxWindow *> &windowlist,
|
||||||
|
const FluxboxWindow &win,
|
||||||
|
int &place_x, int &place_y);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UNDERMOUSEPLACEMENT_HH
|
279
src/Workspace.cc
279
src/Workspace.cc
|
@ -33,6 +33,7 @@
|
||||||
#include "FbWinFrame.hh"
|
#include "FbWinFrame.hh"
|
||||||
#include "WindowCmd.hh"
|
#include "WindowCmd.hh"
|
||||||
#include "FocusControl.hh"
|
#include "FocusControl.hh"
|
||||||
|
#include "PlacementStrategy.hh"
|
||||||
|
|
||||||
#include "FbTk/I18n.hh"
|
#include "FbTk/I18n.hh"
|
||||||
#include "FbTk/MenuItem.hh"
|
#include "FbTk/MenuItem.hh"
|
||||||
|
@ -140,21 +141,13 @@ Workspace::Workspace(BScreen &scrn, FbTk::MultLayers &layermanager,
|
||||||
m_name(name),
|
m_name(name),
|
||||||
m_id(id) {
|
m_id(id) {
|
||||||
|
|
||||||
|
|
||||||
m_cascade_x = new int[scrn.numHeads() + 1];
|
|
||||||
m_cascade_y = new int[scrn.numHeads() + 1];
|
|
||||||
for (int i=0; i < scrn.numHeads()+1; i++) {
|
|
||||||
m_cascade_x[i] = 32 + scrn.getHeadX(i);
|
|
||||||
m_cascade_y[i] = 32 + scrn.getHeadY(i);
|
|
||||||
}
|
|
||||||
menu().setInternalMenu();
|
menu().setInternalMenu();
|
||||||
setName(name);
|
setName(name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Workspace::~Workspace() {
|
Workspace::~Workspace() {
|
||||||
delete [] m_cascade_x;
|
|
||||||
delete [] m_cascade_y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspace::setLastFocusedWindow(FluxboxWindow *win) {
|
void Workspace::setLastFocusedWindow(FluxboxWindow *win) {
|
||||||
|
@ -427,268 +420,12 @@ void Workspace::updateClientmenu() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Workspace::placeWindow(FluxboxWindow &win) {
|
void Workspace::placeWindow(FluxboxWindow &win) {
|
||||||
|
int place_x, place_y;
|
||||||
bool placed = false;
|
// we ignore the return value,
|
||||||
|
// the screen placement strategy is guaranteed to succeed.
|
||||||
// restrictions
|
screen().placementStrategy().placeWindow(m_windowlist,
|
||||||
int head = (signed) screen().getCurrHead();
|
win,
|
||||||
int head_left = (signed) screen().maxLeft(head);
|
place_x, place_y);
|
||||||
int head_right = (signed) screen().maxRight(head);
|
|
||||||
int head_top = (signed) screen().maxTop(head);
|
|
||||||
int head_bot = (signed) screen().maxBottom(head);
|
|
||||||
|
|
||||||
int place_x = head_left, place_y = head_top, change_x = 1, change_y = 1;
|
|
||||||
|
|
||||||
if (screen().getColPlacementDirection() == BScreen::BOTTOMTOP)
|
|
||||||
change_y = -1;
|
|
||||||
if (screen().getRowPlacementDirection() == BScreen::RIGHTLEFT)
|
|
||||||
change_x = -1;
|
|
||||||
|
|
||||||
int win_w = win.width() + win.fbWindow().borderWidth()*2,
|
|
||||||
win_h = win.height() + win.fbWindow().borderWidth()*2;
|
|
||||||
|
|
||||||
|
|
||||||
int test_x, test_y, curr_x, curr_y, curr_w, curr_h;
|
|
||||||
|
|
||||||
switch (screen().getPlacementPolicy()) {
|
|
||||||
case BScreen::UNDERMOUSEPLACEMENT: {
|
|
||||||
int root_x, root_y, ignore_i;
|
|
||||||
|
|
||||||
unsigned int ignore_ui;
|
|
||||||
|
|
||||||
Window ignore_w;
|
|
||||||
|
|
||||||
XQueryPointer(FbTk::App::instance()->display(),
|
|
||||||
screen().rootWindow().window(), &ignore_w,
|
|
||||||
&ignore_w, &root_x, &root_y,
|
|
||||||
&ignore_i, &ignore_i, &ignore_ui);
|
|
||||||
|
|
||||||
test_x = root_x - (win_w / 2);
|
|
||||||
test_y = root_y - (win_h / 2);
|
|
||||||
|
|
||||||
// keep the window inside the screen
|
|
||||||
|
|
||||||
if (test_x < head_left)
|
|
||||||
test_x = head_left;
|
|
||||||
|
|
||||||
if (test_x + win_w > head_right)
|
|
||||||
test_x = head_right - win_w;
|
|
||||||
|
|
||||||
if (test_y < head_top)
|
|
||||||
test_y = head_top;
|
|
||||||
|
|
||||||
if (test_y + win_h > head_bot)
|
|
||||||
test_y = head_bot - win_h;
|
|
||||||
|
|
||||||
place_x = test_x;
|
|
||||||
place_y = test_y;
|
|
||||||
|
|
||||||
placed = true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
} // end case UNDERMOUSEPLACEMENT
|
|
||||||
|
|
||||||
case BScreen::ROWSMARTPLACEMENT: {
|
|
||||||
int next_x, next_y;
|
|
||||||
bool top_bot = screen().getColPlacementDirection() == BScreen::TOPBOTTOM;
|
|
||||||
bool left_right = screen().getRowPlacementDirection() == BScreen::LEFTRIGHT;
|
|
||||||
|
|
||||||
if (top_bot)
|
|
||||||
test_y = head_top;
|
|
||||||
else
|
|
||||||
test_y = head_bot - win_h;
|
|
||||||
|
|
||||||
while (!placed &&
|
|
||||||
(top_bot ? test_y + win_h <= head_bot
|
|
||||||
: test_y >= head_top)) {
|
|
||||||
|
|
||||||
if (left_right)
|
|
||||||
test_x = head_left;
|
|
||||||
else
|
|
||||||
test_x = head_right - win_w;
|
|
||||||
|
|
||||||
// The trick here is that we set it to the furthest away one,
|
|
||||||
// then the code brings it back down to the safest one that
|
|
||||||
// we can go to (i.e. the next untested area)
|
|
||||||
if (top_bot)
|
|
||||||
next_y = head_bot; // will be shrunk
|
|
||||||
else
|
|
||||||
next_y = head_top-1;
|
|
||||||
|
|
||||||
while (!placed &&
|
|
||||||
(left_right ? test_x + win_w <= head_right
|
|
||||||
: test_x >= head_left)) {
|
|
||||||
|
|
||||||
placed = true;
|
|
||||||
|
|
||||||
next_x = test_x + change_x;
|
|
||||||
|
|
||||||
Windows::iterator win_it = m_windowlist.begin();
|
|
||||||
const Windows::iterator win_it_end = m_windowlist.end();
|
|
||||||
|
|
||||||
for (; win_it != win_it_end && placed; ++win_it) {
|
|
||||||
FluxboxWindow &window = **win_it;
|
|
||||||
|
|
||||||
curr_x = window.x();
|
|
||||||
curr_y = window.y();
|
|
||||||
curr_w = window.width() + window.fbWindow().borderWidth()*2;
|
|
||||||
curr_h = window.height() + window.fbWindow().borderWidth()*2;
|
|
||||||
|
|
||||||
if (curr_x < test_x + win_w &&
|
|
||||||
curr_x + curr_w > test_x &&
|
|
||||||
curr_y < test_y + win_h &&
|
|
||||||
curr_y + curr_h > test_y) {
|
|
||||||
// this window is in the way
|
|
||||||
placed = false;
|
|
||||||
|
|
||||||
// we find the next x that we can go to (a window will be in the way
|
|
||||||
// all the way to its far side)
|
|
||||||
if (left_right) {
|
|
||||||
if (curr_x + curr_w > next_x)
|
|
||||||
next_x = curr_x + curr_w;
|
|
||||||
} else {
|
|
||||||
if (curr_x - win_w < next_x)
|
|
||||||
next_x = curr_x - win_w;
|
|
||||||
}
|
|
||||||
|
|
||||||
// but we can only go to the nearest y, since that is where the
|
|
||||||
// next time current windows in the way will change
|
|
||||||
if (top_bot) {
|
|
||||||
if (curr_y + curr_h < next_y)
|
|
||||||
next_y = curr_y + curr_h;
|
|
||||||
} else {
|
|
||||||
if (curr_y - win_h > next_y)
|
|
||||||
next_y = curr_y - win_h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (placed) {
|
|
||||||
place_x = test_x;
|
|
||||||
place_y = test_y;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_x = next_x;
|
|
||||||
} // end while
|
|
||||||
|
|
||||||
test_y = next_y;
|
|
||||||
} // end while
|
|
||||||
|
|
||||||
break;
|
|
||||||
} // end case ROWSMARTPLACEMENT
|
|
||||||
|
|
||||||
case BScreen::COLSMARTPLACEMENT: {
|
|
||||||
int next_x, next_y;
|
|
||||||
bool top_bot = screen().getColPlacementDirection() == BScreen::TOPBOTTOM;
|
|
||||||
bool left_right = screen().getRowPlacementDirection() == BScreen::LEFTRIGHT;
|
|
||||||
|
|
||||||
if (left_right)
|
|
||||||
test_x = head_left;
|
|
||||||
else
|
|
||||||
test_x = head_right - win_w;
|
|
||||||
|
|
||||||
while (!placed &&
|
|
||||||
(left_right ? test_x + win_w <= head_right
|
|
||||||
: test_x >= head_left)) {
|
|
||||||
|
|
||||||
if (left_right)
|
|
||||||
next_x = head_right; // it will get shrunk
|
|
||||||
else
|
|
||||||
next_x = head_left-1;
|
|
||||||
|
|
||||||
if (top_bot)
|
|
||||||
test_y = head_top;
|
|
||||||
else
|
|
||||||
test_y = head_bot - win_h;
|
|
||||||
|
|
||||||
while (!placed &&
|
|
||||||
(top_bot ? test_y + win_h <= head_bot
|
|
||||||
: test_y >= head_top)) {
|
|
||||||
placed = True;
|
|
||||||
|
|
||||||
next_y = test_y + change_y;
|
|
||||||
|
|
||||||
Windows::iterator it = m_windowlist.begin();
|
|
||||||
Windows::iterator it_end = m_windowlist.end();
|
|
||||||
for (; it != it_end && placed; ++it) {
|
|
||||||
curr_x = (*it)->x();
|
|
||||||
curr_y = (*it)->y();
|
|
||||||
curr_w = (*it)->width() + (*it)->fbWindow().borderWidth()*2;
|
|
||||||
curr_h = (*it)->height() + (*it)->fbWindow().borderWidth()*2;
|
|
||||||
|
|
||||||
if (curr_x < test_x + win_w &&
|
|
||||||
curr_x + curr_w > test_x &&
|
|
||||||
curr_y < test_y + win_h &&
|
|
||||||
curr_y + curr_h > test_y) {
|
|
||||||
// this window is in the way
|
|
||||||
placed = False;
|
|
||||||
|
|
||||||
// we find the next y that we can go to (a window will be in the way
|
|
||||||
// all the way to its bottom)
|
|
||||||
if (top_bot) {
|
|
||||||
if (curr_y + curr_h > next_y)
|
|
||||||
next_y = curr_y + curr_h;
|
|
||||||
} else {
|
|
||||||
if (curr_y - win_h < next_y)
|
|
||||||
next_y = curr_y - win_h;
|
|
||||||
}
|
|
||||||
|
|
||||||
// but we can only go to the nearest x, since that is where the
|
|
||||||
// next time current windows in the way will change
|
|
||||||
if (left_right) {
|
|
||||||
if (curr_x + curr_w < next_x)
|
|
||||||
next_x = curr_x + curr_w;
|
|
||||||
} else {
|
|
||||||
if (curr_x - win_w > next_x)
|
|
||||||
next_x = curr_x - win_w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (placed) {
|
|
||||||
place_x = test_x;
|
|
||||||
place_y = test_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
test_y = next_y;
|
|
||||||
} // end while
|
|
||||||
|
|
||||||
test_x = next_x;
|
|
||||||
} // end while
|
|
||||||
|
|
||||||
break;
|
|
||||||
} // end COLSMARTPLACEMENT
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// cascade placement or smart placement failed
|
|
||||||
if (! placed) {
|
|
||||||
|
|
||||||
if ((m_cascade_x[head] > ((head_left + head_right) / 2)) ||
|
|
||||||
(m_cascade_y[head] > ((head_top + head_bot) / 2))) {
|
|
||||||
m_cascade_x[head] = head_left + 32;
|
|
||||||
m_cascade_y[head] = head_top + 32;
|
|
||||||
}
|
|
||||||
|
|
||||||
place_x = m_cascade_x[head];
|
|
||||||
place_y = m_cascade_y[head];
|
|
||||||
|
|
||||||
// just one borderwidth, so they can share a borderwidth (looks better)
|
|
||||||
int titlebar_height = win.titlebarHeight() + win.fbWindow().borderWidth();
|
|
||||||
if (titlebar_height < 4) // make sure it is not insignificant
|
|
||||||
titlebar_height = 32;
|
|
||||||
m_cascade_x[head] += titlebar_height;
|
|
||||||
m_cascade_y[head] += titlebar_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (place_x + win_w > head_right)
|
|
||||||
place_x = (head_right - win_w) / 2;
|
|
||||||
if (place_y + win_h > head_bot)
|
|
||||||
place_y = (head_bot - win_h) / 2;
|
|
||||||
|
|
||||||
|
|
||||||
win.moveResize(place_x, place_y, win.width(), win.height());
|
win.moveResize(place_x, place_y, win.width(), win.height());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue