all repos — fluxbox @ 2928b32f3a399527113325de3db39cd75db4ee8e

custom fork of the fluxbox windowmanager

merged with embedded-tab-branch
fluxgen fluxgen
commit

2928b32f3a399527113325de3db39cd75db4ee8e

parent

b6ca956c821e1e968dda10ee7852c6933b549b08

M src/FbWinFrame.ccsrc/FbWinFrame.cc

@@ -19,16 +19,18 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: FbWinFrame.cc,v 1.16 2003/04/09 17:20:01 rathnor Exp $ +// $Id: FbWinFrame.cc,v 1.17 2003/04/14 14:40:30 fluxgen Exp $ #include "FbWinFrame.hh" #include "ImageControl.hh" #include "EventManager.hh" +#include "TextButton.hh" #include "App.hh" #ifdef SHAPE //#include "Shape.hh" #endif // SHAPE +#include <algorithm> #include <iostream> using namespace std;

@@ -63,17 +65,18 @@ m_clientarea(m_window, 0, 0, 100, 100,

ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | ExposureMask | EnterWindowMask | LeaveWindowMask), - m_clientwin(0), m_bevel(1), m_use_titlebar(true), m_use_handle(true), m_focused(false), m_button_pm(0), m_themelistener(*this) { + // m_shape(new Shape(m_window, 0)) { //Shape::TOPLEFT | Shape::TOPRIGHT)) { theme.addListener(m_themelistener); init(); } + /* FbWinFrame::FbWinFrame(FbWinFrameTheme &theme, FbTk::ImageControl &imgctrl, const FbTk::FbWindow &parent, int x, int y, unsigned int width, unsigned int height):

@@ -88,7 +91,6 @@ m_grip_right(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask),

m_grip_left(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask), m_handle(m_window, 0, 0, 100, 100, ExposureMask | ButtonPressMask | ButtonReleaseMask), m_clientarea(m_window, 0, 0, 100, 100, SubstructureRedirectMask), - m_clientwin(0), m_bevel(1), m_use_titlebar(true), m_use_handles(true),

@@ -101,7 +103,6 @@

FbWinFrame::~FbWinFrame() { removeEventHandler(); removeAllButtons(); - } bool FbWinFrame::setOnClickTitlebar(FbTk::RefCount<FbTk::Command> &ref, int mousebutton_num,

@@ -215,7 +216,6 @@

setupButton(*btn); // setup theme and other stuff m_buttons_left.push_back(btn); - reconfigureTitlebar(); } void FbWinFrame::addRightButton(FbTk::Button *btn) {

@@ -225,7 +225,6 @@

setupButton(*btn); // setup theme and other stuff m_buttons_right.push_back(btn); - reconfigureTitlebar(); } void FbWinFrame::removeAllButtons() {

@@ -239,21 +238,44 @@ while (!m_buttons_right.empty()) {

delete m_buttons_right.back(); m_buttons_right.pop_back(); } +} - // update titlebar - reconfigureTitlebar(); +void FbWinFrame::addLabelButton(FbTk::Button &btn) { + ButtonList::iterator found_it = find(m_labelbuttons.begin(), + m_labelbuttons.end(), + &btn); + + if (found_it != m_labelbuttons.end()) + return; + + m_labelbuttons.push_back(&btn); +} + +void FbWinFrame::removeLabelButton(FbTk::Button &btn) { + ButtonList::iterator erase_it = remove(m_labelbuttons.begin(), + m_labelbuttons.end(), + &btn); + if (erase_it == m_labelbuttons.end()) + return; + + m_labelbuttons.erase(erase_it); +} + +void FbWinFrame::setClientWindow(FbTk::FbWindow &win) { + setClientWindow(win.window()); } void FbWinFrame::setClientWindow(Window win) { - m_clientwin = win; Display *display = FbTk::App::instance()->display(); XSetWindowBorderWidth(display, win, 0); XChangeSaveSet(display, win, SetModeInsert); XSetWindowAttributes attrib_set; - // no events for client window while we reparent it - XSelectInput(display, m_clientarea.window(), NoEventMask); + // sync old events so we can discard events from reparent later + XSync(display, False); XReparentWindow(display, win, m_clientarea.window(), 0, 0); + XSync(display, True); // discard unmap notify event + // redirected events from client window XSelectInput(display, m_clientarea.window(), SubstructureRedirectMask); XFlush(display);

@@ -266,10 +288,6 @@

m_clientarea.raise(); m_clientarea.showSubwindows(); -} - -void FbWinFrame::removeClient() { - m_clientwin = 0; } void FbWinFrame::hideTitlebar() {

@@ -373,10 +391,16 @@ evm.remove(m_clientarea);

} void FbWinFrame::buttonPressEvent(XButtonEvent &event) { - if (event.window != m_titlebar.window() && - event.window != m_label.window()) - return; - + // we can ignore which window the event was generated for + ButtonList::iterator btn_it = m_labelbuttons.begin(); + ButtonList::iterator btn_it_end = m_labelbuttons.end(); + for (; btn_it != btn_it_end; ++btn_it) { + if ((*btn_it)->window() == event.window) { + (*btn_it)->buttonPressEvent(event); + break; + } + } + if (event.button > 5 || event.button < 1) return;

@@ -385,11 +409,19 @@ m_commands[event.button - 1].click_pressed->execute();

} void FbWinFrame::buttonReleaseEvent(XButtonEvent &event) { - if (event.window != m_titlebar.window() && - event.window != m_label.window()) - return; + // we can ignore which window the event was generated for + + ButtonList::iterator btn_it = m_labelbuttons.begin(); + ButtonList::iterator btn_it_end = m_labelbuttons.end(); + for (; btn_it != btn_it_end; ++btn_it) { + if ((*btn_it)->window() == event.window) { + (*btn_it)->buttonReleaseEvent(event); + break; + } + } - if (event.button < 1 || event.button > 5) + if (event.button < 1 || event.button > 5 || + event.window == m_clientarea.window()) return; static int last_release_time = 0;

@@ -405,14 +437,15 @@

} void FbWinFrame::exposeEvent(XExposeEvent &event) { - if (m_titlebar == event.window) - redrawTitlebar(); - else if (m_label == event.window) + if (m_label == event.window) redrawTitle(); else if (m_handle == event.window || m_grip_left == event.window || m_grip_right == event.window) renderHandles(); + else + redrawTitlebar(); + } void FbWinFrame::handleEvent(XEvent &event) {

@@ -432,6 +465,7 @@

// align titlebar and render it if (m_use_titlebar) reconfigureTitlebar(); + // leave client+grips alone if we're shaded (it'll get fixed when we unshade) if (!m_shaded) {

@@ -451,12 +485,6 @@

m_clientarea.moveResize(0, client_top, m_window.width(), client_height); - if (m_clientwin != 0) { - XMoveResizeWindow(FbTk::App::instance()->display(), m_clientwin, - 0, 0, - m_clientarea.width(), m_clientarea.height()); - } - if (!m_use_handle) // no need to do anything more return;

@@ -471,7 +499,8 @@ m_grip_left.moveResize(-m_handle.borderWidth(), ypos,

grip_width, grip_height); m_handle.moveResize(grip_width, ypos, - m_window.width() - grip_width*2 - m_handle.borderWidth()*2, grip_height); + m_window.width() - grip_width*2 - m_handle.borderWidth()*2, + grip_height); m_grip_right.moveResize(m_window.width() - grip_width - m_handle.borderWidth(), ypos, grip_width, grip_height);

@@ -500,24 +529,22 @@ /**

aligns and redraws title */ void FbWinFrame::redrawTitle() { - GC gc = m_theme.labelTextFocusGC(); - m_label.clear(); // clear window - unsigned int textlen = m_titletext.size(); - const FbTk::Font &font = m_theme.font(); - // do text alignment - int align_x = FbTk::doAlignment(m_label.width(), - m_bevel, - m_theme.justify(), - font, - m_titletext.c_str(), m_titletext.size(), - textlen // return new text len - ); + if (m_labelbuttons.size() == 0) + return; - font.drawText(m_label.window(), // drawable - m_window.screenNumber(), - gc, // graphic context - m_titletext.c_str(), textlen, // string and string size - align_x, font.ascent());// position + int button_width = label().width()/m_labelbuttons.size(); + //!! TODO: bevel + ButtonList::iterator btn_it = m_labelbuttons.begin(); + ButtonList::iterator btn_it_end = m_labelbuttons.end(); + for (unsigned int last_x = 0; + btn_it != btn_it_end; + ++btn_it, last_x += button_width) { + (*btn_it)->moveResize(last_x, 0, + button_width, label().height()); + (*btn_it)->setGC(theme().labelTextFocusGC()); + (*btn_it)->clear(); + } + } void FbWinFrame::redrawTitlebar() {

@@ -549,7 +576,7 @@ for (size_t i=0; i < m_buttons_left.size(); i++, next_x += button_size + m_bevel) {

m_buttons_left[i]->moveResize(next_x, m_bevel, button_size, button_size); } - + next_x += m_bevel; // space left on titlebar between left and right buttons

@@ -600,23 +627,32 @@ m_label_unfocused_pm,

m_label.width(), m_label.height()); // finaly set up pixmaps for titlebar windows - + Pixmap labelpm = None; + FbTk::Color labelcolor; + if (m_focused) { - if (m_label_focused_pm != 0) + if (m_label_focused_pm != 0){ + labelpm = m_label_focused_pm; m_label.setBackgroundPixmap(m_label_focused_pm); - else + } else { + labelcolor = m_label_focused_color; m_label.setBackgroundColor(m_label_focused_color); - + } + if (m_title_focused_pm != 0) - m_titlebar.setBackgroundPixmap(m_title_focused_pm); + m_titlebar.setBackgroundPixmap(m_title_focused_pm); else m_titlebar.setBackgroundColor(m_title_focused_color); } else { - if (m_label_unfocused_pm != 0) + if (m_label_unfocused_pm != 0) { + labelpm = m_label_unfocused_pm; m_label.setBackgroundPixmap(m_label_unfocused_pm); - else + } else { + labelcolor = m_label_unfocused_color; m_label.setBackgroundColor(m_label_unfocused_color); + } + if (m_title_unfocused_pm != 0) m_titlebar.setBackgroundPixmap(m_title_unfocused_pm);

@@ -625,6 +661,15 @@ m_titlebar.setBackgroundColor(m_title_unfocused_color);

} + ButtonList::iterator btn_it = m_labelbuttons.begin(); + ButtonList::iterator btn_it_end = m_labelbuttons.end(); + for (; btn_it != btn_it_end; ++btn_it) { + if (labelpm) + (*btn_it)->setBackgroundPixmap(labelpm); + else + (*btn_it)->setBackgroundColor(labelcolor); + } + redrawTitle(); }
M src/FbWinFrame.hhsrc/FbWinFrame.hh

@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: FbWinFrame.hh,v 1.4 2003/02/15 01:54:18 fluxgen Exp $ +// $Id: FbWinFrame.hh,v 1.5 2003/04/14 14:38:21 fluxgen Exp $ #ifndef FBWINFRAME_HH #define FBWINFRAME_HH

@@ -85,10 +85,15 @@ /// add a button to the right of the label

void addRightButton(FbTk::Button *btn); /// remove all buttons from titlebar void removeAllButtons(); + /// adds a button to label window + void addLabelButton(FbTk::Button &btn); + /// removes a specific button from label window + void removeLabelButton(FbTk::Button &btn); + /// attach a client window for client area void setClientWindow(Window win); - /// same as above but with FbWindow, NOT IMPLEMENTED! - void setClientWindow(FbTk::FbWindow win); + /// same as above but with FbWindow + void setClientWindow(FbTk::FbWindow &win); /// remove attached client window void removeClient(); /// redirect events to another eventhandler

@@ -143,6 +148,7 @@ inline const FbTk::FbWindow &gripRight() const { return m_grip_right; }

inline FbTk::FbWindow &gripRight() { return m_grip_right; } inline bool focused() const { return m_focused; } inline bool isShaded() const { return m_shaded; } + inline const FbWinFrameTheme &theme() const { return m_theme; } /// @return titlebar height unsigned int titleHeight() const; /// @return size of button

@@ -186,12 +192,11 @@ FbTk::FbWindow m_grip_right, ///< rightgrip

m_grip_left; ///< left grip FbTk::FbWindow m_handle; ///< handle between grips FbTk::FbWindow m_clientarea; ///< window that holds client window @see setClientWindow - Window m_clientwin; ///< client window in clientarea //@} typedef std::vector<FbTk::Button *> ButtonList; ButtonList m_buttons_left, ///< buttons to the left m_buttons_right; ///< buttons to the right - + ButtonList m_labelbuttons; ///< holds buttons inside label window std::string m_titletext; ///< text to be displayed int m_label int m_bevel; ///< bevel between titlebar items and titlebar bool m_use_titlebar; ///< if we should use titlebar
M src/IconBar.ccsrc/IconBar.cc

@@ -13,13 +13,13 @@ // all copies or substantial portions of the Software.

// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: IconBar.cc,v 1.28 2003/04/09 17:20:02 rathnor Exp $ +// $Id: IconBar.cc,v 1.29 2003/04/14 14:44:17 fluxgen Exp $ #include "IconBar.hh"

@@ -287,15 +287,15 @@ CWColormap | CWOverrideRedirect | CWEventMask;

XSetWindowAttributes attrib; attrib.background_pixmap = None; attrib.background_pixel = attrib.border_pixel = - fluxboxwin->getScreen()->getWindowStyle()->tab.border_color.pixel(); - attrib.colormap = fluxboxwin->getScreen()->colormap(); + fluxboxwin->getScreen().getWindowStyle()->tab.border_color.pixel(); + attrib.colormap = fluxboxwin->getScreen().colormap(); attrib.override_redirect = True; attrib.event_mask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | ExposureMask | EnterWindowMask; //create iconwindow Window iconwin = XCreateWindow(m_display, parent, 0, 0, 1, 1, 0, - fluxboxwin->getScreen()->getDepth(), InputOutput, fluxboxwin->getScreen()->getVisual(), + fluxboxwin->getScreen().getDepth(), InputOutput, fluxboxwin->getScreen().getVisual(), attrib_mask, &attrib); return iconwin;
M src/IconBar.hhsrc/IconBar.hh

@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: IconBar.hh,v 1.12 2003/04/09 12:59:57 fluxgen Exp $ +// $Id: IconBar.hh,v 1.13 2003/04/14 14:43:58 fluxgen Exp $ #ifndef ICONBAR_HH #define ICONBAR_HH

@@ -76,10 +76,8 @@ void setVertical(bool value) { m_vertical = value; }

private: typedef std::list<IconBarObj *> IconList; -// void draw(IconBarObj *obj, int width); void loadTheme(unsigned int width, unsigned int height); void decorate(Window win); -// IconBarObj *findIcon(FluxboxWindow *fluxboxwin); void repositionIcons(); Window createIconWindow(FluxboxWindow *fluxboxwin, Window parent); BScreen *m_screen;
M src/Makefile.amsrc/Makefile.am

@@ -59,12 +59,13 @@ Netizen.cc Netizen.hh nl_types_cygnus.h \

Resource.hh Resource.cc \ Screen.cc Screen.hh \ Slit.cc Slit.hh StringUtil.cc StringUtil.hh \ - Tab.hh Tab.cc Theme.hh Theme.cc \ + TextButton.hh TextButton.cc \ + Theme.hh Theme.cc \ Toolbar.cc Toolbar.hh \ ToolbarHandler.cc ToolbarHandler.hh \ ToolbarTheme.hh ToolbarTheme.cc \ WinButton.hh WinButton.cc Window.cc Window.hh \ Workspace.cc Workspace.hh \ XrmDatabaseHelper.hh FbCommands.hh FbCommands.cc LayerMenu.hh \ - IntResMenuItem.hh IntResMenuItem.cc FbMenu.hh + IntResMenuItem.hh IntResMenuItem.cc FbMenu.hh WinClient.hh WinClient.cc LDADD=FbTk/libFbTk.a
M src/Screen.ccsrc/Screen.cc

@@ -1,5 +1,5 @@

// Screen.cc for Fluxbox Window Manager -// Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxgen at users.sourceforge.net) +// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) // // Screen.cc for Blackbox - an X11 Window manager // Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Screen.cc,v 1.118 2003/03/22 05:13:08 rathnor Exp $ +// $Id: Screen.cc,v 1.119 2003/04/14 14:49:47 fluxgen Exp $ #include "Screen.hh"

@@ -47,6 +47,7 @@ #include "XLayerItem.hh"

#include "MultLayers.hh" #include "FbMenu.hh" #include "LayerMenu.hh" +#include "WinClient.hh" //use GNU extensions #ifndef _GNU_SOURCE

@@ -111,6 +112,7 @@

#include <iostream> #include <memory> #include <algorithm> +#include <functional> using namespace std;

@@ -158,18 +160,6 @@

}; // End anonymous namespace -//---------- resource manipulators --------- -template<> -void Resource<Tab::Alignment>:: -setFromString(const char *strval) { - m_value = Tab::getTabAlignmentNum(strval); -} - -template<> -void Resource<Tab::Placement>:: -setFromString(const char *strval) { - m_value = Tab::getTabPlacementNum(strval); -} template<> void Resource<Toolbar::Placement>::

@@ -221,20 +211,6 @@ else

setDefaultValue(); } - -//--------- resource accessors -------------- -template<> -string Resource<Tab::Alignment>:: -getString() { - return Tab::getTabAlignmentString(m_value); -} - -template<> -string Resource<Tab::Placement>:: -getString() { - return Tab::getTabPlacementString(m_value); -} - template<> string Resource<Toolbar::Placement>:: getString() {

@@ -401,7 +377,6 @@ image_dither(rm, false, scrname+".imageDither", altscrname+".ImageDither"),

opaque_move(rm, false, "session.opaqueMove", "Session.OpaqueMove"), full_max(rm, true, scrname+".fullMaximization", altscrname+".FullMaximization"), max_over_slit(rm, true, scrname+".maxOverSlit",altscrname+".MaxOverSlit"), - tab_rotate_vertical(rm, true, scrname+".tab.rotatevertical", altscrname+".Tab.RotateVertical"), sloppy_window_grouping(rm, true, scrname+".sloppywindowgrouping", altscrname+".SloppyWindowGrouping"), workspace_warping(rm, true, scrname+".workspacewarping", altscrname+".WorkspaceWarping"), desktop_wheeling(rm, true, scrname+".desktopwheeling", altscrname+".DesktopWheeling"),

@@ -415,12 +390,8 @@ focus_model(rm, Fluxbox::CLICKTOFOCUS, scrname+".focusModel", altscrname+".FocusModel"),

workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"), toolbar_width_percent(rm, 65, scrname+".toolbar.widthPercent", altscrname+".Toolbar.WidthPercent"), edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"), - tab_width(rm, 64, scrname+".tab.width", altscrname+".Tab.Width"), - tab_height(rm, 16, scrname+".tab.height", altscrname+".Tab.Height"), slit_layernum(rm, Fluxbox::instance()->getDockLayer(), scrname+".slit.layer", altscrname+".Slit.Layer"), toolbar_layernum(rm, Fluxbox::instance()->getDesktopLayer(), scrname+".toolbar.layer", altscrname+".Toolbar.Layer"), - tab_placement(rm, Tab::PTOP, scrname+".tab.placement", altscrname+".Tab.Placement"), - tab_alignment(rm, Tab::ALEFT, scrname+".tab.alignment", altscrname+".Tab.Alignment"), toolbar_mode(rm, ToolbarHandler::ICONS, scrname+".toolbar.mode", altscrname+".Toolbar.Mode"), toolbar_on_head(rm, 0, scrname+".toolbar.onhead", altscrname+".Toolbar.onHead"), toolbar_placement(rm, Toolbar::BOTTOMCENTER, scrname+".toolbar.placement", altscrname+".Toolbar.Placement")

@@ -502,14 +473,6 @@

// set database for new Theme Engine FbTk::ThemeManager::instance().load(fluxbox->getStyleFilename().c_str()); - // special case for tab rotated - if (*resource.tab_rotate_vertical && - ( *resource.tab_placement == Tab::PLEFT || *resource.tab_placement == Tab::PRIGHT)) { - theme->getWindowStyle().tab.font.rotate(90); - } else { - theme->getWindowStyle().tab.font.rotate(0); - } - const char *s = i18n->getMessage( FBNLS::ScreenSet, FBNLS::ScreenPositionLength, "W: 0000 x H: 0000");

@@ -583,6 +546,7 @@ setupWorkspacemenu(*this, *workspacemenu);

m_configmenu.reset(createMenuFromScreen(*this)); setupConfigmenu(*m_configmenu.get()); + // m_configmenu->setInternalMenu(); workspacemenu->setItemSelected(2, true);

@@ -813,19 +777,14 @@ }

#endif // SLIT //reconfigure workspaces - Workspaces::iterator wit = workspacesList.begin(); - Workspaces::iterator wit_end = workspacesList.end(); - for (; wit != wit_end; ++wit) { - (*wit)->reconfigure(); - } + for_each(workspacesList.begin(), + workspacesList.end(), + mem_fun(&Workspace::reconfigure)); //reconfigure Icons - Icons::iterator iit = iconList.begin(); - Icons::iterator iit_end = iconList.end(); - for (; iit != iit_end; ++iit) { - if ((*iit)->validateClient()) - (*iit)->reconfigure(); - } + for_each(iconList.begin(), + iconList.end(), + mem_fun(&FluxboxWindow::reconfigure)); image_control->timeout(); }

@@ -860,16 +819,13 @@ void BScreen::removeIcon(FluxboxWindow *w) {

if (! w) return; - { - Icons::iterator it = iconList.begin(); - Icons::iterator it_end = iconList.end(); - for (; it != it_end; ++it) { - if (*it == w) { - iconList.erase(it); - break; - } - } - } + + Icons::iterator erase_it = remove_if(iconList.begin(), + iconList.end(), + bind2nd(equal_to<FluxboxWindow *>(), w)); + if (erase_it != iconList.end()) + iconList.erase(erase_it); + Icons::iterator it = iconList.begin(); Icons::iterator it_end = iconList.end();

@@ -881,9 +837,8 @@

void BScreen::removeWindow(FluxboxWindow *win) { Workspaces::iterator it = workspacesList.begin(); Workspaces::iterator it_end = workspacesList.end(); - for (; it != it_end; ++it) { + for (; it != it_end; ++it) (*it)->removeWindow(win); - } } FluxboxWindow *BScreen::getIcon(unsigned int index) {

@@ -967,12 +922,13 @@ // don't reassociate if not opaque moving

focused->pauseMoving(); } + // reassociate all windows that are stuck to the new workspace Workspace *wksp = getCurrentWorkspace(); Workspace::Windows wins = wksp->getWindowList(); Workspace::Windows::iterator it = wins.begin(); for (; it != wins.end(); ++it) { if ((*it)->isStuck()) { - reassociateGroup(*it,id,true); + reassociateGroup(*it, id, true); } }

@@ -980,7 +936,7 @@ current_workspace->hideAll();

workspacemenu->setItemSelected(current_workspace->workspaceID() + 2, false); - if (focused && focused->getScreen() == this && + if (focused && &focused->getScreen() == this && (! focused->isStuck()) && (!focused->isMoving())) { current_workspace->setLastFocusedWindow(focused); Fluxbox::instance()->setFocusedWindow(0); // set focused window to none

@@ -1022,14 +978,8 @@

if (id != current_workspace->workspaceID()) { XSync(BaseDisplay::getXDisplay(), True); - if (win && win->getScreen() == this && + if (win && &win->getScreen() == this && (! win->isStuck())) { - - if ( win->getTab() ) { - Tab *tab = win->getTab(); - tab->disconnect(); - tab->setPosition(); - } if (win->isIconic()) { win->deiconify();

@@ -1090,26 +1040,18 @@

void BScreen::updateNetizenCurrentWorkspace() { m_currentworkspace_sig.notify(); - - Netizens::iterator it = netizenList.begin(); - Netizens::iterator it_end = netizenList.end(); - for (; it != it_end; ++it) { - (*it)->sendCurrentWorkspace(); - } - + for_each(netizenList.begin(), + netizenList.end(), + mem_fun(&Netizen::sendCurrentWorkspace)); } void BScreen::updateNetizenWorkspaceCount() { - - Netizens::iterator it = netizenList.begin(); - Netizens::iterator it_end = netizenList.end(); - for (; it != it_end; ++it) { - (*it)->sendWorkspaceCount(); - } + for_each(netizenList.begin(), + netizenList.end(), + mem_fun(&Netizen::sendWorkspaceCount)); m_workspacecount_sig.notify(); - }

@@ -1175,7 +1117,7 @@ }

} FluxboxWindow *BScreen::createWindow(Window client) { - FluxboxWindow *win = new FluxboxWindow(client, this, getScreenNumber(), *getImageControl(), + FluxboxWindow *win = new FluxboxWindow(client, *this, winFrameTheme(), *menuTheme(), *layerManager().getLayer(Fluxbox::instance()->getNormalLayer()));

@@ -1199,6 +1141,27 @@ XSync(FbTk::App::instance()->display(), False);

return win; } +FluxboxWindow *BScreen::createWindow(WinClient &client) { + FluxboxWindow *win = new FluxboxWindow(client, *this, + winFrameTheme(), *menuTheme(), + *layerManager().getLayer(Fluxbox::instance()->getNormalLayer())); +#ifdef SLIT + if (win->initialState() == WithdrawnState) + getSlit()->addClient(win->getClientWindow()); +#endif // SLIT + if (!win->isManaged()) { + delete win; + return 0; + } + Fluxbox::instance()->saveWindowSearch(client.window(), win); + Fluxbox::instance()->attachSignals(*win); + setupWindowActions(*win); + if (win->getWorkspaceNumber() == getCurrentWorkspaceID() || win->isStuck()) { + win->show(); + } + return win; +} + void BScreen::setupWindowActions(FluxboxWindow &win) { FbWinFrame &frame = win.frame();

@@ -1267,7 +1230,6 @@ newbutton = new WinButton(WinButton::SHADE,

frame.titlebar(), 0, 0, 10, 10); newbutton->setOnClick(shade_cmd); - } if (newbutton != 0) {

@@ -1280,6 +1242,8 @@ }

} //end for i dir = &Fluxbox::instance()->getTitlebarRight(); } // end for c + + frame.reconfigure(); // setup titlebar frame.setOnClickTitlebar(raise_and_focus_cmd, 1, false, true); // on press with button 1

@@ -1301,7 +1265,12 @@ menu.insert("Maximize Horizontal", maximize_horiz_cmd);

menu.insert("Iconify", iconify_cmd); menu.insert("Raise", raise_cmd); menu.insert("Lower", lower_cmd); - menu.insert("Layer...", win.getLayermenu()); + menu.insert("Layer...", &win.getLayermenu()); + CommandRef next_client_cmd(new WindowCmd(win, &FluxboxWindow::nextClient)); + CommandRef prev_client_cmd(new WindowCmd(win, &FluxboxWindow::prevClient)); + menu.insert("Next Client", next_client_cmd); + menu.insert("Prev Client", prev_client_cmd); + menu.insert("ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ"); menu.insert("Close", close_cmd);

@@ -1330,19 +1299,13 @@ }

} void BScreen::reassociateGroup(FluxboxWindow *w, unsigned int wkspc_id, bool ignore_sticky) { - if (w->hasTab() && (w->getTab()->next() || w->getTab()->prev())) { - Tab *tab_it = w->getTab()->first(); - for (; tab_it; tab_it = tab_it->next()) { - reassociateWindow(tab_it->getWindow(), wkspc_id, ignore_sticky); - } - } else { - // no tab, juts move this one - reassociateWindow(w, wkspc_id, ignore_sticky); - } + //!! TODO + cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO!"<<endl; } void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id, bool ignore_sticky) { - if (! w) return; + if (w == 0) + return; if (wkspc_id >= getCount()) { wkspc_id = current_workspace->workspaceID();

@@ -1357,10 +1320,10 @@

if (w->isIconic()) { removeIcon(w); - getWorkspace(wkspc_id)->addWindow(w); + getWorkspace(wkspc_id)->addWindow(*w); } else if (ignore_sticky || ! w->isStuck()) { getWorkspace(w->getWorkspaceNumber())->removeWindow(w); - getWorkspace(wkspc_id)->addWindow(w); + getWorkspace(wkspc_id)->addWindow(*w); } }

@@ -1372,7 +1335,7 @@ FluxboxWindow *focused = Fluxbox::instance()->getFocusedWindow();

const int num_windows = getCurrentWorkspace()->getCount(); if (focused != 0) { - if (focused->getScreen()->getScreenNumber() == + if (focused->getScreen().getScreenNumber() == getScreenNumber()) { have_focused = true; focused_window_number = focused->getWindowNumber();

@@ -1385,9 +1348,9 @@ Workspace::Windows &wins = wksp->getWindowList();

Workspace::Windows::iterator it = wins.begin(); if (!have_focused) { - focused = *it; + focused = (*it); } else { - for (; *it != focused; ++it) //get focused window iterator + for (; (*it) != focused; ++it) //get focused window iterator continue; } do {

@@ -1395,11 +1358,11 @@ ++it;

if (it == wins.end()) it = wins.begin(); // see if the window should be skipped - if (! (doSkipWindow(*it, opts) || !(*it)->setInputFocus()) ) + if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) ) break; - } while (*it != focused); + } while ((*it) != focused); - if (*it != focused && it != wins.end()) + if ((*it) != focused && it != wins.end()) (*it)->raise(); }

@@ -1414,7 +1377,7 @@ FluxboxWindow *focused;

int num_windows = getCurrentWorkspace()->getCount(); if ((focused = Fluxbox::instance()->getFocusedWindow())) { - if (focused->getScreen()->getScreenNumber() == + if (focused->getScreen().getScreenNumber() == getScreenNumber()) { have_focused = true; focused_window_number = focused->getWindowNumber();

@@ -1427,9 +1390,9 @@ Workspace::Windows &wins = wksp->getWindowList();

Workspace::Windows::iterator it = wins.begin(); if (!have_focused) { - focused = *it; + focused = (*it); } else { - for (; *it != focused; ++it) //get focused window iterator + for (; (*it) != focused; ++it) //get focused window iterator continue; }

@@ -1438,11 +1401,11 @@ if (it == wins.begin())

it = wins.end(); --it; // see if the window should be skipped - if (! (doSkipWindow(*it, opts) || !(*it)->setInputFocus()) ) + if (! (doSkipWindow((*it), opts) || !(*it)->setInputFocus()) ) break; - } while (*it != focused); + } while ((*it) != focused); - if (*it != focused && it != wins.end()) + if ((*it) != focused && it != wins.end()) (*it)->raise(); }

@@ -1455,7 +1418,7 @@ int focused_window_number = -1;

Fluxbox * const fb = Fluxbox::instance(); if (fb->getFocusedWindow()) - if (fb->getFocusedWindow()->getScreen()->getScreenNumber() == + if (fb->getFocusedWindow()->getScreen().getScreenNumber() == getScreenNumber()) { have_focused = true; focused_window_number = fb->getFocusedWindow()->getWindowNumber();

@@ -1469,6 +1432,15 @@ void BScreen::initMenu() {

I18n *i18n = I18n::instance(); if (m_rootmenu.get()) { + /* Rootmenus::iterator it = rootmenuList.begin(); + Rootmenus::iterator it_end = rootmenuList.end(); + for (; it != it_end; ++it) { + if (*it != m_configmenu.get()) { + delete *it; + } + } + rootmenuList.clear(); + */ rootmenuList.erase(rootmenuList.begin(), rootmenuList.end()); while (m_rootmenu->numberOfItems())

@@ -1938,17 +1910,13 @@

} void BScreen::shutdown() { - XSelectInput(getBaseDisplay()->getXDisplay(), getRootWindow(), NoEventMask); - XSync(getBaseDisplay()->getXDisplay(), False); - - - Workspaces::iterator it = workspacesList.begin(); - Workspaces::iterator it_end = workspacesList.end(); - for (; it != it_end; ++it) { - (*it)->shutdown(); - } - + Display *disp = FbTk::App::instance()->display(); + XSelectInput(disp, getRootWindow(), NoEventMask); + XSync(disp, False); + for_each(workspacesList.begin(), + workspacesList.end(), + mem_fun(&Workspace::shutdown)); while (!iconList.empty()) { iconList.back()->restore(true); // restore with remap
M src/Toolbar.ccsrc/Toolbar.cc

@@ -1,5 +1,5 @@

// Toolbar.cc for Fluxbox -// Copyright (c) 2002 Henrik Kinnunen (fluxgen at users.sourceforge.net) +// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) // // Toolbar.cc for Blackbox - an X11 Window manager // Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Toolbar.cc,v 1.68 2003/04/09 17:20:04 rathnor Exp $ +// $Id: Toolbar.cc,v 1.69 2003/04/14 14:53:56 fluxgen Exp $ #include "Toolbar.hh"

@@ -736,7 +736,7 @@ frame.window_label.clear();

FluxboxWindow *foc = Fluxbox::instance()->getFocusedWindow(); // don't draw focused window if it's not on the same screen - if (foc->getScreen() != &screen() || foc->getTitle().size() == 0) + if (&foc->getScreen() != &screen() || foc->getTitle().size() == 0) return; unsigned int newlen = foc->getTitle().size();
M src/ToolbarHandler.ccsrc/ToolbarHandler.cc

@@ -20,7 +20,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: ToolbarHandler.cc,v 1.4 2003/03/23 05:07:03 rathnor Exp $ +// $Id: ToolbarHandler.cc,v 1.5 2003/04/14 15:01:55 fluxgen Exp $ /** * The ToolbarHandler class acts as a rough interface to the toolbar.

@@ -45,7 +45,9 @@ namespace {

class ToolbarModeMenuItem : public FbTk::MenuItem { public: - ToolbarModeMenuItem(const char *label, ToolbarHandler &handler, ToolbarHandler::ToolbarMode mode, FbTk::RefCount<FbTk::Command> &cmd): + ToolbarModeMenuItem(const char *label, ToolbarHandler &handler, + ToolbarHandler::ToolbarMode mode, + FbTk::RefCount<FbTk::Command> &cmd): FbTk::MenuItem(label, cmd), m_handler(handler), m_mode(mode) { } bool isEnabled() const { return m_handler.getMode() != m_mode; }

@@ -134,7 +136,8 @@ initForScreen(m_screen);

} void ToolbarHandler::initForScreen(BScreen &screen) { - if (&m_screen != &screen) return; + if (&m_screen != &screen) + return; switch (m_mode) { case OFF: break;

@@ -149,7 +152,7 @@ Workspace::Windows &wins = (*workspace_it)->getWindowList();

Workspace::Windows::iterator wit = wins.begin(); Workspace::Windows::iterator wit_end = wins.end(); for (; wit != wit_end; ++wit) { - m_toolbar->addIcon(*wit); + // m_toolbar->addIcon(*(*wit)); } } }

@@ -161,7 +164,7 @@ BScreen::Icons &iconlist = m_screen.getIconList();

BScreen::Icons::iterator iconit = iconlist.begin(); BScreen::Icons::iterator iconit_end = iconlist.end(); for(; iconit != iconit_end; ++iconit) { - m_toolbar->addIcon(*iconit); + // m_toolbar->addIcon(*iconit); } } break;

@@ -171,7 +174,7 @@ Workspace::Windows &wins = m_screen.getCurrentWorkspace()->getWindowList();

Workspace::Windows::iterator wit = wins.begin(); Workspace::Windows::iterator wit_end = wins.end(); for (; wit != wit_end; ++wit) { - m_toolbar->addIcon(*wit); + // m_toolbar->addIcon(*wit); } } // fall through and add icons for this workspace

@@ -192,7 +195,9 @@ }

} void ToolbarHandler::setupWindow(FluxboxWindow &win) { - if (win.getScreen() != &m_screen) return; + if (&win.getScreen() != &m_screen) + return; + switch (m_mode) { case OFF: case NONE:

@@ -218,7 +223,9 @@ }

} void ToolbarHandler::updateWindowClose(FluxboxWindow &win) { - if (win.getScreen() != &m_screen) return; + if (&win.getScreen() != &m_screen) + return; + // check status of window (in current workspace, etc) and remove if necessary switch (m_mode) { case OFF:

@@ -245,7 +252,8 @@ }

} void ToolbarHandler::updateState(FluxboxWindow &win) { - if (win.getScreen() != &m_screen) return; + if (&win.getScreen() != &m_screen) + return; // this function only relevant for icons switch (m_mode) {

@@ -274,12 +282,14 @@ }

void ToolbarHandler::updateWorkspace(FluxboxWindow &win) { - if (win.getScreen() != &m_screen) return; + if (&win.getScreen() != &m_screen) + return; + // don't care about current workspace except if in workspace mode if (!(m_mode == WORKSPACE || (m_mode == WORKSPACEICONS && win.isIconic()))) return; if (win.getWorkspaceNumber() == m_current_workspace) { - // TODO + //!! TODO // this shouldn't be needed, but is until Workspaces get fixed so that // you only move between them, you don't 'add' and 'remove' // alternatively, fix reassocaiteWindow so that the iconic stuff is
M src/Window.ccsrc/Window.cc

@@ -22,10 +22,11 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.cc,v 1.130 2003/04/09 17:20:06 rathnor Exp $ +// $Id: Window.cc,v 1.131 2003/04/14 14:58:12 fluxgen Exp $ #include "Window.hh" +#include "WinClient.hh" #include "i18n.hh" #include "fluxbox.hh" #include "Screen.hh"

@@ -33,6 +34,9 @@ #include "StringUtil.hh"

#include "Netizen.hh" #include "FbWinFrameTheme.hh" #include "MenuTheme.hh" + +#include "TextButton.hh" +#include "EventManager.hh" #ifdef HAVE_CONFIG_H #include "config.h"

@@ -49,6 +53,7 @@

#include <cstring> #include <cstdio> #include <iostream> + using namespace std;

@@ -82,7 +87,8 @@ ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,

GrabModeAsync, None, cursor); //capslock+numlock+scrolllock - XGrabButton(display, button, Mod1Mask|LockMask|Mod2Mask|Mod5Mask, window, True, + XGrabButton(display, button, Mod1Mask|LockMask|Mod2Mask|Mod5Mask, window, + True, ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, cursor);

@@ -117,7 +123,7 @@ /// raise window and do the same for each transient it holds

void raiseFluxboxWindow(FluxboxWindow &win) { if (!win.isIconic()) { - win.getScreen()->updateNetizenWindowRaise(win.getClientWindow()); + win.getScreen().updateNetizenWindowRaise(win.getClientWindow()); win.getLayerItem().raise(); }

@@ -134,7 +140,7 @@ /// lower window and do the same for each transient it holds

void lowerFluxboxWindow(FluxboxWindow &win) { if (!win.isIconic()) { - win.getScreen()->updateNetizenWindowLower(win.getClientWindow()); + win.getScreen().updateNetizenWindowLower(win.getClientWindow()); win.getLayerItem().lower(); }

@@ -147,10 +153,55 @@ lowerFluxboxWindow(*(*it));

} } +class SetClientCmd:public FbTk::Command { +public: + explicit SetClientCmd(WinClient &client):m_client(client) { + } + void execute() { +#ifdef DEBUG + cerr<<"SetClientCmd"<<endl; +#endif // DEBUG + if (m_client.m_win != 0) + m_client.m_win->setCurrentClient(m_client); + } +private: + WinClient &m_client; }; -FluxboxWindow::FluxboxWindow(Window w, BScreen *s, int screen_num, - FbTk::ImageControl &imgctrl, FbWinFrameTheme &tm, +}; + +FluxboxWindow::FluxboxWindow(WinClient &client, BScreen &scr, FbWinFrameTheme &tm, + FbTk::MenuTheme &menutheme, + FbTk::XLayer &layer): + m_hintsig(*this), + m_statesig(*this), + m_layersig(*this), + m_workspacesig(*this), + m_diesig(*this), + moving(false), resizing(false), shaded(false), maximized(false), + visible(false), iconic(false), transient(false), focused(false), + stuck(false), modal(false), send_focus_message(false), m_managed(false), + screen(scr), + timer(this), + display(0), + lastButtonPressTime(0), + m_windowmenu(menutheme, scr.getScreenNumber(), *scr.getImageControl()), + m_layermenu(menutheme, + scr.getScreenNumber(), + *scr.getImageControl(), + *scr.layerManager().getLayer(Fluxbox::instance()->getMenuLayer()), + this), + old_decoration(DECOR_NORMAL), + m_client(&client), + m_frame(tm, *scr.getImageControl(), scr.getScreenNumber(), 0, 0, 100, 100), + m_layeritem(m_frame.window(), layer), + m_layernum(layer.getLayerNum()) { + + init(); +} + + +FluxboxWindow::FluxboxWindow(Window w, BScreen &scr, FbWinFrameTheme &tm, FbTk::MenuTheme &menutheme, FbTk::XLayer &layer): m_hintsig(*this),

@@ -161,30 +212,100 @@ m_diesig(*this),

moving(false), resizing(false), shaded(false), maximized(false), visible(false), iconic(false), transient(false), focused(false), stuck(false), modal(false), send_focus_message(false), m_managed(false), - screen(s), + screen(scr), timer(this), display(0), lastButtonPressTime(0), - m_windowmenu(menutheme, screen_num, imgctrl), - m_layermenu(0), + m_windowmenu(menutheme, scr.getScreenNumber(), *scr.getImageControl()), + m_layermenu(menutheme, + scr.getScreenNumber(), + *scr.getImageControl(), + *scr.layerManager().getLayer(Fluxbox::instance()->getMenuLayer()), + this), old_decoration(DECOR_NORMAL), - tab(0), - m_frame(tm, imgctrl, screen_num, 0, 0, 100, 100), + m_client(new WinClient(w, *this)), + m_frame(tm, *scr.getImageControl(), scr.getScreenNumber(), 0, 0, 100, 100), m_layeritem(m_frame.window(), layer), - m_layernum(layer.getLayerNum()) -{ + m_layernum(layer.getLayerNum()) { + assert(w != 0); + init(); + +} + + + +FluxboxWindow::~FluxboxWindow() { +#ifdef DEBUG + cerr<<__FILE__<<"("<<__LINE__<<"): starting ~FluxboxWindow("<<this<<")"<<endl; +#endif // DEBUG + if (moving || resizing) { + screen.hideGeometry(); + XUngrabPointer(display, CurrentTime); + } + + Client2ButtonMap::iterator it = m_labelbuttons.begin(); + Client2ButtonMap::iterator it_end = m_labelbuttons.end(); + for (; it != it_end; ++it) { + m_frame.removeLabelButton(*(*it).second); + delete (*it).second; + } + m_labelbuttons.clear(); + + timer.stop(); + + // notify die + m_diesig.notify(); - m_layermenu = new LayerMenu<FluxboxWindow>( - menutheme, - screen_num, - imgctrl, - *s->layerManager().getLayer(Fluxbox::instance()->getMenuLayer()), - this); + if (m_client != 0) + delete m_client; // this also removes client from our list + m_client = 0; + if (m_clientlist.size() > 1) { + cerr<<__FILE__<<"("<<__FUNCTION__<<") WARNING! clientlist > 1"<<endl; + while (!m_clientlist.empty()) { + detachClient(*m_clientlist.back()); + } + } + +#ifdef DEBUG + cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<<this<<")"<<endl; +#endif // DEBUG +} + + +void FluxboxWindow::init() { + assert(m_client); + //!! TODO init of client should be better + // we don't want to duplicate code here and in attachClient + m_clientlist.push_back(m_client); +#ifdef DEBUG + cerr<<"FluxboxWindow::init(this="<<this<<")"<<endl; +#endif // DEBUG + TextButton *btn = new TextButton(m_frame.label(), + m_frame.theme().font(), + m_client->title()); + m_labelbuttons[m_client] = btn; + m_frame.addLabelButton(*btn); + btn->show(); + FbTk::EventManager &evm = *FbTk::EventManager::instance(); + // we need motion notify so we mask it + btn->window().setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask); + + FbTk::RefCount<FbTk::Command> set_client_cmd(new SetClientCmd(*m_client)); + btn->setOnClick(set_client_cmd); + evm.add(*this, btn->window()); // we take care of button events for this + + m_frame.reconfigure(); // redirect events from frame to us +#ifdef DEBUG + cerr<<"Setting up catch for events in frame"<<endl; +#endif // DEBUG m_frame.setEventHandler(*this); - +#ifdef DEBUG + cerr<<"setup for catching events....done"<<endl; +#endif // DEBUG lastFocusTime.tv_sec = lastFocusTime.tv_usec = 0; // display connection

@@ -200,9 +321,6 @@ //use tab as default

decorations.tab = true; // enable decorations decorations.enabled = true; - // set client window - client.window = w; - client.window_group = None; // set default values for decoration decorations.menu = true; //override menu option

@@ -215,15 +333,9 @@

functions.resize = functions.move = functions.iconify = functions.maximize = true; functions.close = decorations.close = false; - client.wm_hint_flags = client.normal_hint_flags = 0; - client.transient_for = 0; - client.mwm_hint = 0; - client.blackbox_hint = 0; - getBlackboxHints(); - if (! client.blackbox_hint) { + if (! m_client->blackbox_hint) getMWMHints(); - } // get size, aspect, minimum/maximum size and other hints set // by the client

@@ -232,19 +344,18 @@ getWMProtocols();

getWMHints(); getWMNormalHints(); + //!! // fetch client size and placement XWindowAttributes wattrib; - if ((! XGetWindowAttributes(display, client.window, &wattrib)) || - !wattrib.screen // no screen? + if (! m_client->getAttrib(wattrib) || + !wattrib.screen // no screen? ?? || wattrib.override_redirect) { // override redirect return; } // save old border width so we can restore it later - client.old_bw = wattrib.border_width; - client.x = wattrib.x; client.y = wattrib.y; - client.width = wattrib.width; - client.height = wattrib.height; + m_client->old_bw = wattrib.border_width; + m_client->x = wattrib.x; m_client->y = wattrib.y; Fluxbox *fluxbox = Fluxbox::instance();

@@ -252,7 +363,7 @@

timer.setTimeout(fluxbox->getAutoRaiseDelay()); timer.fireOnce(true); - if (client.initial_state == WithdrawnState) { + if (m_client->initial_state == WithdrawnState) { return; }

@@ -267,10 +378,10 @@ decorations.maximize = functions.maximize = false;

decorations.handle = decorations.border = false; } - if ((client.normal_hint_flags & PMinSize) && - (client.normal_hint_flags & PMaxSize) && - client.max_width != 0 && client.max_width <= client.min_width && - client.max_height != 0 && client.max_height <= client.min_height) { + if ((m_client->normal_hint_flags & PMinSize) && + (m_client->normal_hint_flags & PMaxSize) && + m_client->max_width != 0 && m_client->max_width <= m_client->min_width && + m_client->max_height != 0 && m_client->max_height <= m_client->min_height) { decorations.maximize = decorations.handle = functions.resize = functions.maximize = false; decorations.tab = false; //no tab for this window

@@ -283,7 +394,7 @@ m_frame.resizeForClient(wattrib.width, wattrib.height);

bool place_window = true; if (fluxbox->isStartup() || transient || - client.normal_hint_flags & (PPosition|USPosition)) { + m_client->normal_hint_flags & (PPosition|USPosition)) { setGravityOffsets(); if (! fluxbox->isStartup()) {

@@ -291,20 +402,10 @@

int real_x = m_frame.x(); int real_y = m_frame.y(); - if (decorations.tab) { - if (screen->getTabPlacement() == Tab::PTOP) { - real_y -= screen->getTabHeight(); - } else if (screen->getTabPlacement() == Tab::PLEFT) { - real_x -= (screen->isTabRotateVertical()) - ? screen->getTabHeight() - : screen->getTabWidth(); - } - } - if (real_x >= 0 && real_y + m_frame.y() >= 0 && - real_x <= (signed) screen->getWidth() && - real_y <= (signed) screen->getHeight()) + real_x <= (signed) screen.getWidth() && + real_y <= (signed) screen.getHeight()) place_window = false; } else

@@ -318,18 +419,18 @@ grabButtons();

positionWindows(); - if (workspace_number < 0 || workspace_number >= screen->getCount()) - workspace_number = screen->getCurrentWorkspaceID(); + if (workspace_number < 0 || workspace_number >= screen.getCount()) + workspace_number = screen.getCurrentWorkspaceID(); restoreAttributes(); // if we're a transient then we should be on the same layer as our parent - if (isTransient()) { + if (isTransient()) getLayerItem().setLayer(getTransientFor()->getLayerItem().getLayer()); - } else // if no parent then set default layer + else // if no parent then set default layer moveToLayer(m_layernum); - screen->getWorkspace(workspace_number)->addWindow(this, place_window); + screen.getWorkspace(workspace_number)->addWindow(*this, place_window); moveResize(m_frame.x(), m_frame.y(), m_frame.width(), m_frame.height());

@@ -357,78 +458,221 @@ setFocusFlag(false);

} - -FluxboxWindow::~FluxboxWindow() { - // notify die - m_diesig.notify(); - - if (screen == 0) //the window wasn't created +/// attach a client to this window and destroy old window +void FluxboxWindow::attachClient(WinClient &client) { + //!! TODO: check for isGroupable in client + if (client.m_win == this) return; - timer.stop(); +#ifdef DEBUG + cerr<<__FILE__<<"("<<__FUNCTION__<<")["<<this<<"]"<<endl; + cerr<<"attach client window = "<<hex<<client.window()<<dec<<endl; +#endif // DEBUG + // reparent client win to this frame + m_frame.setClientWindow(client); - Fluxbox *fluxbox = Fluxbox::instance(); - - if (moving || resizing) { - screen->hideGeometry(); - XUngrabPointer(display, CurrentTime); - } - - if (!iconic) { - Workspace *workspace = screen->getWorkspace(workspace_number); - if (workspace) - workspace->removeWindow(this); - } else - screen->removeIcon(this); - - if (tab != 0) { - delete tab; - tab = 0; - } - - if (client.mwm_hint != 0) { - XFree(client.mwm_hint); - client.mwm_hint = 0; - } + if (client.fbwindow() != 0) { + FluxboxWindow *old_win = client.fbwindow(); // store old window - if (client.blackbox_hint != 0) { - XFree(client.blackbox_hint); - client.blackbox_hint = 0; - } + Fluxbox *fb = Fluxbox::instance(); + // make sure we set new window search for each client + ClientList::iterator client_it = old_win->clientList().begin(); + ClientList::iterator client_it_end = old_win->clientList().end(); + for (; client_it != client_it_end; ++client_it) { + fb->saveWindowSearch((*client_it)->window(), this); + // reparent window to this + m_frame.setClientWindow(*(*client_it)); + (*client_it)->m_win = this; + // create a labelbutton for this client and associate it with the pointer + TextButton *btn = new TextButton(m_frame.label(), + m_frame.theme().font(), + (*client_it)->title()); + m_labelbuttons[(*client_it)] = btn; + m_frame.addLabelButton(*btn); + btn->show(); + FbTk::EventManager &evm = *FbTk::EventManager::instance(); + // we need motion notify so we mask it + btn->window().setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask); - if (client.transient_for != 0) { - if (client.transient_for == this) { - client.transient_for = 0; + FbTk::RefCount<FbTk::Command> set_client_cmd(new SetClientCmd(*(*client_it))); + btn->setOnClick(set_client_cmd); + evm.add(*this, btn->window()); // we take care of button events for this + + // update transients in client to have this as transient_for + WinClient::TransientList::iterator trans_it = (*client_it)->transientList().begin(); + WinClient::TransientList::iterator trans_it_end = (*client_it)->transientList().end(); + for (; trans_it != trans_it_end; ++trans_it) { + (*trans_it)->m_client->transient_for = this; + } } - fluxbox->setFocusedWindow(client.transient_for); + // add client and move over all attached clients + // from the old window to this list + m_clientlist.splice(m_clientlist.end(), old_win->m_clientlist); + + old_win->m_client = 0; + delete old_win; + + } else { + // create a labelbutton for this client and associate it with the pointer + TextButton *btn = new TextButton(m_frame.label(), + m_frame.theme().font(), + client.title()); + m_labelbuttons[&client] = btn; + m_frame.addLabelButton(*btn); + btn->show(); + FbTk::EventManager &evm = *FbTk::EventManager::instance(); + // we need motion notify so we mask it + btn->window().setEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask); - if (client.transient_for) { - client.transient_for->client.transients.remove(this); - client.transient_for->setInputFocus(); - client.transient_for = 0; + + FbTk::RefCount<FbTk::Command> set_client_cmd(new SetClientCmd(client)); + btn->setOnClick(set_client_cmd); + evm.add(*this, btn->window()); // we take care of button events for this + + client.m_win = this; + // update transients in client to have this as transient_for + WinClient::TransientList::iterator trans_it = client.transientList().begin(); + WinClient::TransientList::iterator trans_it_end = client.transientList().end(); + for (; trans_it != trans_it_end; ++trans_it) { + (*trans_it)->m_client->transient_for = this; } + + Fluxbox::instance()->saveWindowSearch(client.window(), this); } - - while (!client.transients.empty()) { - client.transients.back()->client.transient_for = 0; - client.transients.pop_back(); + + m_frame.reconfigure(); +#ifdef DEBUG + XSync(display, False); // so we see error/warnings in time + cerr<<"destroyed old window "<<client.window()<<endl; +#endif // DEBUG + + // keep the current window on top + m_client->raise(); + +#ifdef DEBUG + XSync(display, False); // so we see error/warnings in time + cerr<<__FILE__<<"("<<__FUNCTION__<<") clientlist size: "<<m_clientlist.size()<<endl; + cerr<<endl<<endl<<endl; +#endif // DEBUG + +} + + +/// detach client from window and create a new window for it +bool FluxboxWindow::detachClient(WinClient &client) { + if (client.m_win != this || numClients() <= 1) + return false; + +#ifdef DEBUG + cerr<<__FILE__<<"("<<__FUNCTION__<<")["<<this<<"] client to detach: "<< + hex<<client.window()<<dec<<endl; + cerr<<__FILE__<<"("<<__FUNCTION__<<"): number of clients = "<<numClients()<<endl; +#endif // DEBUG + + removeClient(client); + + client.m_win = screen.createWindow(client); + m_client->raise(); + setInputFocus(); + return true; +} + +/// removes client from client list, does not create new fluxboxwindow for it +bool FluxboxWindow::removeClient(WinClient &client) { + if (client.m_win != this || numClients() == 0) + return false; + +#ifdef DEBUG + cerr<<__FILE__<<"("<<__FUNCTION__<<")["<<this<<"]"<<endl; +#endif // DEBUG + + // set next client to be focused + // if the client we're about to remove is the last client then set prev client + if (&client == m_clientlist.back()) + prevClient(); + else + nextClient(); + + client.m_win = 0; + m_clientlist.remove(&client); + + if (m_client == &client && m_clientlist.size() == 0) + m_client = 0; + + FbTk::Button *label_btn = m_labelbuttons[&client]; + if (label_btn != 0) { + m_frame.removeLabelButton(*label_btn); + FbTk::EventManager::instance()->remove(label_btn->window()); + delete label_btn; + label_btn = 0; } - - if (client.window_group) { - fluxbox->removeGroupSearch(client.window_group); - client.window_group = 0; + + m_labelbuttons.erase(&client); + +#ifdef DEBUG + cerr<<__FILE__<<"("<<__FUNCTION__<<")["<<this<<"] numClients = "<<numClients()<<endl; +#endif // DEBUG + + return true; +} + +/// returns WinClient of window we're searching for +WinClient *FluxboxWindow::findClient(Window win) { + std::list<WinClient *>::iterator it = m_clientlist.begin(); + std::list<WinClient *>::iterator it_end = m_clientlist.end(); + for (; it != it_end; ++it) { + if ((*it)->window() == win) + return (*it); } + // failure + return 0; +} - if (m_layermenu) delete m_layermenu; +/// raise and focus next client +void FluxboxWindow::nextClient() { + if (numClients() == 1) + return; - if (client.window) - fluxbox->removeWindowSearch(client.window); + ClientList::iterator it = find(m_clientlist.begin(), m_clientlist.end(), m_client); + assert(it != m_clientlist.end()); + it++; + if (it == m_clientlist.end()) + m_client = m_clientlist.front(); + else + m_client = *it; + m_client->raise(); + setInputFocus(); +} -#ifdef DEBUG - cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<<this<<")"<<endl; -#endif // DEBUG +void FluxboxWindow::prevClient() { + if (numClients() == 1) + return; + + ClientList::iterator it = find(m_clientlist.begin(), m_clientlist.end(), m_client); + assert(it != m_clientlist.end()); + + if (it == m_clientlist.begin()) + m_client = m_clientlist.back(); + else + m_client = *(--it); + + m_client->raise(); + setInputFocus(); +} + +void FluxboxWindow::setCurrentClient(WinClient &client) { + // make sure it's in our list + if (client.m_win != this) + return; + + m_client = &client; + m_client->raise(); + Fluxbox::instance()->setFocusedWindow(this); + setInputFocus(); } bool FluxboxWindow::isGroupable() const {

@@ -438,12 +682,12 @@ return false;

} void FluxboxWindow::associateClientWindow() { - XSetWindowBorderWidth(display, client.window, 0); + m_client->setBorderWidth(0); updateTitleFromClient(); updateIconNameFromClient(); - m_frame.setClientWindow(client.window); - + m_frame.setClientWindow(*m_client); + m_frame.resizeForClient(m_client->width(), m_client->height()); // make sure the frame reconfigures m_frame.reconfigure(); }

@@ -498,19 +742,19 @@

void FluxboxWindow::positionWindows() { - m_frame.window().setBorderWidth(screen->getBorderWidth()); + m_frame.window().setBorderWidth(screen.getBorderWidth()); m_frame.clientArea().setBorderWidth(0); // client area bordered by other things - m_frame.titlebar().setBorderWidth(screen->getBorderWidth()); + m_frame.titlebar().setBorderWidth(screen.getBorderWidth()); if (decorations.titlebar) { m_frame.showTitlebar(); } else { m_frame.hideTitlebar(); } - m_frame.handle().setBorderWidth(screen->getBorderWidth()); - m_frame.gripLeft().setBorderWidth(screen->getBorderWidth()); - m_frame.gripRight().setBorderWidth(screen->getBorderWidth()); + m_frame.handle().setBorderWidth(screen.getBorderWidth()); + m_frame.gripLeft().setBorderWidth(screen.getBorderWidth()); + m_frame.gripRight().setBorderWidth(screen.getBorderWidth()); if (decorations.handle) m_frame.showHandle();

@@ -518,115 +762,58 @@ else

m_frame.hideHandle(); m_frame.reconfigure(); - - if (tab) - tab->setPosition(); + } - +/// update current client title and title in our frame void FluxboxWindow::updateTitleFromClient() { - XTextProperty text_prop; - char **list; - int num; - I18n *i18n = I18n::instance(); - - if (XGetWMName(display, client.window, &text_prop)) { - if (text_prop.value && text_prop.nitems > 0) { - if (text_prop.encoding != XA_STRING) { - - text_prop.nitems = strlen((char *) text_prop.value); - - if ((XmbTextPropertyToTextList(display, &text_prop, - &list, &num) == Success) && - (num > 0) && *list) { - client.title = static_cast<char *>(*list); - XFreeStringList(list); - } else - client.title = (char *)text_prop.value; - - } else - client.title = (char *)text_prop.value; - XFree((char *) text_prop.value); - } else { // ok, we don't have a name, set default name - client.title = i18n->getMessage( - FBNLS::WindowSet, FBNLS::WindowUnnamed, - "Unnamed"); - } - } else { - client.title = i18n->getMessage( - FBNLS::WindowSet, FBNLS::WindowUnnamed, - "Unnamed"); - } - - m_frame.setTitle(client.title); + m_client->updateTitle(); + m_labelbuttons[m_client]->setText(m_client->title()); + m_labelbuttons[m_client]->clear(); // redraw text } - +/// update icon title from client void FluxboxWindow::updateIconNameFromClient() { - - XTextProperty text_prop; - char **list; - int num; - - if (XGetWMIconName(display, client.window, &text_prop)) { - if (text_prop.value && text_prop.nitems > 0) { - if (text_prop.encoding != XA_STRING) { - text_prop.nitems = strlen((char *) text_prop.value); - - if ((XmbTextPropertyToTextList(display, &text_prop, - &list, &num) == Success) && - (num > 0) && *list) { - client.icon_title = (char *)*list; - XFreeStringList(list); - } else - client.icon_title = (char *)text_prop.value; - } else - client.icon_title = (char *)text_prop.value; - - XFree((char *) text_prop.value); - } else - client.icon_title = getTitle(); - } else - client.icon_title = getTitle(); - + m_client->updateIconTitle(); } void FluxboxWindow::getWMProtocols() { Atom *proto = 0; int num_return = 0; - Fluxbox *fluxbox = Fluxbox::instance(); + FbAtoms *fbatoms = FbAtoms::instance(); - if (XGetWMProtocols(display, client.window, &proto, &num_return)) { + if (XGetWMProtocols(display, m_client->window(), &proto, &num_return)) { for (int i = 0; i < num_return; ++i) { - if (proto[i] == fluxbox->getWMDeleteAtom()) + if (proto[i] == fbatoms->getWMDeleteAtom()) functions.close = true; - else if (proto[i] == fluxbox->getWMTakeFocusAtom()) + else if (proto[i] == fbatoms->getWMTakeFocusAtom()) send_focus_message = true; - else if (proto[i] == fluxbox->getFluxboxStructureMessagesAtom()) - screen->addNetizen(new Netizen(screen, client.window)); + else if (proto[i] == fbatoms->getFluxboxStructureMessagesAtom()) + screen.addNetizen(new Netizen(&screen, m_client->window())); } XFree(proto); } else { - cerr<<"Warning: Failed to read WM Protocols"<<endl; + cerr<<"Warning: Failed to read WM Protocols. "<<endl; } } void FluxboxWindow::getWMHints() { - XWMHints *wmhint = XGetWMHints(display, client.window); + //!! + XWMHints *wmhint = XGetWMHints(display, m_client->window()); if (! wmhint) { visible = true; iconic = false; focus_mode = F_PASSIVE; - client.window_group = None; - client.initial_state = NormalState; + m_client->window_group = None; + m_client->initial_state = NormalState; } else { - client.wm_hint_flags = wmhint->flags; + m_client->wm_hint_flags = wmhint->flags; if (wmhint->flags & InputHint) { if (wmhint->input) { if (send_focus_message)

@@ -643,17 +830,17 @@ } else

focus_mode = F_PASSIVE; if (wmhint->flags & StateHint) - client.initial_state = wmhint->initial_state; + m_client->initial_state = wmhint->initial_state; else - client.initial_state = NormalState; + m_client->initial_state = NormalState; if (wmhint->flags & WindowGroupHint) { - if (! client.window_group) { - client.window_group = wmhint->window_group; - Fluxbox::instance()->saveGroupSearch(client.window_group, this); + if (! m_client->window_group) { + m_client->window_group = wmhint->window_group; + Fluxbox::instance()->saveGroupSearch(m_client->window_group, this); } } else - client.window_group = None; + m_client->window_group = None; XFree(wmhint); }

@@ -663,57 +850,57 @@

void FluxboxWindow::getWMNormalHints() { long icccm_mask; XSizeHints sizehint; - if (! XGetWMNormalHints(display, client.window, &sizehint, &icccm_mask)) { - client.min_width = client.min_height = - client.base_width = client.base_height = - client.width_inc = client.height_inc = 1; - client.max_width = 0; // unbounded - client.max_height = 0; - client.min_aspect_x = client.min_aspect_y = - client.max_aspect_x = client.max_aspect_y = 1; - client.win_gravity = NorthWestGravity; + if (! XGetWMNormalHints(display, m_client->window(), &sizehint, &icccm_mask)) { + m_client->min_width = m_client->min_height = + m_client->base_width = m_client->base_height = + m_client->width_inc = m_client->height_inc = 1; + m_client->max_width = 0; // unbounded + m_client->max_height = 0; + m_client->min_aspect_x = m_client->min_aspect_y = + m_client->max_aspect_x = m_client->max_aspect_y = 1; + m_client->win_gravity = NorthWestGravity; } else { - client.normal_hint_flags = sizehint.flags; + m_client->normal_hint_flags = sizehint.flags; if (sizehint.flags & PMinSize) { - client.min_width = sizehint.min_width; - client.min_height = sizehint.min_height; + m_client->min_width = sizehint.min_width; + m_client->min_height = sizehint.min_height; } else - client.min_width = client.min_height = 1; + m_client->min_width = m_client->min_height = 1; if (sizehint.flags & PMaxSize) { - client.max_width = sizehint.max_width; - client.max_height = sizehint.max_height; + m_client->max_width = sizehint.max_width; + m_client->max_height = sizehint.max_height; } else { - client.max_width = 0; // unbounded - client.max_height = 0; + m_client->max_width = 0; // unbounded + m_client->max_height = 0; } if (sizehint.flags & PResizeInc) { - client.width_inc = sizehint.width_inc; - client.height_inc = sizehint.height_inc; + m_client->width_inc = sizehint.width_inc; + m_client->height_inc = sizehint.height_inc; } else - client.width_inc = client.height_inc = 1; + m_client->width_inc = m_client->height_inc = 1; if (sizehint.flags & PAspect) { - client.min_aspect_x = sizehint.min_aspect.x; - client.min_aspect_y = sizehint.min_aspect.y; - client.max_aspect_x = sizehint.max_aspect.x; - client.max_aspect_y = sizehint.max_aspect.y; + m_client->min_aspect_x = sizehint.min_aspect.x; + m_client->min_aspect_y = sizehint.min_aspect.y; + m_client->max_aspect_x = sizehint.max_aspect.x; + m_client->max_aspect_y = sizehint.max_aspect.y; } else - client.min_aspect_x = client.min_aspect_y = - client.max_aspect_x = client.max_aspect_y = 1; + m_client->min_aspect_x = m_client->min_aspect_y = + m_client->max_aspect_x = m_client->max_aspect_y = 1; if (sizehint.flags & PBaseSize) { - client.base_width = sizehint.base_width; - client.base_height = sizehint.base_height; + m_client->base_width = sizehint.base_width; + m_client->base_height = sizehint.base_height; } else - client.base_width = client.base_height = 0; + m_client->base_width = m_client->base_height = 0; if (sizehint.flags & PWinGravity) - client.win_gravity = sizehint.win_gravity; + m_client->win_gravity = sizehint.win_gravity; else - client.win_gravity = NorthWestGravity; + m_client->win_gravity = NorthWestGravity; } }

@@ -723,20 +910,20 @@ int format;

Atom atom_return; unsigned long num, len; Fluxbox *fluxbox = Fluxbox::instance(); - if (!XGetWindowProperty(display, client.window, + if (!XGetWindowProperty(display, m_client->window(), fluxbox->getMotifWMHintsAtom(), 0, PropMwmHintsElements, false, fluxbox->getMotifWMHintsAtom(), &atom_return, &format, &num, &len, - (unsigned char **) &client.mwm_hint) == Success && - client.mwm_hint) { + (unsigned char **) &m_client->mwm_hint) == Success && + m_client->mwm_hint) { return; } if (num != PropMwmHintsElements) return; - if (client.mwm_hint->flags & MwmHintsDecorations) { - if (client.mwm_hint->decorations & MwmDecorAll) { + if (m_client->mwm_hint->flags & MwmHintsDecorations) { + if (m_client->mwm_hint->decorations & MwmDecorAll) { decorations.titlebar = decorations.handle = decorations.border = decorations.iconify = decorations.maximize = decorations.close = decorations.menu = true;

@@ -745,38 +932,41 @@ decorations.titlebar = decorations.handle = decorations.border =

decorations.iconify = decorations.maximize = decorations.close = decorations.tab = false; decorations.menu = true; - if (client.mwm_hint->decorations & MwmDecorBorder) + if (m_client->mwm_hint->decorations & MwmDecorBorder) decorations.border = true; - if (client.mwm_hint->decorations & MwmDecorHandle) + if (m_client->mwm_hint->decorations & MwmDecorHandle) decorations.handle = true; - if (client.mwm_hint->decorations & MwmDecorTitle) - decorations.titlebar = decorations.tab = true; //only tab on windows with titlebar - if (client.mwm_hint->decorations & MwmDecorMenu) + if (m_client->mwm_hint->decorations & MwmDecorTitle) { + //only tab on windows with titlebar + decorations.titlebar = decorations.tab = true; + } + + if (m_client->mwm_hint->decorations & MwmDecorMenu) decorations.menu = true; - if (client.mwm_hint->decorations & MwmDecorIconify) + if (m_client->mwm_hint->decorations & MwmDecorIconify) decorations.iconify = true; - if (client.mwm_hint->decorations & MwmDecorMaximize) + if (m_client->mwm_hint->decorations & MwmDecorMaximize) decorations.maximize = true; } } - if (client.mwm_hint->flags & MwmHintsFunctions) { - if (client.mwm_hint->functions & MwmFuncAll) { + if (m_client->mwm_hint->flags & MwmHintsFunctions) { + if (m_client->mwm_hint->functions & MwmFuncAll) { functions.resize = functions.move = functions.iconify = functions.maximize = functions.close = true; } else { functions.resize = functions.move = functions.iconify = functions.maximize = functions.close = false; - if (client.mwm_hint->functions & MwmFuncResize) + if (m_client->mwm_hint->functions & MwmFuncResize) functions.resize = true; - if (client.mwm_hint->functions & MwmFuncMove) + if (m_client->mwm_hint->functions & MwmFuncMove) functions.move = true; - if (client.mwm_hint->functions & MwmFuncIconify) + if (m_client->mwm_hint->functions & MwmFuncIconify) functions.iconify = true; - if (client.mwm_hint->functions & MwmFuncMaximize) + if (m_client->mwm_hint->functions & MwmFuncMaximize) functions.maximize = true; - if (client.mwm_hint->functions & MwmFuncClose) + if (m_client->mwm_hint->functions & MwmFuncClose) functions.close = true; } }

@@ -791,38 +981,42 @@ Atom atom_return;

unsigned long num, len; FbAtoms *atoms = FbAtoms::instance(); - if (XGetWindowProperty(display, client.window, + if (XGetWindowProperty(display, m_client->window(), atoms->getFluxboxHintsAtom(), 0, PropBlackboxHintsElements, False, atoms->getFluxboxHintsAtom(), &atom_return, &format, &num, &len, - (unsigned char **) &client.blackbox_hint) == Success && - client.blackbox_hint) { + (unsigned char **) &m_client->blackbox_hint) == Success && + m_client->blackbox_hint) { if (num == PropBlackboxHintsElements) { - if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_SHADED) - shaded = (client.blackbox_hint->attrib & BaseDisplay::ATTRIB_SHADED); + if (m_client->blackbox_hint->flags & BaseDisplay::ATTRIB_SHADED) + shaded = (m_client->blackbox_hint->attrib & BaseDisplay::ATTRIB_SHADED); - if ((client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXHORIZ) && - (client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXVERT)) - maximized = ((client.blackbox_hint->attrib & - (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT)) ? 1 : 0); - else if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXVERT) - maximized = ((client.blackbox_hint->attrib & BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0); - else if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_MAXHORIZ) - maximized = ((client.blackbox_hint->attrib & BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0); + if ((m_client->blackbox_hint->flags & BaseDisplay::ATTRIB_MAXHORIZ) && + (m_client->blackbox_hint->flags & BaseDisplay::ATTRIB_MAXVERT)) + maximized = ((m_client->blackbox_hint->attrib & + (BaseDisplay::ATTRIB_MAXHORIZ | + BaseDisplay::ATTRIB_MAXVERT)) ? 1 : 0); + else if (m_client->blackbox_hint->flags & BaseDisplay::ATTRIB_MAXVERT) + maximized = ((m_client->blackbox_hint->attrib & + BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0); + else if (m_client->blackbox_hint->flags & BaseDisplay::ATTRIB_MAXHORIZ) + maximized = ((m_client->blackbox_hint->attrib & + BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0); - if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_OMNIPRESENT) - stuck = (client.blackbox_hint->attrib & BaseDisplay::ATTRIB_OMNIPRESENT); + if (m_client->blackbox_hint->flags & BaseDisplay::ATTRIB_OMNIPRESENT) + stuck = (m_client->blackbox_hint->attrib & + BaseDisplay::ATTRIB_OMNIPRESENT); - if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_WORKSPACE) - workspace_number = client.blackbox_hint->workspace; + if (m_client->blackbox_hint->flags & BaseDisplay::ATTRIB_WORKSPACE) + workspace_number = m_client->blackbox_hint->workspace; - if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_STACK) - workspace_number = client.blackbox_hint->stack; + if (m_client->blackbox_hint->flags & BaseDisplay::ATTRIB_STACK) + workspace_number = m_client->blackbox_hint->stack; - if (client.blackbox_hint->flags & BaseDisplay::ATTRIB_DECORATION) { - old_decoration = static_cast<Decoration>(client.blackbox_hint->decoration); + if (m_client->blackbox_hint->flags & BaseDisplay::ATTRIB_DECORATION) { + old_decoration = static_cast<Decoration>(m_client->blackbox_hint->decoration); setDecoration(old_decoration); } }

@@ -851,51 +1045,51 @@

downsize(); m_frame.moveResize(new_x, new_y, new_width, new_height); - if (tab) - tab->resize(); - //positionWindows(); setFocusFlag(focused); shaded = false; send_event = true; } else { m_frame.move(new_x, new_y); - //move the tab and the chain - if (tab) - tab->setPosition(); - // if (! moving) send_event = true; } if (send_event && ! moving) { - /* - Send event telling where the root position - of the client window is. (ie frame pos + client pos inside the frame = send pos) - */ - - client.width = m_frame.clientArea().width(); - client.height = m_frame.clientArea().height(); - client.x = m_frame.x(); - client.y = m_frame.y(); - - XEvent event; - event.type = ConfigureNotify; - - event.xconfigure.display = display; - event.xconfigure.event = client.window; - event.xconfigure.window = client.window; - event.xconfigure.x = m_frame.x() + m_frame.clientArea().x(); - event.xconfigure.y = m_frame.y() + m_frame.clientArea().y(); - event.xconfigure.width = client.width; - event.xconfigure.height = client.height; - event.xconfigure.border_width = client.old_bw; - event.xconfigure.above = m_frame.window().window(); - event.xconfigure.override_redirect = false; + ClientList::iterator client_it = m_clientlist.begin(); + ClientList::iterator client_it_end = m_clientlist.end(); + for (; client_it != client_it_end; ++client_it) { + WinClient &client = *(*client_it); + /* + Send event telling where the root position + of the client window is. (ie frame pos + client pos inside the frame = send pos) + */ + //!! + client.x = m_frame.x(); + client.y = m_frame.y(); + client.resize(m_frame.clientArea().width(), + m_frame.clientArea().height()); + client.updateRect(m_frame.x() + m_frame.clientArea().x(), + m_frame.y() + m_frame.clientArea().y(), + m_frame.clientArea().width(), + m_frame.clientArea().height()); + + XEvent event; + event.type = ConfigureNotify; - XSendEvent(display, client.window, False, StructureNotifyMask, &event); + event.xconfigure.display = display; + event.xconfigure.event = client.window(); + event.xconfigure.window = client.window(); + event.xconfigure.x = m_frame.x() + m_frame.clientArea().x(); + event.xconfigure.y = m_frame.y() + m_frame.clientArea().y(); + event.xconfigure.width = client.width(); + event.xconfigure.height = client.height(); + event.xconfigure.border_width = client.old_bw; + event.xconfigure.above = m_frame.window().window(); + event.xconfigure.override_redirect = false; - screen->updateNetizenConfigNotify(&event); + screen.updateNetizenConfigNotify(&event); + } // end for } }

@@ -904,25 +1098,27 @@

//TODO hint skip focus if (((signed) (m_frame.x() + m_frame.width())) < 0) { if (((signed) (m_frame.y() + m_frame.height())) < 0) { - moveResize(screen->getBorderWidth(), screen->getBorderWidth(), + moveResize(screen.getBorderWidth(), screen.getBorderWidth(), m_frame.width(), m_frame.height()); - } else if (m_frame.y() > (signed) screen->getHeight()) { - moveResize(screen->getBorderWidth(), screen->getHeight() - m_frame.height(), + } else if (m_frame.y() > (signed) screen.getHeight()) { + moveResize(screen.getBorderWidth(), screen.getHeight() - m_frame.height(), m_frame.width(), m_frame.height()); } else { - moveResize(screen->getBorderWidth(), m_frame.y() + screen->getBorderWidth(), + moveResize(screen.getBorderWidth(), m_frame.y() + screen.getBorderWidth(), m_frame.width(), m_frame.height()); } - } else if (m_frame.x() > (signed) screen->getWidth()) { + } else if (m_frame.x() > (signed) screen.getWidth()) { if (((signed) (m_frame.y() + m_frame.height())) < 0) { - moveResize(screen->getWidth() - m_frame.width(), screen->getBorderWidth(), + moveResize(screen.getWidth() - m_frame.width(), screen.getBorderWidth(), m_frame.width(), m_frame.height()); - } else if (m_frame.y() > (signed) screen->getHeight()) { - moveResize(screen->getWidth() - m_frame.width(), - screen->getHeight() - m_frame.height(), m_frame.width(), m_frame.height()); + } else if (m_frame.y() > (signed) screen.getHeight()) { + moveResize(screen.getWidth() - m_frame.width(), + screen.getHeight() - m_frame.height(), + m_frame.width(), m_frame.height()); } else { - moveResize(screen->getWidth() - m_frame.width(), - m_frame.y() + screen->getBorderWidth(), m_frame.width(), m_frame.height()); + moveResize(screen.getWidth() - m_frame.width(), + m_frame.y() + screen.getBorderWidth(), + m_frame.width(), m_frame.height()); } }

@@ -931,16 +1127,16 @@ return false;

bool ret = false; - if (client.transients.size() && modal) { - std::list<FluxboxWindow *>::iterator it = client.transients.begin(); - std::list<FluxboxWindow *>::iterator it_end = client.transients.end(); + if (m_client->transients.size() && modal) { + std::list<FluxboxWindow *>::iterator it = m_client->transients.begin(); + std::list<FluxboxWindow *>::iterator it_end = m_client->transients.end(); for (; it != it_end; ++it) { if ((*it)->modal) return (*it)->setInputFocus(); } } else { if (focus_mode == F_LOCALLYACTIVE || focus_mode == F_PASSIVE) { - XSetInputFocus(display, client.window, + XSetInputFocus(display, m_client->window(), RevertToPointerRoot, CurrentTime); } else { return false;

@@ -948,26 +1144,13 @@ }

m_frame.setFocus(true); - Fluxbox *fb = Fluxbox::instance(); - fb->setFocusedWindow(this); + Fluxbox::instance()->setFocusedWindow(this); - if (send_focus_message) { - XEvent ce; - ce.xclient.type = ClientMessage; - ce.xclient.message_type = fb->getWMProtocolsAtom(); - ce.xclient.display = display; - ce.xclient.window = client.window; - ce.xclient.format = 32; - ce.xclient.data.l[0] = fb->getWMTakeFocusAtom(); - ce.xclient.data.l[1] = fb->getLastTime(); - ce.xclient.data.l[2] = 0l; - ce.xclient.data.l[3] = 0l; - ce.xclient.data.l[4] = 0l; - XSendEvent(display, client.window, false, NoEventMask, &ce); - } + if (send_focus_message) + m_client->sendFocus(); - if ((screen->isSloppyFocus() || screen->isSemiSloppyFocus()) - && screen->doAutoRaise()) + if ((screen.isSloppyFocus() || screen.isSemiSloppyFocus()) + && screen.doAutoRaise()) timer.start(); ret = true;

@@ -976,28 +1159,10 @@

return ret; } -/** - Enables or disables the tab on the window -*/ -void FluxboxWindow::setTab(bool flag) { - /* if (flag) { - if (!tab && isGroupable()) - tab = new Tab(this, 0, 0); - - if (tab) { - tab->focus(); // draws the tab with correct texture - tab->setPosition(); // set tab windows position - } - - } else if (tab) { - delete tab; - tab = 0; - } - decorations.tab = flag; - */ -} - void FluxboxWindow::hide() { +#ifdef DEBUG + cerr<<__FILE__<<"("<<__FUNCTION__<<")["<<this<<"]"<<endl; +#endif // DEBUG m_windowmenu.hide(); m_frame.hide(); }

@@ -1011,51 +1176,43 @@ Unmaps the window and removes it from workspace list

*/ void FluxboxWindow::iconify() { - if (iconic) // no need to iconify if we're already + if (isIconic()) // no need to iconify if we're already return; m_windowmenu.hide(); - - XSelectInput(display, client.window, NoEventMask); - XUnmapWindow(display, client.window); - XSelectInput(display, client.window, - PropertyChangeMask | StructureNotifyMask | FocusChangeMask); - visible = false; iconic = true; - + setState(IconicState); m_frame.hide(); - screen->getWorkspace(workspace_number)->removeWindow(this); + ClientList::iterator client_it = m_clientlist.begin(); + const ClientList::iterator client_it_end = m_clientlist.end(); + for (; client_it != client_it_end; ++client_it) { + WinClient &client = *(*client_it); + client.setEventMask(NoEventMask); + client.hide(); + client.setEventMask(PropertyChangeMask | StructureNotifyMask | FocusChangeMask); + if (client.transientFor()) { + if (! client.transientFor()->isIconic()) { + client.transientFor()->iconify(); + } + } - if (client.transient_for) { - if (! client.transient_for->iconic) - client.transient_for->iconify(); - } - - screen->addIcon(this); - - if (tab) //if this window got a tab then iconify it too - tab->iconify(); - - if (client.transients.size()) { - std::list<FluxboxWindow *>::iterator it = client.transients.begin(); - std::list<FluxboxWindow *>::iterator it_end = client.transients.end(); - for (; it != it_end; ++it) { - if (! (*it)->iconic) - (*it)->iconify(); + if (client.transientList().size()) { + for_each(client.transientList().begin(), + client.transientList().end(), + mem_fun(&FluxboxWindow::iconify)); } } } - void FluxboxWindow::deiconify(bool reassoc, bool do_raise) { if (iconic || reassoc) { - screen->reassociateWindow(this, screen->getCurrentWorkspace()->workspaceID(), false); - } else if (moving || workspace_number != screen->getCurrentWorkspace()->workspaceID()) + screen.reassociateWindow(this, screen.getCurrentWorkspace()->workspaceID(), false); + } else if (moving || workspace_number != screen.getCurrentWorkspace()->workspaceID()) return; bool was_iconic = iconic;

@@ -1064,32 +1221,39 @@ iconic = false;

visible = true; setState(NormalState); - XSelectInput(display, client.window, NoEventMask); - XMapWindow(display, client.window); - XSelectInput(display, client.window, - PropertyChangeMask | StructureNotifyMask | FocusChangeMask); - + ClientList::iterator client_it = clientList().begin(); + ClientList::iterator client_it_end = clientList().end(); + for (; client_it != client_it_end; ++client_it) { + (*client_it)->setEventMask(NoEventMask); + (*client_it)->show(); + (*client_it)->setEventMask(PropertyChangeMask | StructureNotifyMask | FocusChangeMask); + } + m_frame.show(); - if (was_iconic && screen->doFocusNew()) + if (was_iconic && screen.doFocusNew()) setInputFocus(); if (focused != m_frame.focused()) m_frame.setFocus(focused); - if (reassoc && client.transients.size()) { + if (reassoc && m_client->transients.size()) { // deiconify all transients - std::list<FluxboxWindow *>::iterator it = client.transients.begin(); - std::list<FluxboxWindow *>::iterator it_end = client.transients.end(); - for (; it != it_end; ++it) { - (*it)->deiconify(true, false); + client_it = clientList().begin(); + for (; client_it != client_it_end; ++client_it) { + + std::list<FluxboxWindow *>::iterator trans_it = + (*client_it)->transientList().begin(); + std::list<FluxboxWindow *>::iterator trans_it_end = + (*client_it)->transientList().end(); + for (; trans_it != trans_it_end; ++trans_it) { + (*trans_it)->deiconify(true, false); + } } + } - - if (tab) - tab->deiconify(); - + if (do_raise) raise(); }

@@ -1098,20 +1262,10 @@ /**

Send close request to client window */ void FluxboxWindow::close() { - // fill in XClientMessage structure for delete message - XEvent ce; - ce.xclient.type = ClientMessage; - ce.xclient.message_type = FbAtoms::instance()->getWMProtocolsAtom(); - ce.xclient.display = FbTk::App::instance()->display(); - ce.xclient.window = client.window; - ce.xclient.format = 32; - ce.xclient.data.l[0] = FbAtoms::instance()->getWMDeleteAtom(); - ce.xclient.data.l[1] = CurrentTime; - ce.xclient.data.l[2] = 0l; - ce.xclient.data.l[3] = 0l; - ce.xclient.data.l[4] = 0l; - // send event delete message to client window - XSendEvent(display, client.window, false, NoEventMask, &ce); +#ifdef DEBUG + cerr<<__FILE__<<"("<<__FUNCTION__<<")"<<endl; +#endif // DEBUG + m_client->sendClose(); } /**

@@ -1127,9 +1281,6 @@

m_frame.hide(); m_windowmenu.hide(); - - if (tab) - tab->withdraw(); } /**

@@ -1145,12 +1296,12 @@ m_old_width = frame().width();

m_old_height = frame().height(); m_old_pos_x = frame().x(); m_old_pos_y = frame().y(); - unsigned int left_x = screen->getMaxLeft(); - unsigned int max_width = screen->getMaxRight(); - unsigned int max_top = screen->getMaxTop(); + unsigned int left_x = screen.getMaxLeft(); + unsigned int max_width = screen.getMaxRight(); + unsigned int max_top = screen.getMaxTop(); moveResize(left_x, max_top, max_width - left_x, - screen->getMaxBottom() - max_top - m_frame.window().borderWidth()); + screen.getMaxBottom() - max_top - m_frame.window().borderWidth()); } else { // demaximize, restore to old values moveResize(m_old_pos_x, m_old_pos_y, m_old_width, m_old_height);

@@ -1160,8 +1311,8 @@ maximized = !maximized;

} void FluxboxWindow::maximizeHorizontal() { - unsigned int left_x = screen->getMaxLeft(); - unsigned int max_width = screen->getMaxRight(); + unsigned int left_x = screen.getMaxLeft(); + unsigned int max_width = screen.getMaxRight(); moveResize(left_x, m_frame.y(), max_width - left_x, m_frame.height() - m_frame.window().borderWidth());

@@ -1171,10 +1322,10 @@ /**

Maximize window horizontal */ void FluxboxWindow::maximizeVertical() { - unsigned int max_top = screen->getMaxTop(); + unsigned int max_top = screen.getMaxTop(); moveResize(m_frame.x(), max_top, m_frame.width() - m_frame.window().borderWidth(), - screen->getMaxBottom() - max_top); + screen.getMaxBottom() - max_top); }

@@ -1207,13 +1358,11 @@ m_layersig.notify();

} void FluxboxWindow::shade() { + // we can only shade if we have a titlebar if (!decorations.titlebar) return; - // toggle shade on tab and frame m_frame.shade(); - if (tab) - tab->shade(); if (shaded) { shaded = false;

@@ -1225,7 +1374,7 @@ } else {

shaded = true; blackbox_attrib.flags |= BaseDisplay::ATTRIB_SHADED; blackbox_attrib.attrib |= BaseDisplay::ATTRIB_SHADED; - + // shading is the same as iconic setState(IconicState); }

@@ -1234,9 +1383,7 @@

void FluxboxWindow::stick() { - if (tab) //if it got a tab then do tab's stick on all of the objects in the list - tab->stick(); //this window will stick too. - else if (stuck) { + if (stuck) { blackbox_attrib.flags ^= BaseDisplay::ATTRIB_OMNIPRESENT; blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_OMNIPRESENT;

@@ -1244,16 +1391,12 @@ stuck = false;

} else { stuck = true; - if (screen->getCurrentWorkspaceID() != workspace_number) { - screen->reassociateWindow(this,screen->getCurrentWorkspaceID(), true); - } - + blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT; blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT; } - //TODO: make sure any button that listens to this state gets updated - + setState(current_state); }

@@ -1306,7 +1449,7 @@ assert(win != win->getTransientFor());

} if (!win->isIconic()) { - screen->updateNetizenWindowRaise(win->getClientWindow()); + screen.updateNetizenWindowRaise(win->getClientWindow()); win->getLayerItem().raiseLayer(); win->setLayerNum(win->getLayerItem().getLayerNum()); }

@@ -1315,7 +1458,7 @@ std::list<FluxboxWindow *>::const_iterator it = win->getTransients().begin();

std::list<FluxboxWindow *>::const_iterator it_end = win->getTransients().end(); for (; it != it_end; ++it) { if (!(*it)->isIconic()) { - screen->updateNetizenWindowRaise((*it)->getClientWindow()); + screen.updateNetizenWindowRaise((*it)->getClientWindow()); (*it)->getLayerItem().raiseLayer(); (*it)->setLayerNum((*it)->getLayerItem().getLayerNum()); }

@@ -1333,7 +1476,7 @@

win = bottom; if (!win->isIconic()) { - screen->updateNetizenWindowLower(win->getClientWindow()); + screen.updateNetizenWindowLower(win->getClientWindow()); win->getLayerItem().lowerLayer(); win->setLayerNum(win->getLayerItem().getLayerNum()); }

@@ -1341,7 +1484,7 @@ std::list<FluxboxWindow *>::const_iterator it = win->getTransients().begin();

std::list<FluxboxWindow *>::const_iterator it_end = win->getTransients().end(); for (; it != it_end; ++it) { if (!(*it)->isIconic()) { - screen->updateNetizenWindowLower((*it)->getClientWindow()); + screen.updateNetizenWindowLower((*it)->getClientWindow()); (*it)->getLayerItem().lowerLayer(); (*it)->setLayerNum((*it)->getLayerItem().getLayerNum()); }

@@ -1365,7 +1508,7 @@ assert(win != win->getTransientFor());

} if (!win->isIconic()) { - screen->updateNetizenWindowRaise(win->getClientWindow()); + screen.updateNetizenWindowRaise(win->getClientWindow()); win->getLayerItem().moveToLayer(layernum); win->setLayerNum(win->getLayerItem().getLayerNum()); }

@@ -1373,10 +1516,9 @@ std::list<FluxboxWindow *>::const_iterator it = win->getTransients().begin();

std::list<FluxboxWindow *>::const_iterator it_end = win->getTransients().end(); for (; it != it_end; ++it) { if (!(*it)->isIconic()) { - screen->updateNetizenWindowRaise((*it)->getClientWindow()); + screen.updateNetizenWindowRaise((*it)->getClientWindow()); (*it)->getLayerItem().moveToLayer(layernum); (*it)->setLayerNum((*it)->getLayerItem().getLayerNum()); - } } }

@@ -1386,17 +1528,14 @@

void FluxboxWindow::setFocusFlag(bool focus) { focused = focus; - // Record focus timestamp for window cycling enhancements, such as skipping lower tabs + // Record focus timestamp for window cycling enhancements if (focused) gettimeofday(&lastFocusTime, 0); m_frame.setFocus(focus); - - if (tab) - tab->focus(); - if ((screen->isSloppyFocus() || screen->isSemiSloppyFocus()) && - screen->doAutoRaise()) + if ((screen.isSloppyFocus() || screen.isSemiSloppyFocus()) && + screen.doAutoRaise()) timer.stop(); }

@@ -1407,10 +1546,10 @@ fluxbox->grab();

if (! validateClient()) return; int i = 0, ncmap = 0; - Colormap *cmaps = XListInstalledColormaps(display, client.window, &ncmap); + Colormap *cmaps = XListInstalledColormaps(display, m_client->window(), &ncmap); XWindowAttributes wattrib; - if (cmaps) { - if (XGetWindowAttributes(display, client.window, &wattrib)) { + if (cmaps) { //!! + if (m_client->getAttrib(wattrib)) { //XGetWindowAttributes(display, m_client->window, &wattrib)) { if (install) { // install the window's colormap for (i = 0; i < ncmap; i++) {

@@ -1424,9 +1563,10 @@ // otherwise, install the window's colormap

if (install) XInstallColormap(display, wattrib.colormap); } else { - for (i = 0; i < ncmap; i++) // uninstall the window's colormap - if (*(cmaps + i) == wattrib.colormap) - XUninstallColormap(display, wattrib.colormap); // we found the colormap to uninstall + for (i = 0; i < ncmap; i++) { // uninstall the window's colormap + if (*(cmaps + i) == wattrib.colormap) + XUninstallColormap(display, wattrib.colormap); + } } }

@@ -1436,23 +1576,29 @@

fluxbox->ungrab(); } +/** + Saves blackbox hints for every client in our list + */ void FluxboxWindow::saveBlackboxHints() { - Fluxbox *fluxbox = Fluxbox::instance(); - XChangeProperty(display, client.window, fluxbox->getFluxboxAttributesAtom(), - fluxbox->getFluxboxAttributesAtom(), 32, PropModeReplace, - (unsigned char *) &blackbox_attrib, PropBlackboxAttributesElements); + for_each(m_clientlist.begin(), m_clientlist.end(), + FbTk::ChangeProperty(display, FbAtoms::instance()->getFluxboxAttributesAtom(), + PropModeReplace, + (unsigned char *)&blackbox_attrib, + PropBlackboxAttributesElements)); } - +/** + Sets state on each client in our list + */ void FluxboxWindow::setState(unsigned long new_state) { current_state = new_state; - Fluxbox *fluxbox = Fluxbox::instance(); unsigned long state[2]; state[0] = (unsigned long) current_state; state[1] = (unsigned long) None; - XChangeProperty(display, client.window, fluxbox->getWMStateAtom(), - fluxbox->getWMStateAtom(), 32, PropModeReplace, - (unsigned char *) state, 2); + for_each(m_clientlist.begin(), m_clientlist.end(), + FbTk::ChangeProperty(display, FbAtoms::instance()->getWMStateAtom(), + PropModeReplace, + (unsigned char *)state, 2)); saveBlackboxHints(); //notify state changed

@@ -1467,7 +1613,7 @@ bool ret = false;

int foo; unsigned long *state, ulfoo, nitems; Fluxbox *fluxbox = Fluxbox::instance(); - if ((XGetWindowProperty(display, client.window, fluxbox->getWMStateAtom(), + if ((XGetWindowProperty(display, m_client->window(), fluxbox->getWMStateAtom(), 0l, 2l, false, fluxbox->getWMStateAtom(), &atom_return, &foo, &nitems, &ulfoo, (unsigned char **) &state) != Success) ||

@@ -1485,12 +1631,12 @@

return ret; } -//TODO: this functions looks odd +//!! TODO: this functions looks odd void FluxboxWindow::setGravityOffsets() { int newx = m_frame.x(); int newy = m_frame.y(); // translate x coordinate - switch (client.win_gravity) { + switch (m_client->win_gravity) { // handle Westward gravity case NorthWestGravity: case WestGravity:

@@ -1526,7 +1672,7 @@ newx = m_frame.x();

} // translate y coordinate - switch (client.win_gravity) { + switch (m_client->win_gravity) { // handle Northbound gravity case NorthWestGravity: case NorthGravity:

@@ -1554,8 +1700,8 @@ if (m_frame.x() != newx || m_frame.y() != newy)

m_frame.move(newx, newy); } -/* - * restoreAttributes sets the attributes to what they should be +/** + * Sets the attributes to what they should be * but doesn't change the actual state * (so the caller can set defaults etc as well) */

@@ -1569,7 +1715,7 @@ unsigned long ulfoo, nitems;

Fluxbox *fluxbox = Fluxbox::instance(); BaseDisplay::BlackboxAttributes *net; - if (XGetWindowProperty(display, client.window, + if (XGetWindowProperty(display, m_client->window(), fluxbox->getFluxboxAttributesAtom(), 0l, PropBlackboxAttributesElements, false, fluxbox->getFluxboxAttributesAtom(), &atom_return, &foo,

@@ -1598,8 +1744,8 @@

current_state = save_state; } - if (( blackbox_attrib.workspace != screen->getCurrentWorkspaceID()) && - ( blackbox_attrib.workspace < screen->getCount())) { + if (( blackbox_attrib.workspace != screen.getCurrentWorkspaceID()) && + ( blackbox_attrib.workspace < screen.getCount())) { workspace_number = blackbox_attrib.workspace; if (current_state == NormalState) current_state = WithdrawnState;

@@ -1647,8 +1793,6 @@ void FluxboxWindow::showMenu(int mx, int my) {

m_windowmenu.move(mx, my); m_windowmenu.show(); m_windowmenu.raise(); - // m_windowmenu.getSendToMenu().raise(); - // m_windowmenu.getSendGroupToMenu().raise(); } /**

@@ -1672,38 +1816,38 @@ }

void FluxboxWindow::restoreGravity() { // restore x coordinate - switch (client.win_gravity) { + switch (m_client->win_gravity) { // handle Westward gravity case NorthWestGravity: case WestGravity: case SouthWestGravity: default: - client.x = m_frame.x(); + m_client->x = m_frame.x(); break; // handle Eastward gravity case NorthEastGravity: case EastGravity: case SouthEastGravity: - client.x = (m_frame.x() + m_frame.width()) - client.width; + m_client->x = (m_frame.x() + m_frame.width()) - m_client->width(); break; } // restore y coordinate - switch (client.win_gravity) { + switch (m_client->win_gravity) { // handle Northbound gravity case NorthWestGravity: case NorthGravity: case NorthEastGravity: default: - client.y = m_frame.y(); + m_client->y = m_frame.y(); break; // handle Southbound gravity case SouthWestGravity: case SouthGravity: case SouthEastGravity: - client.y = (m_frame.y() + m_frame.height()) - client.height; + m_client->y = (m_frame.y() + m_frame.height()) - m_client->height(); break; } }

@@ -1712,15 +1856,8 @@ /**

Determine if this is the lowest tab of them all */ bool FluxboxWindow::isLowerTab() const { - Tab* chkTab = (tab ? tab->first() : 0); - while (chkTab) { - const FluxboxWindow* chkWin = chkTab->getWindow(); - if (chkWin && chkWin != this && - timercmp(&chkWin->lastFocusTime, &lastFocusTime, >)) - return true; - chkTab = chkTab->next(); - } - return false; + cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO!"<<endl; + return true; } /**

@@ -1742,16 +1879,16 @@ }

void FluxboxWindow::mapRequestEvent(XMapRequestEvent &re) { // we're only conserned about client window event - if (re.window != client.window) + if (re.window != m_client->window()) return; Fluxbox *fluxbox = Fluxbox::instance(); bool get_state_ret = getState(); if (! (get_state_ret && fluxbox->isStartup())) { - if ((client.wm_hint_flags & StateHint) && + if ((m_client->wm_hint_flags & StateHint) && (! (current_state == NormalState || current_state == IconicState))) { - current_state = client.initial_state; + current_state = m_client->initial_state; } else current_state = NormalState; } else if (iconic)

@@ -1787,12 +1924,14 @@ XFree(ch.res_class);

} else m_class_name = ""; - Workspace *wsp = screen->getWorkspace(workspace_number); - // we must be resizable AND maximizable to be autogrouped - // TODO: there should be an isGroupable() function - if (wsp != 0 && isResizable() && isMaximizable()) { - wsp->checkGrouping(*this); - } + /* + Workspace *wsp = screen.getWorkspace(workspace_number); + // we must be resizable AND maximizable to be autogrouped + //!! TODO: there should be an isGroupable() function + if (wsp != 0 && isResizable() && isMaximizable()) { + wsp->checkGrouping(*this); + } + */ } deiconify(false);

@@ -1809,7 +1948,7 @@ }

void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) { - if (ne.window == client.window && !ne.override_redirect && visible) { + if (ne.window == m_client->window() && !ne.override_redirect && visible) { Fluxbox *fluxbox = Fluxbox::instance(); fluxbox->grab(); if (! validateClient())

@@ -1817,7 +1956,7 @@ return;

setState(NormalState); - if (transient || screen->doFocusNew()) + if (transient || screen.doFocusNew()) setInputFocus(); else setFocusFlag(false);

@@ -1830,13 +1969,7 @@ iconic = false;

// Auto-group from tab? if (!transient) { - // Grab and clear the auto-group window - FluxboxWindow* autoGroupWindow = screen->useAutoGroupWindow(); - if (autoGroupWindow) { - Tab *groupTab = autoGroupWindow->getTab(); - if (groupTab) - groupTab->addWindowToGroup(this); - } + cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO check grouping here"<<endl; } fluxbox->ungrab();

@@ -1845,32 +1978,33 @@ }

/** Unmaps frame window and client window if - event.window == client.window + event.window == m_client->window Returns true if *this should die else false */ void FluxboxWindow::unmapNotifyEvent(XUnmapEvent &ue) { - if (ue.window != client.window) + WinClient *client = findClient(ue.window); + if (client == 0) return; #ifdef DEBUG - cerr<<__FILE__<<": unmapNotifyEvent() 0x"<<hex<<client.window<<dec<<endl; + cerr<<__FILE__<<"("<<__FUNCTION__<<"): 0x"<<hex<<client->window()<<dec<<endl; #endif // DEBUG - - restore(false); - + + restore(client, false); } /** - Checks if event is for client.window. + Checks if event is for m_client->window. */ void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) { - if (de.window == client.window) { + if (de.window == m_client->window()) { #ifdef DEBUG cerr<<__FILE__<<"("<<__LINE__<<"): DestroyNotifyEvent this="<<this<<endl; #endif // DEBUG - m_frame.hide(); + if (numClients() == 1) + m_frame.hide(); } }

@@ -1884,11 +2018,15 @@ case XA_WM_CLIENT_MACHINE:

case XA_WM_COMMAND: break; - case XA_WM_TRANSIENT_FOR: + case XA_WM_TRANSIENT_FOR: { + bool was_transient = isTransient(); updateTransientInfo(); reconfigure(); - - break; + // update our layer to be the same layer as our transient for + if (isTransient() && isTransient() != was_transient) + getLayerItem().setLayer(getTransientFor()->getLayerItem().getLayer()); + + } break; case XA_WM_HINTS: getWMHints();

@@ -1901,12 +2039,9 @@ break;

case XA_WM_NAME: updateTitleFromClient(); - - if (hasTab()) // update tab - getTab()->draw(false); if (! iconic) - screen->getWorkspace(workspace_number)->update(); + screen.getWorkspace(workspace_number)->update(); else updateIcon();

@@ -1916,11 +2051,11 @@

case XA_WM_NORMAL_HINTS: { getWMNormalHints(); - if ((client.normal_hint_flags & PMinSize) && - (client.normal_hint_flags & PMaxSize)) { + if ((m_client->normal_hint_flags & PMinSize) && + (m_client->normal_hint_flags & PMaxSize)) { - if (client.max_width != 0 && client.max_width <= client.min_width && - client.max_height != 0 && client.max_height <= client.min_height) { + if (m_client->max_width != 0 && m_client->max_width <= m_client->min_width && + m_client->max_height != 0 && m_client->max_height <= m_client->min_height) { decorations.maximize = false; decorations.handle = false; functions.resize=false;

@@ -1956,7 +2091,7 @@ if (atom == FbAtoms::instance()->getWMProtocolsAtom()) {

getWMProtocols(); //!!TODO check this area // reset window actions - screen->setupWindowActions(*this); + screen.setupWindowActions(*this); } break;

@@ -1971,7 +2106,7 @@ }

void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent &cr) { - if (cr.window != client.window) + if (cr.window != m_client->window()) return; int cx = m_frame.x(), cy = m_frame.y();

@@ -1980,7 +2115,7 @@ unsigned int titlebar_y = (decorations.titlebar ?

m_frame.titlebar().height() + frame().titlebar().borderWidth() : 0); if (cr.value_mask & CWBorderWidth) - client.old_bw = cr.border_width; + m_client->old_bw = cr.border_width; if (cr.value_mask & CWX) cx = cr.x;

@@ -2027,7 +2162,7 @@ // check frame events first

m_frame.buttonPressEvent(be); if (be.button == 1 || (be.button == 3 && be.state == Mod1Mask)) { - if ((! focused) && (! screen->isSloppyFocus())) { //check focus + if ((! focused) && (! screen.isSloppyFocus())) { //check focus setInputFocus(); }

@@ -2035,20 +2170,19 @@ if (m_frame.clientArea() == be.window) {

raise(); XAllowEvents(display, ReplayPointer, be.time); } else { - button_grab_x = be.x_root - m_frame.x() - screen->getBorderWidth(); - button_grab_y = be.y_root - m_frame.y() - screen->getBorderWidth(); + button_grab_x = be.x_root - m_frame.x() - screen.getBorderWidth(); + button_grab_y = be.y_root - m_frame.y() - screen.getBorderWidth(); } if (m_windowmenu.isVisible()) - m_windowmenu.hide(); + m_windowmenu.hide(); } - } void FluxboxWindow::shapeEvent(XShapeEvent *) { } void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) { - m_frame.buttonReleaseEvent(re); // let the frame handle the event first + if (isMoving()) stopMoving();

@@ -2057,54 +2191,72 @@ stopResizing();

else if (re.window == m_frame.window()) { if (re.button == 2 && re.state == Mod1Mask) XUngrabPointer(display, CurrentTime); + m_frame.buttonReleaseEvent(re); + } else { + m_frame.buttonReleaseEvent(re); } - } void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { - if (isMoving() && me.window == screen->getRootWindow()) { + if (isMoving() && me.window == screen.getRootWindow()) { me.window = m_frame.window().window(); } + bool inside_titlebar = (m_frame.titlebar() == me.window || m_frame.label() == me.window || + m_frame.handle() == me.window || m_frame.window() == me.window); + + if (!inside_titlebar) { + // determine if we're in titlebar + Client2ButtonMap::iterator it = m_labelbuttons.begin(); + Client2ButtonMap::iterator it_end = m_labelbuttons.end(); + for (; it != it_end; ++it) { + if ((*it).second->window() == me.window) { + inside_titlebar = true; + break; + } + } + } + if ((me.state & Button1Mask) && functions.move && - (m_frame.titlebar() == me.window || m_frame.label() == me.window || - m_frame.handle() == me.window || m_frame.window() == me.window) && !isResizing()) { - + inside_titlebar && + !isResizing()) { + if (! isMoving()) { startMoving(me.window); } else { int dx = me.x_root - button_grab_x, dy = me.y_root - button_grab_y; - dx -= screen->getBorderWidth(); - dy -= screen->getBorderWidth(); + dx -= screen.getBorderWidth(); + dy -= screen.getBorderWidth(); // Warp to next or previous workspace?, must have moved sideways some int moved_x = me.x_root - last_resize_x; // save last event point last_resize_x = me.x_root; last_resize_y = me.y_root; - if (moved_x && screen->isWorkspaceWarping()) { - unsigned int cur_id = screen->getCurrentWorkspaceID(); + + if (moved_x && screen.isWorkspaceWarping()) { + unsigned int cur_id = screen.getCurrentWorkspaceID(); unsigned int new_id = cur_id; - const int warpPad = screen->getEdgeSnapThreshold(); + const int warpPad = screen.getEdgeSnapThreshold(); // 1) if we're inside the border threshold // 2) if we moved in the right direction - if (me.x_root >= int(screen->getWidth()) - warpPad - 1 && + if (me.x_root >= int(screen.getWidth()) - warpPad - 1 && moved_x > 0) { //warp right - new_id = (cur_id + 1) % screen->getCount(); + new_id = (cur_id + 1) % screen.getCount(); dx = - me.x_root; // move mouse back to x=0 } else if (me.x_root <= warpPad && - moved_x < 0) { + moved_x < 0) { //warp left - new_id = (cur_id + screen->getCount() - 1) % screen->getCount(); - dx = screen->getWidth() - me.x_root-1; // move mouse to screen width - 1 + new_id = (cur_id + screen.getCount() - 1) % screen.getCount(); + dx = screen.getWidth() - me.x_root-1; // move mouse to screen width - 1 } if (new_id != cur_id) { XWarpPointer(display, None, None, 0, 0, 0, 0, dx, 0); - - screen->changeWorkspaceID(new_id); + + screen.changeWorkspaceID(new_id); last_resize_x = me.x_root + dx;

@@ -2115,12 +2267,13 @@ }

} - if (! screen->doOpaqueMove()) { - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + if (! screen.doOpaqueMove()) { + XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), last_move_x, last_move_y, m_frame.width() + 2*frame().window().borderWidth(), m_frame.height() + 2*frame().window().borderWidth()); - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + + XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), dx, dy, m_frame.width() + 2*frame().window().borderWidth(), m_frame.height() + 2*frame().window().borderWidth());

@@ -2130,21 +2283,21 @@ } else {

moveResize(dx, dy, m_frame.width(), m_frame.height()); } - if (screen->doShowWindowPos()) - screen->showPosition(dx, dy); + if (screen.doShowWindowPos()) + screen.showPosition(dx, dy); } // end if moving } else if (functions.resize && (((me.state & Button1Mask) && (me.window == m_frame.gripRight() || me.window == m_frame.gripLeft())) || me.window == m_frame.window())) { - + bool left = (me.window == m_frame.gripLeft()); if (! resizing) { startResizing(me.window, me.x, me.y, left); } else if (resizing) { // draw over old rect - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), last_resize_x, last_resize_y, last_resize_w - 1 + 2 * m_frame.window().borderWidth(), last_resize_h - 1 + 2 * m_frame.window().borderWidth());

@@ -2172,13 +2325,13 @@ right_fixsize(&gx, &gy);

} // draw resize rectangle - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), last_resize_x, last_resize_y, last_resize_w - 1 + 2 * m_frame.window().borderWidth(), last_resize_h - 1 + 2 * m_frame.window().borderWidth()); - if (screen->doShowWindowPos()) - screen->showGeometry(gx, gy); + if (screen.doShowWindowPos()) + screen.showGeometry(gx, gy); } }

@@ -2193,8 +2346,8 @@ return;

} if (ev.window == frame().window() || - ev.window == client.window) { - if ((screen->isSloppyFocus() || screen->isSemiSloppyFocus()) + ev.window == m_client->window()) { + if ((screen.isSloppyFocus() || screen.isSemiSloppyFocus()) && !isFocused()) {

@@ -2287,8 +2440,8 @@ bool FluxboxWindow::validateClient() {

XSync(display, false); XEvent e; - if (XCheckTypedWindowEvent(display, client.window, DestroyNotify, &e) || - XCheckTypedWindowEvent(display, client.window, UnmapNotify, &e)) { + if (XCheckTypedWindowEvent(display, m_client->window(), DestroyNotify, &e) || + XCheckTypedWindowEvent(display, m_client->window(), UnmapNotify, &e)) { XPutBackEvent(display, &e); Fluxbox::instance()->ungrab();

@@ -2303,7 +2456,7 @@ moving = true;

Fluxbox *fluxbox = Fluxbox::instance(); // grabbing (and masking) on the root window allows us to // freely map and unmap the window we're moving. - XGrabPointer(display, screen->getRootWindow(), False, Button1MotionMask | + XGrabPointer(display, screen.getRootWindow(), False, Button1MotionMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, fluxbox->getMoveCursor(), CurrentTime);

@@ -2311,16 +2464,17 @@ if (m_windowmenu.isVisible())

m_windowmenu.hide(); move_ws = workspace_number; - fluxbox->maskWindowEvents(screen->getRootWindow(), this); + fluxbox->maskWindowEvents(screen.getRootWindow(), this); + last_move_x = frame().x(); last_move_y = frame().y(); - if (! screen->doOpaqueMove()) { + if (! screen.doOpaqueMove()) { fluxbox->grab(); - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), frame().x(), frame().y(), frame().width() + 2*frame().window().borderWidth(), frame().height() + 2*frame().window().borderWidth()); - screen->showPosition(frame().x(), frame().y()); + screen.showPosition(frame().x(), frame().y()); } }

@@ -2331,32 +2485,32 @@

fluxbox->maskWindowEvents(0, 0); - if (! screen->doOpaqueMove()) { - XDrawRectangle(FbTk::App::instance()->display(), screen->getRootWindow(), screen->getOpGC(), + if (! screen.doOpaqueMove()) { + XDrawRectangle(FbTk::App::instance()->display(), screen.getRootWindow(), screen.getOpGC(), last_move_x, last_move_y, frame().width() + 2*frame().window().borderWidth(), frame().height() + 2*frame().window().borderWidth()); moveResize(last_move_x, last_move_y, m_frame.width(), m_frame.height()); - if (workspace_number != screen->getCurrentWorkspaceID()) { - screen->reassociateGroup(this, screen->getCurrentWorkspaceID(), true); + if (workspace_number != getScreen().getCurrentWorkspaceID()) { + screen.reassociateGroup(this, getScreen().getCurrentWorkspaceID(), true); m_frame.show(); } fluxbox->ungrab(); } else moveResize(m_frame.x(), m_frame.y(), m_frame.width(), m_frame.height()); - screen->hideGeometry(); + screen.hideGeometry(); XUngrabPointer(display, CurrentTime); XSync(display, False); //make sure the redraw is made before we continue } void FluxboxWindow::pauseMoving() { - if (screen->doOpaqueMove()) { + if (getScreen().doOpaqueMove()) { return; } - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + XDrawRectangle(display, getScreen().getRootWindow(), getScreen().getOpGC(), last_move_x, last_move_y, m_frame.width() + 2*frame().window().borderWidth(), m_frame.height() + 2*frame().window().borderWidth());

@@ -2365,15 +2519,15 @@ }

void FluxboxWindow::resumeMoving() { - if (screen->doOpaqueMove()) { + if (screen.doOpaqueMove()) { return; } - if (workspace_number == screen->getCurrentWorkspaceID()) { + if (workspace_number == screen.getCurrentWorkspaceID()) { m_frame.show(); } XSync(display,false); - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), last_move_x, last_move_y, m_frame.width() + 2*frame().window().borderWidth(), m_frame.height() + 2*frame().window().borderWidth());

@@ -2402,10 +2556,10 @@ left_fixsize(&gx, &gy);

else right_fixsize(&gx, &gy); - if (screen->doShowWindowPos()) - screen->showGeometry(gx, gy); + if (screen.doShowWindowPos()) + screen.showGeometry(gx, gy); - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), last_resize_x, last_resize_y, last_resize_w - 1 + 2 * m_frame.window().borderWidth(), last_resize_h - 1 + 2 * m_frame.window().borderWidth());

@@ -2414,12 +2568,12 @@

void FluxboxWindow::stopResizing(Window win) { resizing = false; - XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(), + XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), last_resize_x, last_resize_y, last_resize_w - 1 + 2 * m_frame.window().borderWidth(), last_resize_h - 1 + 2 * m_frame.window().borderWidth()); - screen->hideGeometry(); + screen.hideGeometry(); if (win && win == m_frame.gripLeft()) left_fixsize();

@@ -2439,7 +2593,7 @@ void FluxboxWindow::updateIcon() {

if (Fluxbox::instance()->useIconBar()) { const IconBar *iconbar = 0; const IconBarObj *icon = 0; - if ((iconbar = screen->getToolbar()->iconBar()) != 0) { + if ((iconbar = screen.getToolbar()->iconBar()) != 0) { if ((icon = iconbar->findIcon(this)) != 0) iconbar->draw(icon, icon->width()); }

@@ -2447,89 +2601,118 @@ }

} void FluxboxWindow::updateTransientInfo() { - // remove us from parent - if (client.transient_for != 0) { - client.transient_for->client.transients.remove(this); - } - client.transient_for = 0; - - // determine if this is a transient window - Window win; - if (!XGetTransientForHint(display, client.window, &win)) - return; - - if (win == client.window) - return; - - if (win == screen->getRootWindow() && win != 0) { - modal = true; - return; - } - - client.transient_for = Fluxbox::instance()->searchWindow(win); - if (client.transient_for != 0 && - client.window_group != None && win == client.window_group) { - client.transient_for = Fluxbox::instance()->searchGroup(win, this); - } - - // make sure we don't have deadlock loop in transient chain - for (FluxboxWindow *w = this; w != 0; w = w->client.transient_for) { - if (w == w->client.transient_for) { - w->client.transient_for = 0; -#ifdef DEBUG - cerr<<"w = client.transient_for"; -#endif // DEBUG - break; - } - } - - if (client.transient_for != 0) { - client.transient_for->client.transients.push_back(this); - // make sure we only have on instance of this - client.transient_for->client.transients.unique(); - stuck = client.transient_for->stuck; - } - + for_each(clientList().begin(), + clientList().end(), + mem_fun(&WinClient::updateTransientInfo)); } -void FluxboxWindow::restore(bool remap) { - XChangeSaveSet(display, client.window, SetModeDelete); - XSelectInput(display, client.window, NoEventMask); +void FluxboxWindow::restore(WinClient *client, bool remap) { + if (client->m_win != this) + return; - restoreGravity(); + XChangeSaveSet(display, client->window(), SetModeDelete); + client->setEventMask(NoEventMask); - m_frame.hide(); - // make sure the frame doesn't change client window anymore - m_frame.removeClient(); + //!! TODO + //restoreGravity(); - XUnmapWindow(display, client.window); + client->hide(); // restore old border width - XSetWindowBorderWidth(display, client.window, client.old_bw); + client->setBorderWidth(client->old_bw); - XEvent dummy; - if (! XCheckTypedWindowEvent(display, client.window, ReparentNotify, - &dummy)) { + XEvent not_used; + if (! XCheckTypedWindowEvent(display, client->window(), ReparentNotify, + &not_used)) { #ifdef DEBUG - cerr<<"FluxboxWindow::restore: reparent 0x"<<hex<<client.window<<dec<<" to root"<<endl; + cerr<<"FluxboxWindow::restore: reparent 0x"<<hex<<client->window()<<dec<<" to root"<<endl; #endif // DEBUG - // reparent to screen window - XReparentWindow(display, client.window, screen->getRootWindow(), - m_frame.x(), m_frame.y()); - + // reparent to root window + client->reparent(screen.getRootWindow(), m_frame.x(), m_frame.y()); } if (remap) - XMapWindow(display, client.window); + client->show(); + + delete client; + + if (numClients() == 0) + m_frame.hide(); } +void FluxboxWindow::restore(bool remap) { + if (numClients() == 0) + return; + + while (!clientList().empty()) { + restore(clientList().back(), remap); + } +} void FluxboxWindow::timeout() { raise(); } +bool FluxboxWindow::isTransient() const { + if (m_client == 0) + return false; + + return (m_client->transientFor() ? true : false); +} + +bool FluxboxWindow::hasTransient() const { + if (m_client == 0) + return false; + return (m_client->transients.size() ? true : false); +} + +const std::list<FluxboxWindow *> &FluxboxWindow::getTransients() const { + return m_client->transients; +} + +std::list<FluxboxWindow *> &FluxboxWindow::getTransients() { + return m_client->transients; +} + +const FluxboxWindow *FluxboxWindow::getTransientFor() const { + if (m_client == 0) + return 0; + return m_client->transient_for; +} + +FluxboxWindow *FluxboxWindow::getTransientFor() { + if (m_client == 0) + return 0; + return m_client->transient_for; +} + +Window FluxboxWindow::getClientWindow() const { + if (m_client == 0) + return 0; + return m_client->window(); +} + +const std::string &FluxboxWindow::getTitle() const { + static string empty_string(""); + if (m_client == 0) + return empty_string; + return m_client->title(); +} + +const std::string &FluxboxWindow::getIconTitle() const { + static string empty_string(""); + if (m_client == 0) + return empty_string; + return m_client->iconTitle(); +} + +int FluxboxWindow::getXClient() const { return m_client->x; } +int FluxboxWindow::getYClient() const { return m_client->y; } +unsigned int FluxboxWindow::getClientHeight() const { return m_client->height(); } +unsigned int FluxboxWindow::getClientWidth() const { return m_client->width(); } +int FluxboxWindow::initialState() const { return m_client->initial_state; } void FluxboxWindow::changeBlackboxHints(const BaseDisplay::BlackboxHints &net) { if ((net.flags & BaseDisplay::ATTRIB_SHADED) &&

@@ -2552,7 +2735,7 @@ maximizeHorizontal();

} } - + if ((net.flags & BaseDisplay::ATTRIB_OMNIPRESENT) && ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_OMNIPRESENT) != (net.attrib & BaseDisplay::ATTRIB_OMNIPRESENT)))

@@ -2561,12 +2744,9 @@

if ((net.flags & BaseDisplay::ATTRIB_WORKSPACE) && (workspace_number != net.workspace)) { - if (getTab()) // disconnect from tab chain before sending it to another workspace - getTab()->disconnect(); - - screen->reassociateWindow(this, net.workspace, true); + screen.reassociateWindow(this, net.workspace, true); - if (screen->getCurrentWorkspaceID() != net.workspace) + if (screen.getCurrentWorkspaceID() != net.workspace) withdraw(); else deiconify();

@@ -2586,10 +2766,11 @@

} void FluxboxWindow::upsize() { - m_frame.setBevel(screen->getBevelWidth()); - m_frame.handle().resize(m_frame.handle().width(), screen->getHandleWidth()); - m_frame.gripLeft().resize(m_frame.buttonHeight(), screen->getHandleWidth()); - m_frame.gripRight().resize(m_frame.gripLeft().width(), m_frame.gripLeft().height()); + m_frame.setBevel(screen.getBevelWidth()); + m_frame.handle().resize(m_frame.handle().width(), screen.getHandleWidth()); + m_frame.gripLeft().resize(m_frame.buttonHeight(), screen.getHandleWidth()); + m_frame.gripRight().resize(m_frame.gripLeft().width(), + m_frame.gripLeft().height()); }

@@ -2602,71 +2783,80 @@

void FluxboxWindow::right_fixsize(int *gx, int *gy) { // calculate the size of the client window and conform it to the // size specified by the size hints of the client window... - int dx = last_resize_w - client.base_width; - int titlebar_height = (decorations.titlebar ? frame().titlebar().height() + frame().titlebar().borderWidth() : 0); - int handle_height = (decorations.handle ? frame().handle().height() + frame().handle().borderWidth() : 0); + int dx = last_resize_w - m_client->base_width; + int titlebar_height = (decorations.titlebar ? + frame().titlebar().height() + + frame().titlebar().borderWidth() : 0); + int handle_height = (decorations.handle ? + frame().handle().height() + + frame().handle().borderWidth() : 0); - int dy = last_resize_h - client.base_height - titlebar_height - handle_height; - if (dx < (signed) client.min_width) - dx = client.min_width; - if (dy < (signed) client.min_height) - dy = client.min_height; - if (client.max_width > 0 && (unsigned) dx > client.max_width) - dx = client.max_width; - if (client.max_height > 0 && (unsigned) dy > client.max_height) - dy = client.max_height; + int dy = last_resize_h - m_client->base_height - titlebar_height - handle_height; + if (dx < (signed) m_client->min_width) + dx = m_client->min_width; + if (dy < (signed) m_client->min_height) + dy = m_client->min_height; + if (m_client->max_width > 0 && (unsigned) dx > m_client->max_width) + dx = m_client->max_width; + if (m_client->max_height > 0 && (unsigned) dy > m_client->max_height) + dy = m_client->max_height; // make it snap - if (client.width_inc == 0) - client.width_inc = 1; - if (client.height_inc == 0) - client.height_inc = 1; + if (m_client->width_inc == 0) + m_client->width_inc = 1; + if (m_client->height_inc == 0) + m_client->height_inc = 1; - dx /= client.width_inc; - dy /= client.height_inc; + dx /= m_client->width_inc; + dy /= m_client->height_inc; if (gx) *gx = dx; if (gy) *gy = dy; - dx = (dx * client.width_inc) + client.base_width; - dy = (dy * client.height_inc) + client.base_height + titlebar_height + handle_height; + dx = (dx * m_client->width_inc) + m_client->base_width; + dy = (dy * m_client->height_inc) + m_client->base_height + + titlebar_height + handle_height; last_resize_w = dx; last_resize_h = dy; } void FluxboxWindow::left_fixsize(int *gx, int *gy) { - int titlebar_height = (decorations.titlebar ? frame().titlebar().height() + frame().titlebar().borderWidth() : 0); - int handle_height = (decorations.handle ? frame().handle().height() + frame().handle().borderWidth() : 0); + int titlebar_height = (decorations.titlebar ? + frame().titlebar().height() + + frame().titlebar().borderWidth() : 0); + int handle_height = (decorations.handle ? + frame().handle().height() + + frame().handle().borderWidth() : 0); int decoration_height = titlebar_height + handle_height; // dx is new width = current width + difference between new and old x values int dx = m_frame.width() + m_frame.x() - last_resize_x; // dy = new height (w/o decorations), similarly - int dy = last_resize_h - client.base_height - decoration_height; + int dy = last_resize_h - m_client->base_height - decoration_height; // check minimum size - if (dx < static_cast<signed int>(client.min_width)) - dx = client.min_width; - if (dy < static_cast<signed int>(client.min_height)) - dy = client.min_height; + if (dx < static_cast<signed int>(m_client->min_width)) + dx = m_client->min_width; + if (dy < static_cast<signed int>(m_client->min_height)) + dy = m_client->min_height; // check maximum size - if (client.max_width > 0 && dx > static_cast<signed int>(client.max_width)) - dx = client.max_width; - if (client.max_height > 0 && dy > static_cast<signed int>(client.max_height)) - dy = client.max_height; + if (m_client->max_width > 0 && dx > static_cast<signed int>(m_client->max_width)) + dx = m_client->max_width; + if (m_client->max_height > 0 && dy > static_cast<signed int>(m_client->max_height)) + dy = m_client->max_height; // make sure we have valid increment - if (client.width_inc == 0) - client.width_inc = 1; - if (client.height_inc == 0) - client.height_inc = 1; + if (m_client->width_inc == 0) + m_client->width_inc = 1; + if (m_client->height_inc == 0) + m_client->height_inc = 1; // set snapping - dx /= client.width_inc; - dy /= client.height_inc; + dx /= m_client->width_inc; + dy /= m_client->height_inc; // set return values if (gx != 0)

@@ -2675,8 +2865,8 @@ if (gy != 0)

*gy = dy; // snapping - dx = dx * client.width_inc + client.base_width; - dy = dy * client.height_inc + client.base_height + decoration_height; + dx = dx * m_client->width_inc + m_client->base_width; + dy = dy * m_client->height_inc + m_client->base_height + decoration_height; // update last resize last_resize_w = dx;
M src/Window.hhsrc/Window.hh

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Window.hh,v 1.53 2003/03/22 05:13:08 rathnor Exp $ +// $Id: Window.hh,v 1.54 2003/04/14 14:45:14 fluxgen Exp $ #ifndef WINDOW_HH #define WINDOW_HH

@@ -46,12 +46,14 @@

#include <vector> #include <string> #include <memory> +#include <map> #define PropMwmHintsElements 3 -class Tab; +class WinClient; class FbWinFrameTheme; class BScreen; +class TextButton; namespace FbTk { class MenuTheme;

@@ -98,20 +100,38 @@ MwmDecorIconify = (1l << 5), /// iconify

MwmDecorMaximize = (1l << 6) /// maximize }; + typedef std::list<WinClient *> ClientList; + + /// create a window from a client + FluxboxWindow(WinClient &client, BScreen &scr, + FbWinFrameTheme &tm, + FbTk::MenuTheme &menutheme, + FbTk::XLayer &layer); + /// create fluxbox window with parent win and screen connection - FluxboxWindow(Window win, BScreen *scr, - int screen_num, FbTk::ImageControl &imgctrl, FbWinFrameTheme &tm, + FluxboxWindow(Window win, BScreen &scr, + FbWinFrameTheme &tm, FbTk::MenuTheme &menutheme, FbTk::XLayer &layer); virtual ~FluxboxWindow(); + /// attach client to our client list and remove it from old window + void attachClient(WinClient &client); + /// detach client (remove it from list) and create a new window for it + bool detachClient(WinClient &client); + /// remove client from client list + bool removeClient(WinClient &client); + /// set new current client and raise it + void setCurrentClient(WinClient &client); + WinClient *findClient(Window win); + void nextClient(); + void prevClient(); void setWindowNumber(int n) { window_number = n; } bool validateClient(); bool setInputFocus(); void raiseAndFocus() { raise(); setInputFocus(); } - void setTab(bool flag); void setFocusFlag(bool flag); // map this window void show();

@@ -141,6 +161,7 @@ void moveToLayer(int layernum);

void reconfigure(); void installColormap(bool); + void restore(WinClient *client, bool remap); void restore(bool remap); /// move frame to x, y void move(int x, int y);

@@ -190,41 +211,41 @@ /**

@name accessors */ //@{ - bool isTransient() const { return ((client.transient_for) ? true : false); } - bool hasTransient() const { return ((client.transients.size()) ? true : false); } - bool isManaged() const { return m_managed; } - bool isFocused() const { return focused; } - bool isVisible() const { return visible; } - bool isIconic() const { return iconic; } - bool isShaded() const { return shaded; } - bool isMaximized() const { return maximized; } - bool isIconifiable() const { return functions.iconify; } - bool isMaximizable() const { return functions.maximize; } - bool isResizable() const { return functions.resize; } - bool isClosable() const { return functions.close; } - bool isStuck() const { return stuck; } - bool hasTitlebar() const { return decorations.titlebar; } - bool hasTab() const { return (tab!=0 ? true : false); } - bool isMoving() const { return moving; } - bool isResizing() const { return resizing; } + inline bool isTransient() const; + inline bool hasTransient() const; + inline bool isManaged() const { return m_managed; } + inline bool isFocused() const { return focused; } + inline bool isVisible() const { return visible; } + inline bool isIconic() const { return iconic; } + inline bool isShaded() const { return shaded; } + inline bool isMaximized() const { return maximized; } + inline bool isIconifiable() const { return functions.iconify; } + inline bool isMaximizable() const { return functions.maximize; } + inline bool isResizable() const { return functions.resize; } + inline bool isClosable() const { return functions.close; } + inline bool isStuck() const { return stuck; } + inline bool hasTitlebar() const { return decorations.titlebar; } + inline bool isMoving() const { return moving; } + inline bool isResizing() const { return resizing; } bool isGroupable() const; - - const BScreen *getScreen() const { return screen; } - BScreen *getScreen() { return screen; } - - const FbTk::XLayerItem &getLayerItem() const { return m_layeritem; } - FbTk::XLayerItem &getLayerItem() { return m_layeritem; } + inline int numClients() const { return m_clientlist.size(); } + inline ClientList &clientList() { return m_clientlist; } + inline const ClientList &clientList() const { return m_clientlist; } + inline WinClient &winClient() { return *m_client; } + inline const WinClient &winClient() const { return *m_client; } - const Tab *getTab() const { return tab; } - Tab *getTab() { return tab; } + inline const BScreen &getScreen() const { return screen; } + inline BScreen &getScreen() { return screen; } - const std::list<FluxboxWindow *> &getTransients() const { return client.transients; } - std::list<FluxboxWindow *> &getTransients() { return client.transients; } + inline const FbTk::XLayerItem &getLayerItem() const { return m_layeritem; } + inline FbTk::XLayerItem &getLayerItem() { return m_layeritem; } - const FluxboxWindow *getTransientFor() const { return client.transient_for; } - FluxboxWindow *getTransientFor() { return client.transient_for; } + const std::list<FluxboxWindow *> &getTransients() const; + std::list<FluxboxWindow *> &getTransients(); + const FluxboxWindow *getTransientFor() const; + FluxboxWindow *getTransientFor(); - Window getClientWindow() const { return client.window; } + Window getClientWindow() const; FbTk::FbWindow &getFbWindow() { return m_frame.window(); } const FbTk::FbWindow &getFbWindow() const { return m_frame.window(); }

@@ -232,28 +253,28 @@

FbTk::Menu &getWindowmenu() { return m_windowmenu; } const FbTk::Menu &getWindowmenu() const { return m_windowmenu; } - FbTk::Menu *getLayermenu() { return m_layermenu; } - const FbTk::Menu *getLayermenu() const { return m_layermenu; } + FbTk::Menu &getLayermenu() { return m_layermenu; } + const FbTk::Menu &getLayermenu() const { return m_layermenu; } - const std::string &getTitle() const { return client.title; } - const std::string &getIconTitle() const { return client.icon_title; } + const std::string &getTitle() const; + const std::string &getIconTitle() const; int getXFrame() const { return m_frame.x(); } int getYFrame() const { return m_frame.y(); } - int getXClient() const { return client.x; } - int getYClient() const { return client.y; } + int getXClient() const; + int getYClient() const; unsigned int getWorkspaceNumber() const { return workspace_number; } int getWindowNumber() const { return window_number; } int getLayerNum() const { return m_layernum; } void setLayerNum(int layernum); unsigned int getWidth() const { return m_frame.width(); } unsigned int getHeight() const { return m_frame.height(); } - unsigned int getClientHeight() const { return client.height; } - unsigned int getClientWidth() const { return client.width; } + unsigned int getClientHeight() const; + unsigned int getClientWidth() const; unsigned int getTitleHeight() const { return m_frame.titleHeight(); } const std::string &className() const { return m_class_name; } const std::string &instanceName() const { return m_instance_name; } bool isLowerTab() const; - int initialState() const { return client.initial_state; } + int initialState() const; FbWinFrame &frame() { return m_frame; } const FbWinFrame &frame() const { return m_frame; }

@@ -288,13 +309,7 @@ FluxboxWindow &m_win;

}; private: - // this structure only contains 3 elements... the Motif 2.0 structure contains - // 5... we only need the first 3... so that is all we will define - typedef struct MwmHints { - unsigned long flags; // Motif wm flags - unsigned long functions; // Motif wm functions - unsigned long decorations; // Motif wm decorations - } MwmHints; + void init(); void grabButtons();

@@ -341,14 +356,14 @@ //Window state

bool moving, resizing, shaded, maximized, visible, iconic, transient, focused, stuck, modal, send_focus_message, m_managed; - BScreen *screen; /// screen on which this window exist + BScreen &screen; /// screen on which this window exist FbTk::Timer timer; - Display *display; /// display connection (obsolete by FbTk) + Display *display; /// display connection BaseDisplay::BlackboxAttributes blackbox_attrib; Time lastButtonPressTime; FbTk::Menu m_windowmenu; - LayerMenu<FluxboxWindow> *m_layermenu; + LayerMenu<FluxboxWindow> m_layermenu; timeval lastFocusTime;

@@ -364,23 +379,13 @@ unsigned long current_state;

Decoration old_decoration; - struct _client { - FluxboxWindow *transient_for; // which window are we a transient for? - std::list<FluxboxWindow *> transients; // which windows are our transients? - Window window, window_group; + ClientList m_clientlist; + WinClient *m_client; + typedef std::map<WinClient *, TextButton *> Client2ButtonMap; + Client2ButtonMap m_labelbuttons; - std::string title, icon_title; - int x, y, old_bw; - unsigned int width, height, title_text_w, - min_width, min_height, max_width, max_height, width_inc, height_inc, - min_aspect_x, min_aspect_y, max_aspect_x, max_aspect_y, - base_width, base_height, win_gravity; - unsigned long initial_state, normal_hint_flags, wm_hint_flags; - - MwmHints *mwm_hint; - BaseDisplay::BlackboxHints *blackbox_hint; - - } client; + // just temporary solution + friend class WinClient; struct _decorations { bool titlebar, handle, border, iconify,

@@ -391,11 +396,6 @@ struct _functions {

bool resize, move, iconify, maximize, close; } functions; - - Tab *tab; - friend class Tab; //TODO: Don't like long distant friendship - - int frame_resize_x, frame_resize_w; int frame_resize_y, frame_resize_h; int m_old_pos_x, m_old_pos_y; ///< old position so we can restore from maximized
M src/Workspace.ccsrc/Workspace.cc

@@ -1,5 +1,5 @@

// Workspace.cc for Fluxbox -// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) +// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen[at]users.sourceforge.net) // // Workspace.cc for Blackbox - an X11 Window manager // Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)

@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Workspace.cc,v 1.50 2003/02/20 21:00:29 fluxgen Exp $ +// $Id: Workspace.cc,v 1.51 2003/04/14 14:59:15 fluxgen Exp $ #include "Workspace.hh"

@@ -32,6 +32,7 @@ #include "Screen.hh"

#include "Window.hh" #include "StringUtil.hh" #include "SimpleCommand.hh" +#include "WinClient.hh" // use GNU extensions #ifndef _GNU_SOURCE

@@ -50,6 +51,7 @@ #include <cstring>

#include <algorithm> #include <iostream> +#include <iterator> using namespace std;

@@ -68,24 +70,42 @@

return ret; } -class RaiseFocusAndSetWorkspace: public FbTk::Command { +class ClientMenuItem:public FbTk::MenuItem { public: - RaiseFocusAndSetWorkspace(Workspace &space, FluxboxWindow &win): - m_space(space), m_win(win) { } - void execute() { + ClientMenuItem(WinClient &client, Workspace &space): + FbTk::MenuItem(client.title().c_str()), + m_client(client), m_space(space) { + + } + void click(int button, int time) { + if (m_client.fbwindow() == 0) + return; + FluxboxWindow &win = *m_client.fbwindow(); + BScreen &scr = win.getScreen(); // determine workspace change - for (size_t i=0; i<m_space.getScreen().getCount(); i++) { - if (m_space.getScreen().getWorkspace(i) == &m_space) { - m_space.getScreen().changeWorkspaceID(i); + for (size_t i=0; i<scr.getCount(); i++) { + if (scr.getWorkspace(i) == &m_space) { + scr.changeWorkspaceID(i); break; } } - m_win.raiseAndFocus(); + win.setCurrentClient(m_client); + win.raiseAndFocus(); + } + + const std::string &label() const { return m_client.title(); } + bool isSelected() const { + if (m_client.fbwindow() == 0) + return false; + if (m_client.fbwindow()->isFocused() == false) + return false; + return (&(m_client.fbwindow()->winClient()) == &m_client); + } private: + WinClient &m_client; Workspace &m_space; - FluxboxWindow &m_win; }; };

@@ -119,15 +139,18 @@ else

lastfocus = 0; } -int Workspace::addWindow(FluxboxWindow *w, bool place) { - if (w == 0) +int Workspace::addWindow(FluxboxWindow &w, bool place) { + // we don't need to add a window that already exist in our list + if (find(m_windowlist.begin(), m_windowlist.end(), &w) != + m_windowlist.end()) return -1; + w.setWorkspace(m_id); + w.setWindowNumber(m_windowlist.size()); + if (place) placeWindow(w); - w->setWorkspace(m_id); - w->setWindowNumber(m_windowlist.size()); //insert window after the currently focused window //FluxboxWindow *focused = Fluxbox::instance()->getFocusedWindow();

@@ -168,18 +191,19 @@ if (insert_point_it != m_windowlist.end())

m_windowlist.insert(insert_point_it, w); else // we didn't find it, so we just add it to stack */ - m_windowlist.push_back(w); + m_windowlist.push_back(&w); updateClientmenu(); - if (!w->isStuck()) - screen.updateNetizenWindowAdd(w->getClientWindow(), m_id); + if (!w.isStuck()) + screen.updateNetizenWindowAdd(w.getClientWindow(), m_id); - return w->getWindowNumber(); + return w.getWindowNumber(); } int Workspace::removeWindow(FluxboxWindow *w) { + if (w == 0) return -1;

@@ -200,38 +224,38 @@ // this bit is pretty dodgy at present

// it gets the next item down, then scans through our windowlist to see if it is // in this workspace. If not, goes down more /* //!! TODO! FbTk::XLayerItem *item = 0, *lastitem = w->getLayerItem(); - do { - item = m_layermanager.getItemBelow(*lastitem); - Windows::iterator it = m_windowlist.begin(); - Windows::iterator it_end = m_windowlist.end(); - for (; it != it_end; ++it) { - if ((*it)->getLayerItem() == item) { - // found one! - top = *it; - } - } + do { + item = m_layermanager.getItemBelow(*lastitem); + Windows::iterator it = m_windowlist.begin(); + Windows::iterator it_end = m_windowlist.end(); + for (; it != it_end; ++it) { + if ((*it)->getLayerItem() == item) { + // found one! + top = *it; + } + } - lastitem = item; + lastitem = item; - } while (item && !top); + } while (item && !top); - if (!top) { - // look upwards - lastitem = w->getLayerItem(); - do { - item = m_layermanager.getItemAbove(*lastitem); - Windows::iterator it = m_windowlist.begin(); - Windows::iterator it_end = m_windowlist.end(); - for (; it != it_end; ++it) { - if ((*it)->getLayerItem() == item) { - // found one! - top = *it; - } - } - lastitem = item; - } while (item && !top); + if (!top) { + // look upwards + lastitem = w->getLayerItem(); + do { + item = m_layermanager.getItemAbove(*lastitem); + Windows::iterator it = m_windowlist.begin(); + Windows::iterator it_end = m_windowlist.end(); + for (; it != it_end; ++it) { + if ((*it)->getLayerItem() == item) { + // found one! + top = *it; + } + } + lastitem = item; + } while (item && !top); - } + } */ if (top == 0|| !top->setInputFocus()) { Fluxbox::instance()->setFocusedWindow(0); // set focused window to none

@@ -240,34 +264,32 @@ }

} // we don't remove it from the layermanager, as it may be being moved + Windows::iterator erase_it = remove(m_windowlist.begin(), + m_windowlist.end(), w); + if (erase_it != m_windowlist.end()) + m_windowlist.erase(erase_it); - Windows::iterator it = m_windowlist.begin(); - Windows::iterator it_end = m_windowlist.end(); - for (; it != it_end; ++it) { - if (*it == w) { - m_windowlist.erase(it); - break; - } - } updateClientmenu(); - - if (!w->isStuck()) - screen.updateNetizenWindowDel(w->getClientWindow()); - { - Windows::iterator it = m_windowlist.begin(); - Windows::const_iterator it_end = m_windowlist.end(); - for (int i = 0; it != it_end; ++it, ++i) { - (*it)->setWindowNumber(i); - } - } - if (lastfocus == w || m_windowlist.empty()) lastfocus = 0; - + return m_windowlist.size(); } +void Workspace::removeWindow(WinClient &client) { + if (client.m_win == 0) + return; + + if (client.m_win->numClients() == 0) { + Windows::iterator erase_it = remove(m_windowlist.begin(), + m_windowlist.end(), client.m_win); + if (erase_it != m_windowlist.end()) + m_windowlist.erase(erase_it); + } + + updateClientmenu(); +} void Workspace::showAll() { Windows::iterator it = m_windowlist.begin();

@@ -375,16 +397,7 @@ if (find_if((*g).begin(), (*g).end(), FindInGroup(*(*wit))) != (*g).end()) {

// make sure the window is groupable if ( !(*wit)->isGroupable()) break; // try next name - //toggle tab on - if ((*wit)->getTab() == 0) - (*wit)->setTab(true); - if (win.getTab() == 0) - win.setTab(true); - // did we succefully set the tab? - if ((*wit)->getTab() == 0) - break; // try another window - (*wit)->getTab()->insert(win.getTab()); - + cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO attach client here!"<<endl; return; // grouping done } }

@@ -438,7 +451,8 @@ } else { //if name == 0 then set default name from nls

char tname[128]; sprintf(tname, I18n::instance()-> getMessage( - FBNLS::WorkspaceSet, FBNLS::WorkspaceDefaultNameFormat, + FBNLS::WorkspaceSet, + FBNLS::WorkspaceDefaultNameFormat, "Workspace %d"), m_id + 1); //m_id starts at 0 m_name = tname; }

@@ -455,161 +469,103 @@ on the workspace and then

clears the m_windowlist */ void Workspace::shutdown() { +#ifdef DEBUG + cerr<<__FILE__<<"("<<__FUNCTION__<<"): windowlist:"<<endl; + copy(m_windowlist.begin(), m_windowlist.end(), + ostream_iterator<FluxboxWindow *>(cerr, " \n")); + cerr<<endl; +#endif // DEBUG // note: when the window dies it'll remove it self from the list while (!m_windowlist.empty()) { - m_windowlist.back()->restore(true); // restore with remap - delete m_windowlist.back(); //delete window (the window removes it self from m_windowlist) + // restore with remap on all clients in that window + m_windowlist.back()->restore(true); + //delete window (the window removes it self from m_windowlist) + delete m_windowlist.back(); } } void Workspace::updateClientmenu() { + // remove all items and then add them again m_clientmenu.removeAll(); + // for each fluxboxwindow add every client in them to our clientlist Windows::iterator win_it = m_windowlist.begin(); Windows::iterator win_it_end = m_windowlist.end(); for (; win_it != win_it_end; ++win_it) { - FbTk::RefCount<FbTk::Command> - raise_and_focus(new RaiseFocusAndSetWorkspace(*this, *(*win_it))); - - m_clientmenu.insert((*win_it)->getTitle().c_str(), raise_and_focus); + // add every client in this fluxboxwindow to menu + FluxboxWindow::ClientList::iterator client_it = + (*win_it)->clientList().begin(); + FluxboxWindow::ClientList::iterator client_it_end = + (*win_it)->clientList().end(); + for (; client_it != client_it_end; ++client_it) { + /* FbTk::RefCount<FbTk::Command> + raise_and_focus(new RaiseFocusAndSetWorkspace(*this, + *(*client_it))); + */ + m_clientmenu.insert(new ClientMenuItem(*(*client_it), *this)); + } } + m_clientmenu.update(); } -void Workspace::placeWindow(FluxboxWindow *win) { - Bool placed = False; - int borderWidth4x = screen.getBorderWidth2x() * 2, +void Workspace::placeWindow(FluxboxWindow &win) { - place_x = 0, place_y = 0, change_x = 1, change_y = 1; + bool placed = false; + + int place_x = 0, place_y = 0, change_x = 1, change_y = 1; if (screen.getColPlacementDirection() == BScreen::BOTTOMTOP) change_y = -1; if (screen.getRowPlacementDirection() == BScreen::RIGHTLEFT) change_x = -1; -#ifdef XINERAMA - int head = 0, - head_x = 0, - head_y = 0; - int head_w, head_h; - if (screen.hasXinerama()) { - head = screen.getCurrHead(); - head_x = screen.getHeadX(head); - head_y = screen.getHeadY(head); - head_w = screen.getHeadWidth(head); - head_h = screen.getHeadHeight(head); - } else { // no xinerama - head_w = screen.getWidth(); - head_h = screen.getHeight(); - } - -#endif // XINERAMA - - int win_w = win->getWidth() + screen.getBorderWidth2x(), - win_h = win->getHeight() + screen.getBorderWidth2x(); + int win_w = win.getWidth() + screen.getBorderWidth2x(), + win_h = win.getHeight() + screen.getBorderWidth2x(); - if (win->hasTab()) { - if ((! win->isShaded()) && - screen.getTabPlacement() == Tab::PLEFT || - screen.getTabPlacement() == Tab::PRIGHT) - win_w += (screen.isTabRotateVertical()) - ? screen.getTabHeight() - : screen.getTabWidth(); - else // tab placement top or bottom or win is shaded - win_h += screen.getTabHeight(); - } - - register int test_x, test_y, curr_x, curr_y, curr_w, curr_h; + int test_x, test_y, curr_x, curr_y, curr_w, curr_h; switch (screen.getPlacementPolicy()) { case BScreen::ROWSMARTPLACEMENT: { -#ifdef XINERAMA - test_y = head_y; -#else // !XINERAMA + test_y = 0; -#endif // XINERAMA + if (screen.getColPlacementDirection() == BScreen::BOTTOMTOP) -#ifdef XINERAMA - test_y = (head_y + head_h) - win_h - test_y; -#else // !XINERAMA - test_y = screen.getHeight() - win_h - test_y; -#endif // XINERAMA + test_y = screen.getHeight() - win_h - test_y; + while (((screen.getColPlacementDirection() == BScreen::BOTTOMTOP) ? -#ifdef XINERAMA - test_y >= head_y : test_y + win_h <= (head_y + head_h) -#else // !XINERAMA - test_y > 0 : test_y + win_h < (signed) screen.getHeight() -#endif // XINERAMA - ) && ! placed) { + test_y > 0 : test_y + win_h < (signed) screen.getHeight()) && + ! placed) { -#ifdef XINERAMA - test_x = head_x; -#else // !XINERAMA test_x = 0; -#endif // XINERAMA + if (screen.getRowPlacementDirection() == BScreen::RIGHTLEFT) -#ifdef XINERAMA - test_x = (head_x + head_w) - win_w - test_x; -#else // !XINERAMA - test_x = screen.getWidth() - win_w - test_x; -#endif // XINERAMA + test_x = screen.getWidth() - win_w - test_x; + while (((screen.getRowPlacementDirection() == BScreen::RIGHTLEFT) ? -#ifdef XINERAMA - test_x >= head_x : test_x + win_w <= (head_x + head_w) -#else // !XINERAMA - test_x > 0 : test_x + win_w < (signed) screen.getWidth() -#endif // XINERAMA - ) && ! placed) { + test_x > 0 : test_x + win_w < (signed) screen.getWidth()) && ! placed) { - placed = True; + placed = true; - Windows::iterator it = m_windowlist.begin(); - Windows::iterator it_end = m_windowlist.end(); + Windows::iterator win_it = m_windowlist.begin(); + const Windows::iterator win_it_end = m_windowlist.end(); - for (; it != it_end && placed; ++it) { - curr_x = (*it)->getXFrame(); - curr_y = (*it)->getYFrame(); - curr_w = (*it)->getWidth() + screen.getBorderWidth2x(); - curr_h = - (((*it)->isShaded()) - ? (*it)->getTitleHeight() - : (*it)->getHeight()) + - screen.getBorderWidth2x(); + for (; win_it != win_it_end && placed; ++win_it) { + FluxboxWindow &window = **win_it; - if ((*it)->hasTab()) { - if (! (*it)->isShaded()) { // not shaded window - switch(screen.getTabPlacement()) { - case Tab::PTOP: - curr_y -= screen.getTabHeight(); - case Tab::PBOTTOM: - curr_h += screen.getTabHeight(); - break; - case Tab::PLEFT: - curr_x -= (screen.isTabRotateVertical()) - ? screen.getTabHeight() - : screen.getTabWidth(); - case Tab::PRIGHT: - curr_w += (screen.isTabRotateVertical()) - ? screen.getTabHeight() - : screen.getTabWidth(); - break; - case Tab::PNONE: - break; - } - } else { // shaded window - if (screen.getTabPlacement() == Tab::PTOP) - curr_y -= screen.getTabHeight(); - curr_h += screen.getTabHeight(); - } - } // tab cheking done + curr_x = window.getXFrame(); + curr_y = window.getYFrame(); + curr_w = window.getWidth() + screen.getBorderWidth2x(); + curr_h = window.isShaded() ? window.getTitleHeight() : + window.getHeight() + screen.getBorderWidth2x(); if (curr_x < test_x + win_w && curr_x + curr_w > test_x && curr_y < test_y + win_h && curr_y + curr_h > test_y) { - placed = False; + placed = false; } }

@@ -622,53 +578,33 @@ break;

} test_x += change_x; - } + } // end while test_y += change_y; - } + } // end while - break; } + break; + } // end case ROWSMARTPLACEMENT case BScreen::COLSMARTPLACEMENT: { -#ifdef XINERAMA - test_x = head_x; -#else // !XINERAMA test_x = 0; -#endif // XINERAMA + if (screen.getRowPlacementDirection() == BScreen::RIGHTLEFT) -#ifdef XINERAMA - test_x = (head_x + head_w) - win_w - test_x; -#else // !XINERAMA - test_x = screen.getWidth() - win_w - test_x; -#endif // XINERAMA + + test_x = screen.getWidth() - win_w - test_x; + while (((screen.getRowPlacementDirection() == BScreen::RIGHTLEFT) ? -#ifdef XINERAMA - test_x >= 0 : test_x + win_w <= (head_x + head_w) -#else // !XINERAMA - test_x > 0 : test_x + win_w < (signed) screen.getWidth() -#endif // XINERAMA - ) && ! placed) { + test_x > 0 : test_x + win_w < (signed) screen.getWidth()) && + !placed) { -#ifdef XINERAMA - test_y = head_y; -#else // !XINERAMA test_y = 0; -#endif // XINERAMA if (screen.getColPlacementDirection() == BScreen::BOTTOMTOP) -#ifdef XINERAMA - test_y = (head_y + head_h) - win_h - test_y; -#else // !XINERAMA - test_y = screen.getHeight() - win_h - test_y; -#endif // XINERAMA + test_y = screen.getHeight() - win_h - test_y; while (((screen.getColPlacementDirection() == BScreen::BOTTOMTOP) ? -#ifdef XINERAMA - test_y >= head_y : test_y + win_h <= (head_y + head_h) -#else // !XINERAMA - test_y > 0 : test_y + win_h < (signed) screen.getHeight() -#endif // XINERAMA - ) && ! placed) { + test_y > 0 : test_y + win_h < (signed) screen.getHeight()) && + !placed) { placed = True; Windows::iterator it = m_windowlist.begin();

@@ -683,36 +619,6 @@ ? (*it)->getTitleHeight()

: (*it)->getHeight()) + screen.getBorderWidth2x();; - if ((*it)->hasTab()) { - if (! (*it)->isShaded()) { // not shaded window - switch(screen.getTabPlacement()) { - case Tab::PTOP: - curr_y -= screen.getTabHeight(); - case Tab::PBOTTOM: - curr_h += screen.getTabHeight(); - break; - case Tab::PLEFT: - curr_x -= (screen.isTabRotateVertical()) - ? screen.getTabHeight() - : screen.getTabWidth(); - case Tab::PRIGHT: - curr_w += (screen.isTabRotateVertical()) - ? screen.getTabHeight() - : screen.getTabWidth(); - break; - default: -#ifdef DEBUG - cerr << __FILE__ << ":" <<__LINE__ << ": " << - "Unsupported Placement" << endl; -#endif // DEBUG - break; - } - } else { // shaded window - if (screen.getTabPlacement() == Tab::PTOP) - curr_y -= screen.getTabHeight(); - curr_h += screen.getTabHeight(); - } - } // tab cheking done if (curr_x < test_x + win_w && curr_x + curr_w > test_x &&

@@ -729,57 +635,35 @@ place_y = test_y;

} test_y += change_y; - } + } // end while test_x += change_x; - } + } // end while + + break; + } // end COLSMARTPLACEMENT - break; } } // cascade placement or smart placement failed if (! placed) { -#ifdef XINERAMA - if ((cascade_x > (head_w / 2)) || - (cascade_y > (head_h / 2))) -#else // !XINERAMA - if (((unsigned) cascade_x > (screen.getWidth() / 2)) || - ((unsigned) cascade_y > (screen.getHeight() / 2))) -#endif // XINERAMA + + if (((unsigned) cascade_x > (screen.getWidth() / 2)) || + ((unsigned) cascade_y > (screen.getHeight() / 2))) + cascade_x = cascade_y = 32; - cascade_x = cascade_y = 32; -#ifdef XINERAMA - place_x = head_x + cascade_x; - place_y = head_y + cascade_y; -#else // !XINERAMA place_x = cascade_x; place_y = cascade_y; -#endif // XINERAMA - cascade_x += win->getTitleHeight(); - cascade_y += win->getTitleHeight(); + + cascade_x += win.getTitleHeight(); + cascade_y += win.getTitleHeight(); } -#ifdef XINERAMA - if (place_x + win_w > (head_x + head_w)) - place_x = head_x + ((head_w - win_w) / 2); - if (place_y + win_h > (head_y + head_h)) - place_y = head_y + ((head_h - win_h) / 2); -#else // !XINERAMA if (place_x + win_w > (signed) screen.getWidth()) place_x = (((signed) screen.getWidth()) - win_w) / 2; if (place_y + win_h > (signed) screen.getHeight()) place_y = (((signed) screen.getHeight()) - win_h) / 2; -#endif // XINERAMA - // fix window placement, think of tabs - if (win->hasTab()) { - if (screen.getTabPlacement() == Tab::PTOP) - place_y += screen.getTabHeight(); - else if (screen.getTabPlacement() == Tab::PLEFT) - place_x += (screen.isTabRotateVertical()) - ? screen.getTabHeight() - : screen.getTabWidth(); - } - win->moveResize(place_x, place_y, win->getWidth(), win->getHeight()); + win.moveResize(place_x, place_y, win.getWidth(), win.getHeight()); }
M src/Workspace.hhsrc/Workspace.hh

@@ -38,6 +38,7 @@ #include <list>

class BScreen; class FluxboxWindow; +class WinClient; /** Handles a single workspace

@@ -62,8 +63,9 @@ void reconfigure();

void update(); void setCurrent(); void shutdown(); - int addWindow(FluxboxWindow *win, bool place = false); + int addWindow(FluxboxWindow &win, bool place = false); int removeWindow(FluxboxWindow *win); + void removeWindow(WinClient &client); BScreen &getScreen() { return screen; } FluxboxWindow *getLastFocusedWindow() { return lastfocus; }

@@ -92,7 +94,7 @@ int getCount() const;

void checkGrouping(FluxboxWindow &win); static bool loadGroups(const std::string &filename); protected: - void placeWindow(FluxboxWindow *win); + void placeWindow(FluxboxWindow &win); private: void updateClientmenu();