aboutsummaryrefslogtreecommitdiff
path: root/src/Screen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Screen.cc')
-rw-r--r--src/Screen.cc145
1 files changed, 89 insertions, 56 deletions
diff --git a/src/Screen.cc b/src/Screen.cc
index 8372f0f..e4ede29 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Screen.cc,v 1.289 2004/09/09 14:29:03 akir Exp $ 25// $Id: Screen.cc,v 1.290 2004/09/11 13:30:37 fluxgen Exp $
26 26
27 27
28#include "Screen.hh" 28#include "Screen.hh"
@@ -55,6 +55,7 @@
55#include "Strut.hh" 55#include "Strut.hh"
56#include "CommandParser.hh" 56#include "CommandParser.hh"
57#include "AtomHandler.hh" 57#include "AtomHandler.hh"
58#include "HeadArea.hh"
58 59
59 60
60#include "FbTk/I18n.hh" 61#include "FbTk/I18n.hh"
@@ -226,7 +227,6 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
226 m_name(screenname), 227 m_name(screenname),
227 m_altname(altscreenname), 228 m_altname(altscreenname),
228 m_resource_manager(rm), 229 m_resource_manager(rm),
229 m_available_workspace_area(new Strut(0, 0, 0, 0)),
230 m_xinerama_headinfo(0), 230 m_xinerama_headinfo(0),
231 m_shutdown(false) { 231 m_shutdown(false) {
232 232
@@ -250,6 +250,9 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
250 managed = running; 250 managed = running;
251 if (! managed) 251 if (! managed)
252 return; 252 return;
253
254 // TODO fluxgen: check if this is the right place
255 m_head_areas = new HeadArea[numHeads() ? numHeads() : 1];
253 256
254 _FB_USES_NLS; 257 _FB_USES_NLS;
255 258
@@ -434,6 +437,9 @@ BScreen::~BScreen() {
434 if (hasXinerama() && m_xinerama_headinfo) { 437 if (hasXinerama() && m_xinerama_headinfo) {
435 delete [] m_xinerama_headinfo; 438 delete [] m_xinerama_headinfo;
436 } 439 }
440
441 // TODO fluxgen: check if this is the right place
442 delete [] m_head_areas;
437} 443}
438 444
439void BScreen::initWindows() { 445void BScreen::initWindows() {
@@ -548,32 +554,36 @@ unsigned int BScreen::currentWorkspaceID() const {
548 return m_current_workspace->workspaceID(); 554 return m_current_workspace->workspaceID();
549} 555}
550 556
557const Strut* BScreen::availableWorkspaceArea(int head) const {
558 return m_head_areas[head ? head-1 : 0].availableWorkspaceArea();
559}
560
551unsigned int BScreen::maxLeft(int head) const { 561unsigned int BScreen::maxLeft(int head) const {
562
552 // we ignore strut if we're doing full maximization 563 // we ignore strut if we're doing full maximization
553 if (hasXinerama()) 564 if (hasXinerama())
554 return doFullMax() ? getHeadX(head) : 565 return doFullMax() ? getHeadX(head) :
555 getHeadX(head) + m_available_workspace_area->left(); 566 getHeadX(head) + availableWorkspaceArea(head)->left();
556 else 567 else
557 return doFullMax() ? 0 : m_available_workspace_area->left(); 568 return doFullMax() ? 0 : availableWorkspaceArea(head)->left();
558} 569}
559 570
560unsigned int BScreen::maxRight(int head) const { 571unsigned int BScreen::maxRight(int head) const {
561 // we ignore strut if we're doing full maximization 572 // we ignore strut if we're doing full maximization
562 if (hasXinerama()) 573 if (hasXinerama())
563 return doFullMax() ? getHeadX(head) + getHeadWidth(head) : 574 return doFullMax() ? getHeadX(head) + getHeadWidth(head) :
564 getHeadX(head) + getHeadWidth(head) - m_available_workspace_area->right(); 575 getHeadX(head) + getHeadWidth(head) - availableWorkspaceArea(head)->right();
565 else 576 else
566 return doFullMax() ? width() : width() - m_available_workspace_area->right(); 577 return doFullMax() ? width() : width() - availableWorkspaceArea(head)->right();
567} 578}
568 579
569unsigned int BScreen::maxTop(int head) const { 580unsigned int BScreen::maxTop(int head) const {
570
571 // we ignore strut if we're doing full maximization 581 // we ignore strut if we're doing full maximization
572 582
573 if (hasXinerama()) 583 if (hasXinerama())
574 return doFullMax() ? getHeadY(head) : getHeadY(head) + m_available_workspace_area->top(); 584 return doFullMax() ? getHeadY(head) : getHeadY(head) + availableWorkspaceArea(head)->top();
575 else 585 else
576 return doFullMax() ? 0 : m_available_workspace_area->top(); 586 return doFullMax() ? 0 : availableWorkspaceArea(head)->top();
577} 587}
578 588
579unsigned int BScreen::maxBottom(int head) const { 589unsigned int BScreen::maxBottom(int head) const {
@@ -581,9 +591,9 @@ unsigned int BScreen::maxBottom(int head) const {
581 591
582 if (hasXinerama()) 592 if (hasXinerama())
583 return doFullMax() ? getHeadY(head) + getHeadHeight(head) : 593 return doFullMax() ? getHeadY(head) + getHeadHeight(head) :
584 getHeadY(head) + getHeadHeight(head) - m_available_workspace_area->bottom(); 594 getHeadY(head) + getHeadHeight(head) - availableWorkspaceArea(head)->bottom();
585 else 595 else
586 return doFullMax() ? height() : height() - m_available_workspace_area->bottom(); 596 return doFullMax() ? height() : height() - availableWorkspaceArea(head)->bottom();
587} 597}
588 598
589void BScreen::update(FbTk::Subject *subj) { 599void BScreen::update(FbTk::Subject *subj) {
@@ -1260,58 +1270,46 @@ FluxboxWindow *BScreen::createWindow(WinClient &client) {
1260 return win; 1270 return win;
1261} 1271}
1262 1272
1263Strut *BScreen::requestStrut(int left, int right, int top, int bottom) { 1273Strut *BScreen::requestStrut(int head, int left, int right, int top, int bottom) {
1264 Strut *str = new Strut(left, right, top, bottom); 1274 if (head > numHeads() && head != 1) {
1265 m_strutlist.push_back(str); 1275 // head does not exist (if head == 1, then numHeads() == 0,
1266 return str; 1276 // which means no xinerama, but there's a head after all
1267} 1277 head = numHeads();
1278 }
1268 1279
1269void BScreen::clearStrut(Strut *str) { 1280 int begin = head-1;
1270 if (str == 0) 1281 int end = head;
1271 return;
1272 // find strut and erase it
1273 std::list<Strut *>::iterator pos = find(m_strutlist.begin(),
1274 m_strutlist.end(),
1275 str);
1276 if (pos == m_strutlist.end())
1277 return;
1278 m_strutlist.erase(pos);
1279 delete str;
1280}
1281 1282
1282/// helper class for for_each in BScreen::updateAvailableWorkspaceArea() 1283 if (head == 0) { // all heads (or no xinerama)
1283namespace { 1284 begin = 0;
1284class MaxArea { 1285 end = (numHeads() ? numHeads() : 1);
1285public:
1286 MaxArea(Strut &max_area):m_max_area(max_area) { }
1287 void operator ()(const Strut *str) {
1288 static int left, right, bottom, top;
1289 left = std::max(m_max_area.left(), str->left());
1290 right = std::max(m_max_area.right(), str->right());
1291 bottom = std::max(m_max_area.bottom(), str->bottom());
1292 top = std::max(m_max_area.top(), str->top());
1293 m_max_area = Strut(left, right, top, bottom);
1294 } 1286 }
1295private:
1296 Strut &m_max_area;
1297};
1298 1287
1299} // end anonymous namespace 1288 Strut* next = 0;
1289 for (int i = begin; i != end; i++) {
1290 next = m_head_areas[i].requestStrut(i+1, left, right, top, bottom, next);
1291 }
1292
1293 return next;
1294}
1295
1296void BScreen::clearStrut(Strut *str) {
1297 if (str->next())
1298 clearStrut(str->next());
1299 int head = str->head() ? str->head() - 1 : 0;
1300 m_head_areas[head].clearStrut(str);
1301 // str is invalid now
1302}
1300 1303
1301void BScreen::updateAvailableWorkspaceArea() { 1304void BScreen::updateAvailableWorkspaceArea() {
1302 // find max of left, right, top and bottom and set avaible workspace area 1305 size_t n = (numHeads() ? numHeads() : 1);
1306 bool updated = false;
1303 1307
1304 // clear old area 1308 for (size_t i = 0; i < n; i++) {
1305 Strut oldarea = *(m_available_workspace_area.get()); 1309 updated = m_head_areas[i].updateAvailableWorkspaceArea() || updated;
1306 m_available_workspace_area.reset(new Strut(0, 0, 0, 0)); 1310 }
1307
1308 // calculate max area
1309 for_each(m_strutlist.begin(),
1310 m_strutlist.end(),
1311 MaxArea(*m_available_workspace_area.get()));
1312 1311
1313 // only notify if the area changed 1312 if (updated)
1314 if (oldarea == *(m_available_workspace_area.get()))
1315 m_workspace_area_sig.notify(); 1313 m_workspace_area_sig.notify();
1316} 1314}
1317 1315
@@ -2204,11 +2202,17 @@ void BScreen::initXinerama() {
2204 Display *display = FbTk::App::instance()->display(); 2202 Display *display = FbTk::App::instance()->display();
2205 2203
2206 if (!XineramaIsActive(display)) { 2204 if (!XineramaIsActive(display)) {
2205#ifdef DEBUG
2206 cerr<<"BScreen::initXinerama(): dont have Xinerama"<<endl;
2207#endif // DEBUG
2207 m_xinerama_avail = false; 2208 m_xinerama_avail = false;
2208 m_xinerama_headinfo = 0; 2209 m_xinerama_headinfo = 0;
2209 m_xinerama_num_heads = 0; 2210 m_xinerama_num_heads = 0;
2210 return; 2211 return;
2211 } 2212 }
2213#ifdef DEBUG
2214 cerr<<"BScreen::initXinerama(): have Xinerama"<<endl;
2215#endif // DEBUG
2212 m_xinerama_avail = true; 2216 m_xinerama_avail = true;
2213 2217
2214 XineramaScreenInfo *screen_info; 2218 XineramaScreenInfo *screen_info;
@@ -2222,6 +2226,10 @@ void BScreen::initXinerama() {
2222 m_xinerama_headinfo[i].width = screen_info[i].width; 2226 m_xinerama_headinfo[i].width = screen_info[i].width;
2223 m_xinerama_headinfo[i].height = screen_info[i].height; 2227 m_xinerama_headinfo[i].height = screen_info[i].height;
2224 } 2228 }
2229#ifdef DEBUG
2230 cerr<<"BScreen::initXinerama(): number of heads ="<<number<<endl;
2231#endif // DEBUG
2232
2225#else // XINERAMA 2233#else // XINERAMA
2226 // no xinerama 2234 // no xinerama
2227 m_xinerama_avail = false; 2235 m_xinerama_avail = false;
@@ -2308,6 +2316,31 @@ int BScreen::getHeadHeight(int head) const {
2308#endif // XINERAMA 2316#endif // XINERAMA
2309} 2317}
2310 2318
2319pair<int,int> BScreen::clampToHead(int head, int x, int y, int w, int h) const {
2320
2321 // if there are multiple heads, head=0 is not valid
2322 // a better way would be to search the closest head
2323 if (head == 0 && numHeads() != 0)
2324 head = 1;
2325
2326 int hx = getHeadX(head);
2327 int hy = getHeadY(head);
2328 int hw = getHeadWidth(head);
2329 int hh = getHeadHeight(head);
2330
2331 if (x + w > hx + hw)
2332 x = hx + hw - w;
2333 if (y + h > hy + hh)
2334 y = hy + hh - h;
2335
2336 if (x < hx)
2337 x = hx;
2338 if (y < hy)
2339 y = hy;
2340
2341 return make_pair(x,y);
2342}
2343
2311// TODO: when toolbar gets its resources moved into Toolbar.hh/cc, then 2344// TODO: when toolbar gets its resources moved into Toolbar.hh/cc, then
2312// this can be gone and a consistent interface for the two used 2345// this can be gone and a consistent interface for the two used
2313// on the actual objects 2346// on the actual objects