From 041eacdfd58451d0d561f332e1cb3d17a0970cd1 Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Wed, 11 Jul 2007 13:54:53 +0200 Subject: Reload the Xinerama layout on RandR signal. The m_head_areas became a vector, because we need to dynamically change its size. The functions manipulating struts (which refer to a particular head) now check whether the head still exists. Signed-off-by: Tomas Janousek --- src/Screen.cc | 46 ++++++++++++++++++++++++++++++++++++++-------- src/Screen.hh | 2 +- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/Screen.cc b/src/Screen.cc index e3b08c6..2e8c265 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -360,6 +360,12 @@ BScreen::BScreen(FbTk::ResourceManager &rm, Display *disp = m_root_window.display(); Fluxbox *fluxbox = Fluxbox::instance(); + // TODO fluxgen: check if this is the right place (it was not -lis) + // + // Create the first one, initXinerama will expand this if needed. + m_head_areas.resize(1); + m_head_areas[0] = new HeadArea(); + initXinerama(); // setup error handler to catch "screen already managed by other wm" @@ -402,9 +408,6 @@ BScreen::BScreen(FbTk::ResourceManager &rm, XFree(ret_prop); } - // TODO fluxgen: check if this is the right place - m_head_areas = new HeadArea[numHeads() ? numHeads() : 1]; - #ifdef HAVE_RANDR // setup RANDR for this screens root window // we need to determine if we should use old randr select input function or not @@ -600,7 +603,8 @@ BScreen::~BScreen() { m_slit.reset(0); // TODO fluxgen: check if this is the right place - delete [] m_head_areas; + for (int i = 0; i < m_head_areas.size(); i++) + delete m_head_areas[i]; delete m_focus_control; delete m_placement_strategy; @@ -722,7 +726,12 @@ unsigned int BScreen::currentWorkspaceID() const { } const Strut* BScreen::availableWorkspaceArea(int head) const { - return m_head_areas[head ? head-1 : 0].availableWorkspaceArea(); + if (head > numHeads()) { + /* May this ever happen? */ + static Strut whole(-1 /* should never be used */, 0, width(), 0, height()); + return &whole; + } + return m_head_areas[head ? head-1 : 0]->availableWorkspaceArea(); } unsigned int BScreen::maxLeft(int head) const { @@ -1412,7 +1421,7 @@ Strut *BScreen::requestStrut(int head, int left, int right, int top, int bottom) Strut* next = 0; for (int i = begin; i != end; i++) { - next = m_head_areas[i].requestStrut(i+1, left, right, top, bottom, next); + next = m_head_areas[i]->requestStrut(i+1, left, right, top, bottom, next); } return next; @@ -1422,7 +1431,9 @@ 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); + /* The number of heads may have changed, be careful. */ + if (head < numHeads()) + m_head_areas[head]->clearStrut(str); // str is invalid now } @@ -1431,7 +1442,7 @@ void BScreen::updateAvailableWorkspaceArea() { bool updated = false; for (size_t i = 0; i < n; i++) { - updated = m_head_areas[i].updateAvailableWorkspaceArea() || updated; + updated = m_head_areas[i]->updateAvailableWorkspaceArea() || updated; } if (updated) @@ -1886,6 +1897,9 @@ void BScreen::renderPosWindow() { } void BScreen::updateSize() { + // update xinerama layout + initXinerama(); + // force update geometry rootWindow().updateGeometry(); @@ -1945,6 +1959,8 @@ void BScreen::initXinerama() { cerr<<"BScreen::initXinerama(): dont have Xinerama"< Date: Thu, 1 Mar 2007 23:18:18 +0100 Subject: Move windows out of inactive heads upon layout change. Signed-off-by: Tomas Janousek --- src/Screen.cc | 19 +++++++++++++++++++ src/Screen.hh | 1 + 2 files changed, 20 insertions(+) diff --git a/src/Screen.cc b/src/Screen.cc index c6379a0..36b1918 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -1909,6 +1909,9 @@ void BScreen::updateSize() { // send resize notify m_resize_sig.notify(); m_workspace_area_sig.notify(); + + // move windows out of inactive heads + clearHeads(); } @@ -2020,6 +2023,22 @@ notactive: } +/* Move windows out of inactive heads */ +void BScreen::clearHeads() { + if (!hasXinerama()) return; + + for (Workspaces::iterator i = m_workspaces_list.begin(); + i != m_workspaces_list.end(); i++) { + for (Workspace::Windows::iterator win = (*i)->windowList().begin(); + win != (*i)->windowList().end(); win++) { + if (getHead((*win)->fbWindow()) == 0) { + // first head is a safe bet here + (*win)->placeWindow(1); + } + } + } +} + int BScreen::getHead(int x, int y) const { if (!hasXinerama()) return 0; #ifdef XINERAMA diff --git a/src/Screen.hh b/src/Screen.hh index c95e573..f0dbcc6 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -406,6 +406,7 @@ public: int numHeads() const { return m_xinerama_num_heads; } void initXinerama(); + void clearHeads(); /** * Determines head number for a position * @param x position in pixels on the screen -- cgit v0.11.2 From 4faf1bf5c3fe07260b0a4c084db56b0bed12734a Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Mon, 6 Aug 2007 00:36:12 +0200 Subject: "On head" menu -- reloading and refreshing bugfix. We should reload the contents of this menu on Xinerama layout change. I switched it from FbMenu to ToggleMenu, because the selected head wasn't being updated properly. Signed-off-by: Tomas Janousek --- src/Slit.cc | 12 ++++++++---- src/Slit.hh | 7 +++++++ src/Toolbar.cc | 12 ++++++++---- src/Toolbar.hh | 7 +++++++ src/Xinerama.hh | 18 ++++++++++++++---- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/Slit.cc b/src/Slit.cc index 18c21f4..b8ff368 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -48,10 +48,6 @@ #include "RootTheme.hh" #include "FbMenu.hh" -#ifdef XINERAMA -#include "Xinerama.hh" -#endif // XINERAMA - #include "SlitTheme.hh" #include "SlitClient.hh" #include "Xutil.hh" @@ -270,6 +266,9 @@ Slit::Slit(BScreen &scr, FbTk::XLayer &layer, const char *filename) m_slitmenu(scr.menuTheme(), scr.imageControl(), *scr.layerManager().getLayer(Layer::MENU)), +#ifdef XINERAMA + m_xineramaheadmenu(0), +#endif // XINERAMA frame(scr.rootWindow()), //For KDE dock applets m_kwm1_dockwindow(XInternAtom(FbTk::App::instance()->display(), @@ -1113,6 +1112,10 @@ void Slit::exposeEvent(XExposeEvent &ev) { void Slit::update(FbTk::Subject *subj) { reconfigure(); +#ifdef XINERAMA + if (subj == &m_screen.resizeSig() && m_xineramaheadmenu) + m_xineramaheadmenu->reloadHeads(); +#endif // XINERAMA } void Slit::clearWindow() { @@ -1254,6 +1257,7 @@ void Slit::setupMenu() { #ifdef XINERAMA if (screen().hasXinerama()) { m_slitmenu.insert(_FB_XTEXT(Menu, OnHead, "On Head...", "Title of On Head menu"), + m_xineramaheadmenu = new XineramaHeadMenu( screen().menuTheme(), screen(), diff --git a/src/Slit.hh b/src/Slit.hh index 64ae6b4..a7f8e40 100644 --- a/src/Slit.hh +++ b/src/Slit.hh @@ -29,6 +29,10 @@ #include "LayerMenu.hh" #include "Layer.hh" +#ifdef XINERAMA +#include "Xinerama.hh" +#endif // XINERAMA + #include "FbTk/Menu.hh" #include "FbTk/FbWindow.hh" #include "FbTk/Timer.hh" @@ -144,6 +148,9 @@ private: SlitClients m_client_list; std::auto_ptr m_layermenu; FbMenu m_clientlist_menu, m_slitmenu; +#ifdef XINERAMA + XineramaHeadMenu *m_xineramaheadmenu; +#endif // XINERAMA std::string m_filename; struct frame { diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 2c7bde2..00cdfee 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -35,10 +35,6 @@ #include "Screen.hh" #include "WindowCmd.hh" -#ifdef XINERAMA -#include "Xinerama.hh" -#endif // XINERAMA - #include "Strut.hh" #include "FbTk/CommandParser.hh" #include "Layer.hh" @@ -216,6 +212,9 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width): m_toolbarmenu(scrn.menuTheme(), scrn.imageControl(), *scrn.layerManager().getLayer(Layer::MENU)), +#ifdef XINERAMA + m_xineramaheadmenu(0), +#endif // XINERAMA m_theme(scrn.screenNumber()), m_tool_factory(scrn), m_strut(0), @@ -629,6 +628,10 @@ void Toolbar::update(FbTk::Subject *subj) { else reconfigure(); +#ifdef XINERAMA + if (subj == &m_screen.resizeSig() && m_xineramaheadmenu) + m_xineramaheadmenu->reloadHeads(); +#endif // XINERAMA } void Toolbar::setPlacement(Toolbar::Placement where) { @@ -872,6 +875,7 @@ void Toolbar::setupMenus(bool skip_new_placement) { #ifdef XINERAMA if (screen().hasXinerama()) { menu().insert(_FB_XTEXT(Menu, OnHead, "On Head...", "Title of On Head menu"), + m_xineramaheadmenu = new XineramaHeadMenu(screen().menuTheme(), screen(), screen().imageControl(), diff --git a/src/Toolbar.hh b/src/Toolbar.hh index c528102..c295e24 100644 --- a/src/Toolbar.hh +++ b/src/Toolbar.hh @@ -31,6 +31,10 @@ #include "ToolTheme.hh" #include "Layer.hh" +#ifdef XINERAMA +#include "Xinerama.hh" +#endif // XINERAMA + #include "FbTk/Timer.hh" #include "FbTk/Resource.hh" #include "FbTk/Observer.hh" @@ -159,6 +163,9 @@ private: FbTk::XLayerItem m_layeritem; ///< layer item, must be declared before layermenu LayerMenu m_layermenu; FbMenu m_placementmenu, m_toolbarmenu; +#ifdef XINERAMA + XineramaHeadMenu *m_xineramaheadmenu; +#endif // XINERAMA // themes diff --git a/src/Xinerama.hh b/src/Xinerama.hh index f58b4f0..eab2e37 100644 --- a/src/Xinerama.hh +++ b/src/Xinerama.hh @@ -25,6 +25,7 @@ #include "FbMenu.hh" #include "fluxbox.hh" +#include "Screen.hh" #include "FbTk/RefCount.hh" #include "FbTk/SimpleCommand.hh" @@ -59,14 +60,16 @@ private: /// Create a xinerama menu template -class XineramaHeadMenu : public FbMenu { +class XineramaHeadMenu : public ToggleMenu { public: XineramaHeadMenu(FbTk::ThemeProxy &tm, BScreen &screen, FbTk::ImageControl &imgctrl, FbTk::XLayer &layer, ItemType &item, const FbTk::FbString & title = ""); + void reloadHeads(); private: ItemType &m_object; + BScreen &m_screen; }; @@ -75,15 +78,22 @@ XineramaHeadMenu::XineramaHeadMenu( FbTk::ThemeProxy &tm, BScreen &screen, FbTk::ImageControl &imgctrl, FbTk::XLayer &layer, ItemType &item, const FbTk::FbString & title): - FbMenu(tm, imgctrl, layer), - m_object(item) + ToggleMenu(tm, imgctrl, layer), + m_object(item), m_screen(screen) { setLabel(title); + reloadHeads(); +} + +template +void XineramaHeadMenu::reloadHeads() +{ + removeAll(); FbTk::RefCount > saverc_cmd(new FbTk::SimpleCommand( *Fluxbox::instance(), &Fluxbox::save_rc)); char tname[128]; - for (int i=1; i <= screen.numHeads(); ++i) { + for (int i=1; i <= m_screen.numHeads(); ++i) { // TODO: nls /* sprintf(tname, I18n::instance()-> -- cgit v0.11.2 From f605312c489378ee3c2070468cc9f115419a9cee Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Tue, 25 Dec 2007 23:30:34 +0100 Subject: Move dockapps to (-100,-100) instead of (screenw + 10, screenh + 10). The windows used to appear when one xrandr'ed to a bigger resolution. Signed-off-by: Tomas Janousek --- src/Slit.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Slit.cc b/src/Slit.cc index b8ff368..e8b6ee0 100644 --- a/src/Slit.cc +++ b/src/Slit.cc @@ -481,8 +481,7 @@ void Slit::addClient(Window w) { if (wmhints != 0) { if ((wmhints->flags & IconWindowHint) && (wmhints->icon_window != None)) { - XMoveWindow(disp, client->clientWindow(), screen().width() + 10, - screen().height() + 10); + XMoveWindow(disp, client->clientWindow(), -100, -100); XMapWindow(disp, client->clientWindow()); client->setIconWindow(wmhints->icon_window); client->setWindow(client->iconWindow()); -- cgit v0.11.2 From 5c85fcbe648b5b4581db1ca2303d5f849a63c28c Mon Sep 17 00:00:00 2001 From: Tomas Janousek Date: Sun, 27 Jan 2008 15:31:54 +0100 Subject: Changelog entries for the xinerama_randr branch changes. Signed-off-by: Tomas Janousek --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 687ef64..bdf4ff9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ (Format: Year/Month/Day) Changes for 1.0.1: +*08/01/27: + * Reload the Xinerama layout on RandR signal (Tomas) + Screen.cc/hh + * Move windows out of inactive heads upon Xinerama layout change (Tomas) + Screen.cc/hh *07/12/28: * Added new key command :Delay {} [], which runs the command after a delay of microseconds (default is 200 milliseconds) (Mark) -- cgit v0.11.2