From 37757769634c836895d205b0a5149ffffaae9bfb Mon Sep 17 00:00:00 2001 From: fluxgen Date: Sat, 11 Sep 2004 13:33:07 +0000 Subject: head specific strut, patch from Mathieu De Zutter --- src/Screen.cc | 145 +++++++++++++++++++++++++++++++++++---------------------- src/Screen.hh | 13 ++++-- src/Slit.cc | 4 +- src/Toolbar.cc | 33 +++++++------ 4 files changed, 116 insertions(+), 79 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 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.289 2004/09/09 14:29:03 akir Exp $ +// $Id: Screen.cc,v 1.290 2004/09/11 13:30:37 fluxgen Exp $ #include "Screen.hh" @@ -55,6 +55,7 @@ #include "Strut.hh" #include "CommandParser.hh" #include "AtomHandler.hh" +#include "HeadArea.hh" #include "FbTk/I18n.hh" @@ -226,7 +227,6 @@ BScreen::BScreen(FbTk::ResourceManager &rm, m_name(screenname), m_altname(altscreenname), m_resource_manager(rm), - m_available_workspace_area(new Strut(0, 0, 0, 0)), m_xinerama_headinfo(0), m_shutdown(false) { @@ -250,6 +250,9 @@ BScreen::BScreen(FbTk::ResourceManager &rm, managed = running; if (! managed) return; + + // TODO fluxgen: check if this is the right place + m_head_areas = new HeadArea[numHeads() ? numHeads() : 1]; _FB_USES_NLS; @@ -434,6 +437,9 @@ BScreen::~BScreen() { if (hasXinerama() && m_xinerama_headinfo) { delete [] m_xinerama_headinfo; } + + // TODO fluxgen: check if this is the right place + delete [] m_head_areas; } void BScreen::initWindows() { @@ -548,32 +554,36 @@ unsigned int BScreen::currentWorkspaceID() const { return m_current_workspace->workspaceID(); } +const Strut* BScreen::availableWorkspaceArea(int head) const { + return m_head_areas[head ? head-1 : 0].availableWorkspaceArea(); +} + unsigned int BScreen::maxLeft(int head) const { + // we ignore strut if we're doing full maximization if (hasXinerama()) return doFullMax() ? getHeadX(head) : - getHeadX(head) + m_available_workspace_area->left(); + getHeadX(head) + availableWorkspaceArea(head)->left(); else - return doFullMax() ? 0 : m_available_workspace_area->left(); + return doFullMax() ? 0 : availableWorkspaceArea(head)->left(); } unsigned int BScreen::maxRight(int head) const { // we ignore strut if we're doing full maximization if (hasXinerama()) return doFullMax() ? getHeadX(head) + getHeadWidth(head) : - getHeadX(head) + getHeadWidth(head) - m_available_workspace_area->right(); + getHeadX(head) + getHeadWidth(head) - availableWorkspaceArea(head)->right(); else - return doFullMax() ? width() : width() - m_available_workspace_area->right(); + return doFullMax() ? width() : width() - availableWorkspaceArea(head)->right(); } unsigned int BScreen::maxTop(int head) const { - // we ignore strut if we're doing full maximization - + if (hasXinerama()) - return doFullMax() ? getHeadY(head) : getHeadY(head) + m_available_workspace_area->top(); + return doFullMax() ? getHeadY(head) : getHeadY(head) + availableWorkspaceArea(head)->top(); else - return doFullMax() ? 0 : m_available_workspace_area->top(); + return doFullMax() ? 0 : availableWorkspaceArea(head)->top(); } unsigned int BScreen::maxBottom(int head) const { @@ -581,9 +591,9 @@ unsigned int BScreen::maxBottom(int head) const { if (hasXinerama()) return doFullMax() ? getHeadY(head) + getHeadHeight(head) : - getHeadY(head) + getHeadHeight(head) - m_available_workspace_area->bottom(); + getHeadY(head) + getHeadHeight(head) - availableWorkspaceArea(head)->bottom(); else - return doFullMax() ? height() : height() - m_available_workspace_area->bottom(); + return doFullMax() ? height() : height() - availableWorkspaceArea(head)->bottom(); } void BScreen::update(FbTk::Subject *subj) { @@ -1260,58 +1270,46 @@ FluxboxWindow *BScreen::createWindow(WinClient &client) { return win; } -Strut *BScreen::requestStrut(int left, int right, int top, int bottom) { - Strut *str = new Strut(left, right, top, bottom); - m_strutlist.push_back(str); - return str; -} +Strut *BScreen::requestStrut(int head, int left, int right, int top, int bottom) { + if (head > numHeads() && head != 1) { + // head does not exist (if head == 1, then numHeads() == 0, + // which means no xinerama, but there's a head after all + head = numHeads(); + } -void BScreen::clearStrut(Strut *str) { - if (str == 0) - return; - // find strut and erase it - std::list::iterator pos = find(m_strutlist.begin(), - m_strutlist.end(), - str); - if (pos == m_strutlist.end()) - return; - m_strutlist.erase(pos); - delete str; -} + int begin = head-1; + int end = head; -/// helper class for for_each in BScreen::updateAvailableWorkspaceArea() -namespace { -class MaxArea { -public: - MaxArea(Strut &max_area):m_max_area(max_area) { } - void operator ()(const Strut *str) { - static int left, right, bottom, top; - left = std::max(m_max_area.left(), str->left()); - right = std::max(m_max_area.right(), str->right()); - bottom = std::max(m_max_area.bottom(), str->bottom()); - top = std::max(m_max_area.top(), str->top()); - m_max_area = Strut(left, right, top, bottom); + if (head == 0) { // all heads (or no xinerama) + begin = 0; + end = (numHeads() ? numHeads() : 1); } -private: - Strut &m_max_area; -}; -} // end anonymous namespace + Strut* next = 0; + for (int i = begin; i != end; i++) { + next = m_head_areas[i].requestStrut(i+1, left, right, top, bottom, next); + } + + return next; +} + +void BScreen::clearStrut(Strut *str) { + if (str->next()) + clearStrut(str->next()); + int head = str->head() ? str->head() - 1 : 0; + m_head_areas[head].clearStrut(str); + // str is invalid now +} void BScreen::updateAvailableWorkspaceArea() { - // find max of left, right, top and bottom and set avaible workspace area + size_t n = (numHeads() ? numHeads() : 1); + bool updated = false; - // clear old area - Strut oldarea = *(m_available_workspace_area.get()); - m_available_workspace_area.reset(new Strut(0, 0, 0, 0)); - - // calculate max area - for_each(m_strutlist.begin(), - m_strutlist.end(), - MaxArea(*m_available_workspace_area.get())); + for (size_t i = 0; i < n; i++) { + updated = m_head_areas[i].updateAvailableWorkspaceArea() || updated; + } - // only notify if the area changed - if (oldarea == *(m_available_workspace_area.get())) + if (updated) m_workspace_area_sig.notify(); } @@ -2204,11 +2202,17 @@ void BScreen::initXinerama() { Display *display = FbTk::App::instance()->display(); if (!XineramaIsActive(display)) { +#ifdef DEBUG + cerr<<"BScreen::initXinerama(): dont have Xinerama"< @@ -333,7 +337,7 @@ public: FluxboxWindow *createWindow(WinClient &client); void setupWindowActions(FluxboxWindow &win); /// request workspace space, i.e "don't maximize over this area" - Strut *requestStrut(int left, int right, int top, int bottom); + Strut *requestStrut(int head, int left, int right, int top, int bottom); /// remove requested space and destroy strut void clearStrut(Strut *strut); /// updates max avaible area for the workspace @@ -363,6 +367,8 @@ private: void renderGeomWindow(); void renderPosWindow(); + const Strut* availableWorkspaceArea(int head) const; + ScreenSubject m_clientlist_sig, ///< client signal m_iconlist_sig, ///< notify if a window gets iconified/deiconified @@ -455,13 +461,12 @@ private: int m_xinerama_center_x, m_xinerama_center_y; - std::auto_ptr m_available_workspace_area; + HeadArea *m_head_areas; struct XineramaHeadInfo { int x, y, width, height; } *m_xinerama_headinfo; - std::list m_strutlist; bool m_shutdown; }; diff --git a/src/Slit.cc b/src/Slit.cc index f960ac8..dc14d42 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Slit.cc,v 1.99 2004/08/31 19:27:21 akir Exp $ +// $Id: Slit.cc,v 1.100 2004/09/11 13:31:36 fluxgen Exp $ #include "Slit.hh" @@ -407,7 +407,7 @@ void Slit::updateStrut() { right = width(); break; } - m_strut = screen().requestStrut(left, right, top, bottom); + m_strut = screen().requestStrut(getOnHead(), left, right, top, bottom); screen().updateAvailableWorkspaceArea(); } diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 2c19518..d35e872 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -22,7 +22,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Toolbar.cc,v 1.152 2004/08/31 19:38:42 akir Exp $ +// $Id: Toolbar.cc,v 1.153 2004/09/11 13:33:07 fluxgen Exp $ #include "Toolbar.hh" @@ -328,7 +328,7 @@ void Toolbar::updateStrut() { left = width(); break; }; - m_strut = screen().requestStrut(left, right, top, bottom); + m_strut = screen().requestStrut(getOnHead(), left, right, top, bottom); screen().updateAvailableWorkspaceArea(); } @@ -485,22 +485,21 @@ void Toolbar::buttonPressEvent(XButtonEvent &be) { screen().hideMenus(); if (! menu().isVisible()) { - int x, y; - x = be.x_root - (menu().width() / 2); - y = be.y_root - (menu().height() / 2); - - if (x < 0) - x = 0; - else if (x + menu().width() > screen().width()) - x = screen().width() - menu().width(); - - if (y < 0) - y = 0; - else if (y + menu().height() > screen().height()) - y = screen().height() - menu().height(); - - menu().move(x, y); + int head = screen().getHead(be.x_root, be.y_root); + int borderw = menu().fbwindow().borderWidth(); + pair m = screen().clampToHead( head, + be.x_root - (menu().width() / 2), + be.y_root - (menu().titleWindow().height() / 2), + menu().width() + 2*borderw, + menu().height() + 2*borderw); + + menu().setScreen( + screen().getHeadX(head), + screen().getHeadY(head), + screen().getHeadWidth(head), + screen().getHeadHeight(head)); + menu().move(m.first, m.second); menu().show(); menu().grabInputFocus(); } else -- cgit v0.11.2