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 \
|
||||
WindowCmd.hh WindowCmd.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} \
|
||||
${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 "FocusControl.hh"
|
||||
#include "ScreenPlacement.hh"
|
||||
|
||||
// themes
|
||||
#include "FbWinFrameTheme.hh"
|
||||
|
@ -184,9 +185,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
|
|||
menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"),
|
||||
menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"),
|
||||
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_style(rm,
|
||||
FbTk::GContext::LINESOLID,
|
||||
|
@ -238,6 +237,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
|||
m_name(screenname),
|
||||
m_altname(altscreenname),
|
||||
m_focus_control(new FocusControl(*this)),
|
||||
m_placement_strategy(new ScreenPlacement(*this)),
|
||||
m_xinerama_headinfo(0),
|
||||
m_shutdown(false) {
|
||||
|
||||
|
@ -446,7 +446,10 @@ BScreen::~BScreen() {
|
|||
|
||||
// TODO fluxgen: check if this is the right place
|
||||
delete [] m_head_areas;
|
||||
|
||||
delete m_focus_control;
|
||||
delete m_placement_strategy;
|
||||
|
||||
}
|
||||
|
||||
void BScreen::initWindows() {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "FbRootWindow.hh"
|
||||
#include "MenuTheme.hh"
|
||||
#include "PlacementStrategy.hh"
|
||||
|
||||
#include "FbTk/Resource.hh"
|
||||
#include "FbTk/Subject.hh"
|
||||
|
@ -63,6 +64,7 @@ class Strut;
|
|||
class Slit;
|
||||
class HeadArea;
|
||||
class FocusControl;
|
||||
class PlacementStrategy;
|
||||
|
||||
namespace FbTk {
|
||||
class Menu;
|
||||
|
@ -90,15 +92,6 @@ public:
|
|||
QUADRANTRESIZE,
|
||||
DEFAULTRESIZE = BOTTOMRESIZE };
|
||||
|
||||
enum PlacementPolicy {
|
||||
ROWSMARTPLACEMENT,
|
||||
COLSMARTPLACEMENT,
|
||||
CASCADEPLACEMENT,
|
||||
UNDERMOUSEPLACEMENT
|
||||
};
|
||||
|
||||
enum RowDirection { LEFTRIGHT, RIGHTLEFT};
|
||||
enum ColumnDirection { TOPBOTTOM, BOTTOMTOP};
|
||||
|
||||
typedef std::vector<FluxboxWindow *> Icons;
|
||||
|
||||
|
@ -218,10 +211,7 @@ public:
|
|||
/// hide all windowmenus except the given one (if given)
|
||||
void hideWindowMenus(const FluxboxWindow* except= 0);
|
||||
|
||||
inline PlacementPolicy getPlacementPolicy() const { return *resource.placement_policy; }
|
||||
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 saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; }
|
||||
|
@ -249,7 +239,9 @@ public:
|
|||
const std::string &altName() const { return m_altname; }
|
||||
bool isShuttingdown() const { return m_shutdown; }
|
||||
|
||||
|
||||
PlacementStrategy &placementStrategy() { return *m_placement_strategy; }
|
||||
const PlacementStrategy &placementStrategy() const { return *m_placement_strategy; }
|
||||
|
||||
int addWorkspace();
|
||||
int removeLastWorkspace();
|
||||
// scroll workspaces
|
||||
|
@ -442,9 +434,7 @@ private:
|
|||
FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha,
|
||||
unfocused_alpha, menu_alpha, menu_delay, menu_delay_close;
|
||||
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<FbTk::GContext::LineStyle> gc_line_style;
|
||||
FbTk::Resource<FbTk::GContext::JoinStyle> gc_join_style;
|
||||
|
@ -458,6 +448,7 @@ private:
|
|||
const std::string m_name, m_altname;
|
||||
|
||||
FocusControl *m_focus_control;
|
||||
PlacementStrategy *m_placement_strategy;
|
||||
|
||||
// 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
|
||||
|
|
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>
|
||||
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 <>
|
||||
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 "WindowCmd.hh"
|
||||
#include "FocusControl.hh"
|
||||
#include "PlacementStrategy.hh"
|
||||
|
||||
#include "FbTk/I18n.hh"
|
||||
#include "FbTk/MenuItem.hh"
|
||||
|
@ -140,21 +141,13 @@ Workspace::Workspace(BScreen &scrn, FbTk::MultLayers &layermanager,
|
|||
m_name(name),
|
||||
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();
|
||||
setName(name);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Workspace::~Workspace() {
|
||||
delete [] m_cascade_x;
|
||||
delete [] m_cascade_y;
|
||||
}
|
||||
|
||||
void Workspace::setLastFocusedWindow(FluxboxWindow *win) {
|
||||
|
@ -427,268 +420,12 @@ void Workspace::updateClientmenu() {
|
|||
}
|
||||
|
||||
void Workspace::placeWindow(FluxboxWindow &win) {
|
||||
|
||||
bool placed = false;
|
||||
|
||||
// restrictions
|
||||
int head = (signed) screen().getCurrHead();
|
||||
int head_left = (signed) screen().maxLeft(head);
|
||||
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;
|
||||
|
||||
int place_x, place_y;
|
||||
// we ignore the return value,
|
||||
// the screen placement strategy is guaranteed to succeed.
|
||||
screen().placementStrategy().placeWindow(m_windowlist,
|
||||
win,
|
||||
place_x, place_y);
|
||||
|
||||
win.moveResize(place_x, place_y, win.width(), win.height());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue