diff options
author | Tomas Janousek <tomi@nomi.cz> | 2008-01-28 08:58:23 (GMT) |
---|---|---|
committer | Tomas Janousek <tomi@nomi.cz> | 2008-01-28 08:58:23 (GMT) |
commit | 880209a43821c8f56e4a46b2debf7a72f68658c8 (patch) | |
tree | 22f68473e939c1cf8cb838ece3943e4184ff7392 /src/Screen.cc | |
parent | a61b37da70e0cd1556617c56890455ef89ee1fb0 (diff) | |
parent | 5c85fcbe648b5b4581db1ca2303d5f849a63c28c (diff) | |
download | fluxbox-880209a43821c8f56e4a46b2debf7a72f68658c8.zip fluxbox-880209a43821c8f56e4a46b2debf7a72f68658c8.tar.bz2 |
Merge branch 'xinerama_randr'
Diffstat (limited to 'src/Screen.cc')
-rw-r--r-- | src/Screen.cc | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/src/Screen.cc b/src/Screen.cc index e3b08c6..36b1918 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -360,6 +360,12 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
360 | Display *disp = m_root_window.display(); | 360 | Display *disp = m_root_window.display(); |
361 | Fluxbox *fluxbox = Fluxbox::instance(); | 361 | Fluxbox *fluxbox = Fluxbox::instance(); |
362 | 362 | ||
363 | // TODO fluxgen: check if this is the right place (it was not -lis) | ||
364 | // | ||
365 | // Create the first one, initXinerama will expand this if needed. | ||
366 | m_head_areas.resize(1); | ||
367 | m_head_areas[0] = new HeadArea(); | ||
368 | |||
363 | initXinerama(); | 369 | initXinerama(); |
364 | 370 | ||
365 | // setup error handler to catch "screen already managed by other wm" | 371 | // setup error handler to catch "screen already managed by other wm" |
@@ -402,9 +408,6 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
402 | XFree(ret_prop); | 408 | XFree(ret_prop); |
403 | } | 409 | } |
404 | 410 | ||
405 | // TODO fluxgen: check if this is the right place | ||
406 | m_head_areas = new HeadArea[numHeads() ? numHeads() : 1]; | ||
407 | |||
408 | #ifdef HAVE_RANDR | 411 | #ifdef HAVE_RANDR |
409 | // setup RANDR for this screens root window | 412 | // setup RANDR for this screens root window |
410 | // we need to determine if we should use old randr select input function or not | 413 | // we need to determine if we should use old randr select input function or not |
@@ -600,7 +603,8 @@ BScreen::~BScreen() { | |||
600 | m_slit.reset(0); | 603 | m_slit.reset(0); |
601 | 604 | ||
602 | // TODO fluxgen: check if this is the right place | 605 | // TODO fluxgen: check if this is the right place |
603 | delete [] m_head_areas; | 606 | for (int i = 0; i < m_head_areas.size(); i++) |
607 | delete m_head_areas[i]; | ||
604 | 608 | ||
605 | delete m_focus_control; | 609 | delete m_focus_control; |
606 | delete m_placement_strategy; | 610 | delete m_placement_strategy; |
@@ -722,7 +726,12 @@ unsigned int BScreen::currentWorkspaceID() const { | |||
722 | } | 726 | } |
723 | 727 | ||
724 | const Strut* BScreen::availableWorkspaceArea(int head) const { | 728 | const Strut* BScreen::availableWorkspaceArea(int head) const { |
725 | return m_head_areas[head ? head-1 : 0].availableWorkspaceArea(); | 729 | if (head > numHeads()) { |
730 | /* May this ever happen? */ | ||
731 | static Strut whole(-1 /* should never be used */, 0, width(), 0, height()); | ||
732 | return &whole; | ||
733 | } | ||
734 | return m_head_areas[head ? head-1 : 0]->availableWorkspaceArea(); | ||
726 | } | 735 | } |
727 | 736 | ||
728 | unsigned int BScreen::maxLeft(int head) const { | 737 | unsigned int BScreen::maxLeft(int head) const { |
@@ -1412,7 +1421,7 @@ Strut *BScreen::requestStrut(int head, int left, int right, int top, int bottom) | |||
1412 | 1421 | ||
1413 | Strut* next = 0; | 1422 | Strut* next = 0; |
1414 | for (int i = begin; i != end; i++) { | 1423 | for (int i = begin; i != end; i++) { |
1415 | next = m_head_areas[i].requestStrut(i+1, left, right, top, bottom, next); | 1424 | next = m_head_areas[i]->requestStrut(i+1, left, right, top, bottom, next); |
1416 | } | 1425 | } |
1417 | 1426 | ||
1418 | return next; | 1427 | return next; |
@@ -1422,7 +1431,9 @@ void BScreen::clearStrut(Strut *str) { | |||
1422 | if (str->next()) | 1431 | if (str->next()) |
1423 | clearStrut(str->next()); | 1432 | clearStrut(str->next()); |
1424 | int head = str->head() ? str->head() - 1 : 0; | 1433 | int head = str->head() ? str->head() - 1 : 0; |
1425 | m_head_areas[head].clearStrut(str); | 1434 | /* The number of heads may have changed, be careful. */ |
1435 | if (head < numHeads()) | ||
1436 | m_head_areas[head]->clearStrut(str); | ||
1426 | // str is invalid now | 1437 | // str is invalid now |
1427 | } | 1438 | } |
1428 | 1439 | ||
@@ -1431,7 +1442,7 @@ void BScreen::updateAvailableWorkspaceArea() { | |||
1431 | bool updated = false; | 1442 | bool updated = false; |
1432 | 1443 | ||
1433 | for (size_t i = 0; i < n; i++) { | 1444 | for (size_t i = 0; i < n; i++) { |
1434 | updated = m_head_areas[i].updateAvailableWorkspaceArea() || updated; | 1445 | updated = m_head_areas[i]->updateAvailableWorkspaceArea() || updated; |
1435 | } | 1446 | } |
1436 | 1447 | ||
1437 | if (updated) | 1448 | if (updated) |
@@ -1886,6 +1897,9 @@ void BScreen::renderPosWindow() { | |||
1886 | } | 1897 | } |
1887 | 1898 | ||
1888 | void BScreen::updateSize() { | 1899 | void BScreen::updateSize() { |
1900 | // update xinerama layout | ||
1901 | initXinerama(); | ||
1902 | |||
1889 | // force update geometry | 1903 | // force update geometry |
1890 | rootWindow().updateGeometry(); | 1904 | rootWindow().updateGeometry(); |
1891 | 1905 | ||
@@ -1895,6 +1909,9 @@ void BScreen::updateSize() { | |||
1895 | // send resize notify | 1909 | // send resize notify |
1896 | m_resize_sig.notify(); | 1910 | m_resize_sig.notify(); |
1897 | m_workspace_area_sig.notify(); | 1911 | m_workspace_area_sig.notify(); |
1912 | |||
1913 | // move windows out of inactive heads | ||
1914 | clearHeads(); | ||
1898 | } | 1915 | } |
1899 | 1916 | ||
1900 | 1917 | ||
@@ -1941,10 +1958,13 @@ void BScreen::initXinerama() { | |||
1941 | Display *display = FbTk::App::instance()->display(); | 1958 | Display *display = FbTk::App::instance()->display(); |
1942 | 1959 | ||
1943 | if (!XineramaIsActive(display)) { | 1960 | if (!XineramaIsActive(display)) { |
1961 | notactive: | ||
1944 | #ifdef DEBUG | 1962 | #ifdef DEBUG |
1945 | cerr<<"BScreen::initXinerama(): dont have Xinerama"<<endl; | 1963 | cerr<<"BScreen::initXinerama(): dont have Xinerama"<<endl; |
1946 | #endif // DEBUG | 1964 | #endif // DEBUG |
1947 | m_xinerama_avail = false; | 1965 | m_xinerama_avail = false; |
1966 | if (m_xinerama_headinfo) | ||
1967 | delete [] m_xinerama_headinfo; | ||
1948 | m_xinerama_headinfo = 0; | 1968 | m_xinerama_headinfo = 0; |
1949 | m_xinerama_num_heads = 0; | 1969 | m_xinerama_num_heads = 0; |
1950 | return; | 1970 | return; |
@@ -1957,6 +1977,19 @@ void BScreen::initXinerama() { | |||
1957 | XineramaScreenInfo *screen_info; | 1977 | XineramaScreenInfo *screen_info; |
1958 | int number; | 1978 | int number; |
1959 | screen_info = XineramaQueryScreens(display, &number); | 1979 | screen_info = XineramaQueryScreens(display, &number); |
1980 | |||
1981 | /* The call may have actually failed. If this is the first time we init | ||
1982 | * Xinerama, fall back to turning it off. If not, pretend nothing | ||
1983 | * happened -- another event will tell us and it will work then. */ | ||
1984 | if (!screen_info) { | ||
1985 | if (m_xinerama_headinfo) | ||
1986 | return; | ||
1987 | else | ||
1988 | goto notactive; | ||
1989 | } | ||
1990 | |||
1991 | if (m_xinerama_headinfo) | ||
1992 | delete [] m_xinerama_headinfo; | ||
1960 | m_xinerama_headinfo = new XineramaHeadInfo[number]; | 1993 | m_xinerama_headinfo = new XineramaHeadInfo[number]; |
1961 | m_xinerama_num_heads = number; | 1994 | m_xinerama_num_heads = number; |
1962 | for (int i=0; i < number; i++) { | 1995 | for (int i=0; i < number; i++) { |
@@ -1970,6 +2003,18 @@ void BScreen::initXinerama() { | |||
1970 | cerr<<"BScreen::initXinerama(): number of heads ="<<number<<endl; | 2003 | cerr<<"BScreen::initXinerama(): number of heads ="<<number<<endl; |
1971 | #endif // DEBUG | 2004 | #endif // DEBUG |
1972 | 2005 | ||
2006 | /* Reallocate to the new number of heads. */ | ||
2007 | int ha_num = numHeads() ? numHeads() : 1, ha_oldnum = m_head_areas.size(); | ||
2008 | if (ha_num > ha_oldnum) { | ||
2009 | m_head_areas.resize(ha_num); | ||
2010 | for (int i = ha_oldnum; i < ha_num; i++) | ||
2011 | m_head_areas[i] = new HeadArea(); | ||
2012 | } else if (ha_num < ha_oldnum) { | ||
2013 | for (int i = ha_num; i < ha_oldnum; i++) | ||
2014 | delete m_head_areas[i]; | ||
2015 | m_head_areas.resize(ha_num); | ||
2016 | } | ||
2017 | |||
1973 | #else // XINERAMA | 2018 | #else // XINERAMA |
1974 | // no xinerama | 2019 | // no xinerama |
1975 | m_xinerama_avail = false; | 2020 | m_xinerama_avail = false; |
@@ -1978,6 +2023,22 @@ void BScreen::initXinerama() { | |||
1978 | 2023 | ||
1979 | } | 2024 | } |
1980 | 2025 | ||
2026 | /* Move windows out of inactive heads */ | ||
2027 | void BScreen::clearHeads() { | ||
2028 | if (!hasXinerama()) return; | ||
2029 | |||
2030 | for (Workspaces::iterator i = m_workspaces_list.begin(); | ||
2031 | i != m_workspaces_list.end(); i++) { | ||
2032 | for (Workspace::Windows::iterator win = (*i)->windowList().begin(); | ||
2033 | win != (*i)->windowList().end(); win++) { | ||
2034 | if (getHead((*win)->fbWindow()) == 0) { | ||
2035 | // first head is a safe bet here | ||
2036 | (*win)->placeWindow(1); | ||
2037 | } | ||
2038 | } | ||
2039 | } | ||
2040 | } | ||
2041 | |||
1981 | int BScreen::getHead(int x, int y) const { | 2042 | int BScreen::getHead(int x, int y) const { |
1982 | if (!hasXinerama()) return 0; | 2043 | if (!hasXinerama()) return 0; |
1983 | #ifdef XINERAMA | 2044 | #ifdef XINERAMA |