diff options
Diffstat (limited to 'src/Screen.cc')
-rw-r--r-- | src/Screen.cc | 145 |
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 | ||
439 | void BScreen::initWindows() { | 445 | void 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 | ||
557 | const Strut* BScreen::availableWorkspaceArea(int head) const { | ||
558 | return m_head_areas[head ? head-1 : 0].availableWorkspaceArea(); | ||
559 | } | ||
560 | |||
551 | unsigned int BScreen::maxLeft(int head) const { | 561 | unsigned 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 | ||
560 | unsigned int BScreen::maxRight(int head) const { | 571 | unsigned 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 | ||
569 | unsigned int BScreen::maxTop(int head) const { | 580 | unsigned 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 | ||
579 | unsigned int BScreen::maxBottom(int head) const { | 589 | unsigned 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 | ||
589 | void BScreen::update(FbTk::Subject *subj) { | 599 | void BScreen::update(FbTk::Subject *subj) { |
@@ -1260,58 +1270,46 @@ FluxboxWindow *BScreen::createWindow(WinClient &client) { | |||
1260 | return win; | 1270 | return win; |
1261 | } | 1271 | } |
1262 | 1272 | ||
1263 | Strut *BScreen::requestStrut(int left, int right, int top, int bottom) { | 1273 | Strut *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 | ||
1269 | void 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) |
1283 | namespace { | 1284 | begin = 0; |
1284 | class MaxArea { | 1285 | end = (numHeads() ? numHeads() : 1); |
1285 | public: | ||
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 | } |
1295 | private: | ||
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 | |||
1296 | void 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 | ||
1301 | void BScreen::updateAvailableWorkspaceArea() { | 1304 | void 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 | ||
2319 | pair<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 |