update many things to use WinClient instead of FluxboxWindow

This commit is contained in:
rathnor 2003-07-28 15:06:36 +00:00
parent f9bb208da8
commit d353b688de
20 changed files with 449 additions and 356 deletions

View file

@ -1,5 +1,19 @@
(Format: Year/Month/Day)
Changes for 0.9.5:
*03/07/29:
* Change: (Simon)
- Fluxbox::window search
- Fluxbox::m_focused_window
- strut saving
- Some event handling
- and more
to use WinClient, not FluxboxWindow.
This should fix some bugs where things weren't consistent and
hopefully sets the stage to fix various other things that get out of
whack.
fluxbox.hh/cc Screen.hh/cc Window.hh/cc Workspace.cc WinClient.hh/cc
CurrentWindowCmd.hh/cc AtomHandler.hh Ewmh.hh/cc Gnome.hh/cc
Remember.hh ToolbarHandler.hh Toolbar.cc CurrentWindowCmd.hh/cc
*03/07/28:
* Added MoveTabLeft and MoveTabRight commands (Henrik)
Window.hh/cc, FbWinFrame.hh/cc, FbCommandFactory.cc

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: AtomHandler.hh,v 1.11 2003/07/10 11:23:35 fluxgen Exp $
// $Id: AtomHandler.hh,v 1.12 2003/07/28 15:06:33 rathnor Exp $
#ifndef ATOMHANDLER_HH
#define ATOMHANDLER_HH
@ -51,9 +51,9 @@ public:
virtual void updateLayer(FluxboxWindow &win) = 0;
virtual bool checkClientMessage(const XClientMessageEvent &ce,
BScreen * screen, FluxboxWindow * const win) = 0;
BScreen * screen, WinClient * const winclient) = 0;
virtual bool propertyNotify(FluxboxWindow &win, Atom the_property) = 0;
virtual bool propertyNotify(WinClient &winclient, Atom the_property) = 0;
/// should this object be updated or not?
bool update() const { return m_update; }

View file

@ -20,58 +20,68 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: CurrentWindowCmd.cc,v 1.2 2003/07/26 13:44:00 rathnor Exp $
// $Id: CurrentWindowCmd.cc,v 1.3 2003/07/28 15:06:33 rathnor Exp $
#include "CurrentWindowCmd.hh"
#include "fluxbox.hh"
#include "Window.hh"
#include "Screen.hh"
#include "WinClient.hh"
CurrentWindowCmd::CurrentWindowCmd(Action act):m_action(act) { }
void CurrentWindowCmd::execute() {
Fluxbox *fb = Fluxbox::instance();
if (fb->getFocusedWindow() != 0)
(*fb->getFocusedWindow().*m_action)();
WinClient *client = Fluxbox::instance()->getFocusedWindow();
if (client && client->fbwindow())
(client->fbwindow()->*m_action)();
}
void KillWindowCmd::real_execute() {
XKillClient(FbTk::App::instance()->display(), window().clientWindow());
winclient().sendClose(true);
}
void SendToWorkspaceCmd::real_execute() {
if (m_workspace_num >= 0 && m_workspace_num < window().screen().getNumberOfWorkspaces())
window().screen().sendToWorkspace(m_workspace_num, &window());
if (m_workspace_num >= 0 && m_workspace_num < fbwindow().screen().getNumberOfWorkspaces())
fbwindow().screen().sendToWorkspace(m_workspace_num, &fbwindow());
}
void WindowHelperCmd::execute() {
if (Fluxbox::instance()->getFocusedWindow())
WinClient *client = Fluxbox::instance()->getFocusedWindow();
if (client && client->fbwindow()) // guarantee that fbwindow() exists too
real_execute();
}
FluxboxWindow &WindowHelperCmd::window() {
WinClient &WindowHelperCmd::winclient() {
// will exist from execute above
return *Fluxbox::instance()->getFocusedWindow();
}
FluxboxWindow &WindowHelperCmd::fbwindow() {
// will exist from execute above
return *Fluxbox::instance()->getFocusedWindow()->fbwindow();
}
MoveLeftCmd::MoveLeftCmd(int step_size):MoveHelper(step_size) { }
void MoveLeftCmd::real_execute() {
window().move(window().x() - stepSize(), window().y());
fbwindow().move(fbwindow().x() - stepSize(),
fbwindow().y());
}
MoveRightCmd::MoveRightCmd(int step_size):MoveHelper(step_size) { }
void MoveRightCmd::real_execute() {
window().move(window().x() + stepSize(), window().y());
fbwindow().move(fbwindow().x() + stepSize(),
fbwindow().y());
}
MoveDownCmd::MoveDownCmd(int step_size):MoveHelper(step_size) { }
void MoveDownCmd::real_execute() {
window().move(window().x(), window().y() + stepSize());
fbwindow().move(fbwindow().x(), fbwindow().y() + stepSize());
}
MoveUpCmd::MoveUpCmd(int step_size):MoveHelper(step_size) { }
void MoveUpCmd::real_execute() {
window().move(window().x(), window().y() - stepSize());
fbwindow().move(fbwindow().x(), fbwindow().y() - stepSize());
}

View file

@ -20,7 +20,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: CurrentWindowCmd.hh,v 1.1 2003/06/30 14:35:11 fluxgen Exp $
// $Id: CurrentWindowCmd.hh,v 1.2 2003/07/28 15:06:33 rathnor Exp $
#ifndef CURRENTWINDOWCMD_HH
#define CURRENTWINDOWCMD_HH
@ -28,6 +28,8 @@
#include "Command.hh"
class FluxboxWindow;
class WinClient;
/// command that calls FluxboxWindow::<the function> on execute()
/// similar to FbTk::SimpleCommand<T>
class CurrentWindowCmd: public FbTk::Command {
@ -47,7 +49,8 @@ public:
protected:
FluxboxWindow &window();
WinClient &winclient();
FluxboxWindow &fbwindow();
virtual void real_execute() = 0;
};

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Ewmh.cc,v 1.29 2003/07/04 01:03:40 rathnor Exp $
// $Id: Ewmh.cc,v 1.30 2003/07/28 15:06:33 rathnor Exp $
#include "Ewmh.hh"
@ -95,6 +95,10 @@ void Ewmh::initForScreen(BScreen &screen) {
}
void Ewmh::setupClient(WinClient &winclient) {
updateStrut(winclient);
}
void Ewmh::setupFrame(FluxboxWindow &win) {
Atom ret_type;
@ -123,8 +127,6 @@ void Ewmh::setupFrame(FluxboxWindow &win) {
XFree(data);
}
updateStrut(win);
}
void Ewmh::updateClientList(BScreen &screen) {
@ -260,34 +262,36 @@ void Ewmh::updateWorkspace(FluxboxWindow &win) {
}
// return true if we did handle the atom here
bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win) {
bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient) {
if (ce.message_type == m_net_wm_desktop) {
if (screen == 0)
return true;
// ce.data.l[0] = workspace number
// valid window and workspace number?
if (win == 0 ||
if (winclient == 0 || winclient->fbwindow() == 0 ||
static_cast<unsigned int>(ce.data.l[0]) >= screen->getCount())
return true;
screen->sendToWorkspace(ce.data.l[0], win, false);
screen->sendToWorkspace(ce.data.l[0], winclient->fbwindow(), false);
return true;
} else if (ce.message_type == m_net_wm_state) {
if (win == 0)
if (winclient == 0 || winclient->fbwindow() == 0)
return true;
FluxboxWindow &win = *winclient->fbwindow();
// ce.data.l[0] = the action (remove, add or toggle)
// ce.data.l[1] = the first property to alter
// ce.data.l[2] = second property to alter (can be zero)
if (ce.data.l[0] == STATE_REMOVE) {
setState(*win, ce.data.l[1], false);
setState(*win, ce.data.l[2], false);
setState(win, ce.data.l[1], false);
setState(win, ce.data.l[2], false);
} else if (ce.data.l[0] == STATE_ADD) {
setState(*win, ce.data.l[1], true);
setState(*win, ce.data.l[2], true);
setState(win, ce.data.l[1], true);
setState(win, ce.data.l[2], true);
} else if (ce.data.l[0] == STATE_TOGGLE) {
toggleState(*win, ce.data.l[1]);
toggleState(*win, ce.data.l[2]);
toggleState(win, ce.data.l[1]);
toggleState(win, ce.data.l[2]);
}
return true;
@ -330,20 +334,20 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, F
} else if (ce.message_type == m_net_active_window) {
// make sure we have a valid window
if (win == 0)
if (winclient == 0)
return true;
// ce.window = window to focus
win->setInputFocus();
winclient->focus();
return true;
} else if (ce.message_type == m_net_close_window) {
if (win == 0)
if (winclient == 0)
return true;
// ce.window = window to close (which in this case is the win argument)
win->close();
winclient->sendClose();
return true;
} else if (ce.message_type == m_net_moveresize_window) {
if (win == 0)
if (winclient == 0 && winclient->fbwindow())
return true;
// ce.data.l[0] = gravity and flags
// ce.data.l[1] = x
@ -351,7 +355,7 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, F
// ce.data.l[3] = width
// ce.data.l[4] = height
// TODO: gravity and flags
win->moveResize(ce.data.l[1], ce.data.l[2],
winclient->fbwindow()->moveResize(ce.data.l[1], ce.data.l[2],
ce.data.l[3], ce.data.l[4]);
return true;
}
@ -361,9 +365,9 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, F
}
bool Ewmh::propertyNotify(FluxboxWindow &win, Atom the_property) {
bool Ewmh::propertyNotify(WinClient &winclient, Atom the_property) {
if (the_property == m_net_wm_strut) {
updateStrut(win);
updateStrut(winclient);
return true;
}
@ -434,20 +438,20 @@ void Ewmh::toggleState(FluxboxWindow &win, Atom state) const {
}
void Ewmh::updateStrut(FluxboxWindow &win) {
void Ewmh::updateStrut(WinClient &winclient) {
Atom ret_type = 0;
int fmt = 0;
unsigned long nitems = 0, bytes_after = 0;
long *data = 0;
if (win.winClient().property(m_net_wm_strut, 0, 4, False, XA_CARDINAL,
if (winclient.property(m_net_wm_strut, 0, 4, False, XA_CARDINAL,
&ret_type, &fmt, &nitems, &bytes_after,
(unsigned char **) &data) && data) {
#ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<"): Strut: "<<data[0]<<", "<<data[1]<<", "<<
data[2]<<", "<<data[3]<<endl;
#endif // DEBUG
win.setStrut(win.screen().requestStrut(data[0], data[1], data[2], data[3]));
win.screen().updateAvailableWorkspaceArea();
winclient.setStrut(
winclient.screen().requestStrut(data[0], data[1], data[2], data[3]));
winclient.screen().updateAvailableWorkspaceArea();
}
}

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Ewmh.hh,v 1.9 2003/07/04 14:06:20 rathnor Exp $
// $Id: Ewmh.hh,v 1.10 2003/07/28 15:06:33 rathnor Exp $
#include "AtomHandler.hh"
@ -33,7 +33,7 @@ public:
~Ewmh();
void initForScreen(BScreen &screen);
void setupFrame(FluxboxWindow &win);
void setupClient(WinClient &winclient) {}
void setupClient(WinClient &winclient);
void updateClientList(BScreen &screen);
void updateWorkspaceNames(BScreen &screen);
@ -47,9 +47,9 @@ public:
bool checkClientMessage(const XClientMessageEvent &ce,
BScreen * screen, FluxboxWindow * const win);
BScreen * screen, WinClient * const winclient);
bool propertyNotify(FluxboxWindow &win, Atom the_property);
bool propertyNotify(WinClient &winclient, Atom the_property);
//ignore these ones
void updateFrameClose(FluxboxWindow &win) {}
void updateClientClose(WinClient &winclient) {}
@ -61,7 +61,7 @@ private:
void setState(FluxboxWindow &win, Atom state, bool value) const;
void toggleState(FluxboxWindow &win, Atom state) const;
void createAtoms();
void updateStrut(FluxboxWindow &win);
void updateStrut(WinClient &winclient);
// root window properties
Atom m_net_supported, m_net_client_list, m_net_client_list_stacking,

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Gnome.cc,v 1.30 2003/07/17 17:56:28 rathnor Exp $
// $Id: Gnome.cc,v 1.31 2003/07/28 15:06:33 rathnor Exp $
#include "Gnome.hh"
@ -278,22 +278,22 @@ void Gnome::updateHints(FluxboxWindow &win) {
}
bool Gnome::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win) {
bool Gnome::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient) {
if (ce.message_type == m_gnome_wm_win_workspace) {
#ifdef DEBUG
cerr<<__FILE__<<"("<<__LINE__<<"): Got workspace atom="<<ce.data.l[0]<<endl;
#endif//!DEBUG
if ( win !=0 && // the message sent to client window?
if ( winclient !=0 && // the message sent to client window?
ce.data.l[0] >= 0 &&
ce.data.l[0] < (signed)win->screen().getCount()) {
win->screen().changeWorkspaceID(ce.data.l[0]);
ce.data.l[0] < (signed)winclient->screen().getCount()) {
winclient->screen().changeWorkspaceID(ce.data.l[0]);
} else if (screen!=0 && //the message sent to root window?
ce.data.l[0] >= 0 &&
ce.data.l[0] < (signed)screen->getCount())
screen->changeWorkspaceID(ce.data.l[0]);
return true;
} else if (win == 0)
} else if (winclient == 0)
return false;
@ -308,15 +308,16 @@ bool Gnome::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen,
cerr<<"New members:"<<ce.data.l[1]<<endl;
#endif // DEBUG
//get new states
int flag = ce.data.l[0] & ce.data.l[1];
//don't update this when when we set new state
disableUpdate();
// convert to Fluxbox state
setState(win, flag);
// enable update of atom states
enableUpdate();
if (winclient && winclient->fbwindow()) {
//get new states
int flag = ce.data.l[0] & ce.data.l[1];
//don't update this when when we set new state
disableUpdate();
// convert to Fluxbox state
setState(winclient->fbwindow(), flag);
// enable update of atom states
enableUpdate();
}
} else if (ce.message_type == m_gnome_wm_win_hints) {
#ifdef DEBUG
cerr<<__FILE__<<"("<<__LINE__<<"): _WIN_HINTS"<<endl;
@ -327,7 +328,8 @@ bool Gnome::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen,
cerr<<__FILE__<<"("<<__LINE__<<"): _WIN_LAYER"<<endl;
#endif // DEBUG
setLayer(win, ce.data.l[0]);
if (winclient && winclient->fbwindow())
setLayer(winclient->fbwindow(), ce.data.l[0]);
} else
return false; //the gnome atom wasn't found or not supported

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Gnome.hh,v 1.9 2003/07/04 14:06:20 rathnor Exp $
// $Id: Gnome.hh,v 1.10 2003/07/28 15:06:33 rathnor Exp $
#ifndef GNOME_HH
#define GNOME_HH
@ -78,12 +78,12 @@ public:
void updateHints(FluxboxWindow &win);
void updateWorkspace(FluxboxWindow &win);
bool checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win);
bool checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient);
// ignore these ones
void updateFrameClose(FluxboxWindow &win) {}
void updateClientClose(WinClient &winclient) {}
bool propertyNotify(FluxboxWindow &win, Atom the_property) { return false; }
bool propertyNotify(WinClient &winclient, Atom the_property) { return false; }
private:
void setLayer(FluxboxWindow *win, int layer);

View file

@ -21,7 +21,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Remember.hh,v 1.11 2003/07/10 13:23:09 rathnor Exp $
// $Id: Remember.hh,v 1.12 2003/07/28 15:06:33 rathnor Exp $
/* Based on the original "Remember patch" by Xavier Brouckaert */
@ -188,9 +188,9 @@ public:
void updateLayer(FluxboxWindow &win) {}
bool checkClientMessage(const XClientMessageEvent &ce,
BScreen * screen, FluxboxWindow * const win) { return false; }
BScreen * screen, WinClient * const winclient) { return false; }
// ignore this
bool propertyNotify(FluxboxWindow &win, Atom the_property) { return false; }
bool propertyNotify(WinClient &winclient, Atom the_property) { return false; }
private:
// returns number of lines read

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Screen.cc,v 1.207 2003/07/25 10:03:55 rathnor Exp $
// $Id: Screen.cc,v 1.208 2003/07/28 15:06:33 rathnor Exp $
#include "Screen.hh"
@ -738,11 +738,11 @@ void BScreen::removeWindow(FluxboxWindow *win) {
void BScreen::removeClient(WinClient &client) {
WinClient *cyc = *cycling_window;
FluxboxWindow *focused = Fluxbox::instance()->getFocusedWindow();
WinClient *focused = Fluxbox::instance()->getFocusedWindow();
focused_list.remove(&client);
if (cyc == &client) {
cycling_window = focused_list.end();
} else if (focused && &focused->winClient() == &client) {
} else if (focused == &client) {
// if we are focused, then give our focus to our transient parent
// or revert normally
if (client.transientFor() && client.transientFor()->fbwindow())
@ -832,7 +832,11 @@ void BScreen::changeWorkspaceID(unsigned int id) {
return;
XSync(FbTk::App::instance()->display(), true);
FluxboxWindow *focused = Fluxbox::instance()->getFocusedWindow();
WinClient *focused_client = Fluxbox::instance()->getFocusedWindow();
FluxboxWindow *focused = 0;
if (focused_client)
focused = focused_client->fbwindow();
#ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<"): focused = "<<focused<<endl;
#endif // DEBUG
@ -882,8 +886,11 @@ void BScreen::sendToWorkspace(unsigned int id, FluxboxWindow *win, bool changeWS
if (! m_current_workspace || id >= m_workspaces_list.size())
return;
if (!win)
win = Fluxbox::instance()->getFocusedWindow();
if (!win) {
WinClient *client = Fluxbox::instance()->getFocusedWindow();
if (client)
win = client->fbwindow();
}
if (id != currentWorkspace()->workspaceID()) {
XSync(FbTk::App::instance()->display(), True);
@ -930,7 +937,7 @@ void BScreen::addNetizen(Window win) {
}
Window f = ((Fluxbox::instance()->getFocusedWindow()) ?
Fluxbox::instance()->getFocusedWindow()->clientWindow() : None);
Fluxbox::instance()->getFocusedWindow()->window() : None);
net->sendWindowFocus(f);
}
@ -970,7 +977,7 @@ void BScreen::updateNetizenWindowFocus() {
Netizens::iterator it = m_netizen_list.begin();
Netizens::iterator it_end = m_netizen_list.end();
Window f = ((Fluxbox::instance()->getFocusedWindow()) ?
Fluxbox::instance()->getFocusedWindow()->clientWindow() : None);
Fluxbox::instance()->getFocusedWindow()->window() : None);
for (; it != it_end; ++it) {
(*it)->sendWindowFocus(f);
}
@ -1075,8 +1082,6 @@ FluxboxWindow *BScreen::createWindow(Window client) {
Fluxbox::instance()->attachSignals(*win);
}
Fluxbox::instance()->saveWindowSearch(client, win);
// we also need to check if another window expects this window to the left
// and if so, then join it.
FluxboxWindow *otherwin = 0;
@ -1108,7 +1113,6 @@ FluxboxWindow *BScreen::createWindow(WinClient &client) {
// don't add to focused_list, as it should already be in there (since the
// WinClient already exists).
Fluxbox::instance()->saveWindowSearch(client.window(), win);
Fluxbox::instance()->attachSignals(*win);
// winclient actions should have been setup when the WinClient was created
if (win->workspaceNumber() == currentWorkspaceID() || win->isStuck()) {
@ -1213,16 +1217,8 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id,
void BScreen::nextFocus(int opts) {
bool have_focused = false;
FluxboxWindow *focused = Fluxbox::instance()->getFocusedWindow();
const int num_windows = currentWorkspace()->numberOfWindows();
if (focused != 0) {
if (focused->screen().screenNumber() == screenNumber()) {
have_focused = true;
}
}
if (num_windows >= 1) {
if (!(opts & CYCLELINEAR)) {
if (!cycling_focus) {
@ -1272,16 +1268,30 @@ void BScreen::nextFocus(int opts) {
}
cycling_window = it;
} else { // not stacked cycling
// I really don't like this, but evidently some people use it(!)
Workspace *wksp = currentWorkspace();
Workspace::Windows &wins = wksp->windowList();
Workspace::Windows::iterator it = wins.begin();
FluxboxWindow *focused_group = 0;
// start from the focused window
bool have_focused = false;
WinClient *focused = Fluxbox::instance()->getFocusedWindow();
if (focused != 0) {
if (focused->screen().screenNumber() == screenNumber()) {
have_focused = true;
focused_group = focused->fbwindow();
}
}
if (!have_focused) {
focused = (*it);
focused_group = (*it);
} else {
for (; (*it) != focused; ++it) //get focused window iterator
//get focused window iterator
for (; it != wins.end() && (*it) != focused_group; ++it)
continue;
}
do {
++it;
if (it == wins.end())
@ -1289,8 +1299,8 @@ void BScreen::nextFocus(int opts) {
// see if the window should be skipped
if (! (doSkipWindow((*it)->winClient(), opts) || !(*it)->setInputFocus()) )
break;
} while ((*it) != focused);
if ((*it) != focused && it != wins.end())
} while ((*it) != focused_group);
if ((*it) != focused_group && it != wins.end())
(*it)->raise();
}
@ -1300,16 +1310,8 @@ void BScreen::nextFocus(int opts) {
void BScreen::prevFocus(int opts) {
bool have_focused = false;
FluxboxWindow *focused;
int num_windows = currentWorkspace()->numberOfWindows();
if ((focused = Fluxbox::instance()->getFocusedWindow())) {
if (focused->screen().screenNumber() == screenNumber()) {
have_focused = true;
}
}
if (num_windows >= 1) {
if (!(opts & CYCLELINEAR)) {
if (!cycling_focus) {
@ -1366,13 +1368,25 @@ void BScreen::prevFocus(int opts) {
Workspace::Windows &wins = wksp->windowList();
Workspace::Windows::iterator it = wins.begin();
FluxboxWindow *focused_group = 0;
// start from the focused window
bool have_focused = false;
WinClient *focused = Fluxbox::instance()->getFocusedWindow();
if (focused != 0) {
if (focused->screen().screenNumber() == screenNumber()) {
have_focused = true;
focused_group = focused->fbwindow();
}
}
if (!have_focused) {
focused = (*it);
focused_group = (*it);
} else {
for (; (*it) != focused; ++it) //get focused window iterator
//get focused window iterator
for (; it != wins.end() && (*it) != focused_group; ++it)
continue;
}
do {
if (it == wins.begin())
it = wins.end();
@ -1380,9 +1394,9 @@ void BScreen::prevFocus(int opts) {
// see if the window should be skipped
if (! (doSkipWindow((*it)->winClient(), opts) || !(*it)->setInputFocus()) )
break;
} while ((*it) != focused);
} while ((*it) != focused_group);
if ((*it) != focused && it != wins.end())
if ((*it) != focused_group && it != wins.end())
(*it)->raise();
}
}
@ -2150,7 +2164,7 @@ bool BScreen::doSkipWindow(const WinClient &winclient, int opts) {
return (!win ||
(opts & CYCLESKIPSTUCK) != 0 && win->isStuck() || // skip if stuck
// skip if not active client (i.e. only visit each fbwin once)
(opts & CYCLEGROUPS) != 0 && win->winClient() != winclient.window() ||
(opts & CYCLEGROUPS) != 0 && win->winClient().window() != winclient.window() ||
(opts & CYCLESKIPSHADED) != 0 && win->isShaded() // skip if shaded
);
}
@ -2229,15 +2243,6 @@ WinClient *BScreen::getLastFocusedWindow(int workspace) {
return 0;
}
/**
Access and clear the auto-group window
*/
FluxboxWindow* BScreen::useAutoGroupWindow() {
Window w = auto_group_window;
auto_group_window = 0;
return w ? Fluxbox::instance()->searchWindow(w) : 0;
}
void BScreen::updateSize() {
rootWindow().updateGeometry();
@ -2263,16 +2268,19 @@ FluxboxWindow *BScreen::findGroupLeft(WinClient &winclient) {
if (w == None)
return 0;
FluxboxWindow *fbwin = Fluxbox::instance()->searchWindow(w);
WinClient *have_client = Fluxbox::instance()->searchWindow(w);
if (!fbwin) {
if (!have_client) {
// not found, add it to expecting
m_expecting_groups[w] = &winclient;
} else if (&fbwin->screen() != &winclient.screen())
} else if (&have_client->screen() != &winclient.screen())
// something is not consistent
return 0;
return fbwin;
if (have_client)
return have_client->fbwindow();
else
return 0;
}
FluxboxWindow *BScreen::findGroupRight(WinClient &winclient) {

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Screen.hh,v 1.116 2003/07/20 08:12:36 rathnor Exp $
// $Id: Screen.hh,v 1.117 2003/07/28 15:06:34 rathnor Exp $
#ifndef SCREEN_HH
#define SCREEN_HH
@ -258,8 +258,6 @@ public:
void setLayer(FbTk::XLayerItem &item, int layernum);
// remove? no, items are never removed from their layer until they die
FluxboxWindow* useAutoGroupWindow();
/// updates root window size and resizes/reconfigures screen clients
/// that depends on screen size (slit)
/// (and maximized windows?)
@ -391,8 +389,6 @@ private:
WorkspaceNames m_workspace_names;
Workspaces m_workspaces_list;
Window auto_group_window;
std::auto_ptr<FbWinFrameTheme> m_windowtheme;
std::auto_ptr<WinButtonTheme> m_winbutton_theme;
std::auto_ptr<MenuTheme> m_menutheme;

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Toolbar.cc,v 1.103 2003/07/25 10:03:55 rathnor Exp $
// $Id: Toolbar.cc,v 1.104 2003/07/28 15:06:34 rathnor Exp $
#include "Toolbar.hh"
@ -31,6 +31,7 @@
#include "fluxbox.hh"
#include "Screen.hh"
#include "Window.hh"
#include "WinClient.hh"
#include "Workspace.hh"
#include "ImageControl.hh"
#include "ToolbarTheme.hh"
@ -880,21 +881,23 @@ void Toolbar::checkClock(bool redraw, bool date) {
void Toolbar::redrawWindowLabel(bool redraw) {
if (Fluxbox::instance()->getFocusedWindow()) {
WinClient *winclient = Fluxbox::instance()->getFocusedWindow();
if (winclient) {
if (redraw)
frame.window_label.clear();
FluxboxWindow *foc = Fluxbox::instance()->getFocusedWindow();
const std::string &title = winclient->getTitle();
// don't draw focused window if it's not on the same screen
if (&foc->screen() != &screen() || foc->title().size() == 0)
if (&winclient->screen() != &screen() || title.size() == 0)
return;
unsigned int newlen = foc->title().size();
unsigned int newlen = title.size();
int dx = FbTk::doAlignment(frame.window_label_w, frame.bevel_w*2,
m_theme.justify(),
m_theme.font(),
foc->title().c_str(),
foc->title().size(), newlen);
title.c_str(),
title.size(), newlen);
int dy = 1 + m_theme.font().ascent();
if (m_theme.font().isRotated()) {
@ -907,7 +910,7 @@ void Toolbar::redrawWindowLabel(bool redraw) {
m_theme.font().drawText(frame.window_label.window(),
screen().screenNumber(),
m_theme.windowTextGC(),
foc->title().c_str(), newlen,
title.c_str(), newlen,
dx, dy);
} else
frame.window_label.clear();
@ -961,8 +964,9 @@ void Toolbar::edit() {
frame.workspace_label.clear();
Fluxbox * const fluxbox = Fluxbox::instance();
if (fluxbox->getFocusedWindow()) //disable focus on current focused window
fluxbox->getFocusedWindow()->setFocusFlag(false);
WinClient *winclient = fluxbox->getFocusedWindow();
if (winclient && winclient->fbwindow()) //disable focus on current focused window
winclient->fbwindow()->setFocusFlag(false);
frame.workspace_label.drawRectangle(screen().winFrameTheme().labelTextFocusGC(),
frame.workspace_label_w / 2, 0, 1,
@ -1116,10 +1120,9 @@ void Toolbar::keyPressEvent(XKeyEvent &ke) {
Fluxbox * const fluxbox = Fluxbox::instance();
if (fluxbox->getFocusedWindow()) {
fluxbox->getFocusedWindow()->setInputFocus();
fluxbox->getFocusedWindow()->setFocusFlag(true);
fluxbox->getFocusedWindow()->focus();
} else
XSetInputFocus(FbTk::App::instance()->display(), PointerRoot, None, CurrentTime);
fluxbox->revertFocus(screen());
if (ks == XK_Return) //change workspace name if keypress = Return
screen().currentWorkspace()->setName(m_new_workspace_name.c_str());

View file

@ -20,7 +20,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: ToolbarHandler.hh,v 1.6 2003/07/04 14:06:20 rathnor Exp $
// $Id: ToolbarHandler.hh,v 1.7 2003/07/28 15:06:34 rathnor Exp $
#ifndef TOOLBARHANDLER_HH
#define TOOLBARHANDLER_HH
@ -74,9 +74,9 @@ public:
void updateLayer(FluxboxWindow &win) {}
bool checkClientMessage(const XClientMessageEvent &ce,
BScreen * screen, FluxboxWindow * const win) { return false; }
BScreen * screen, WinClient * const winclient) { return false; }
bool propertyNotify(FluxboxWindow &win, Atom the_atom) { return false; }
bool propertyNotify(WinClient &winclient, Atom the_atom) { return false; }
inline FbTk::Menu &getModeMenu() { return m_modemenu; }
inline const FbTk::Menu &getModeMenu() const { return m_modemenu; }

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: WinClient.cc,v 1.19 2003/07/21 15:26:56 rathnor Exp $
// $Id: WinClient.cc,v 1.20 2003/07/28 15:06:34 rathnor Exp $
#include "WinClient.hh"
@ -52,9 +52,10 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb
initial_state(0),
normal_hint_flags(0),
wm_hint_flags(0),
send_focus_message(false),
m_win(fbwin),
m_modal(0),
send_focus_message(false),
closable(false),
m_title(""), m_icon_title(""),
m_class_name(""), m_instance_name(""),
m_blackbox_hint(0),
@ -68,6 +69,10 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb
updateWMClassHint();
updateTitle();
updateIconTitle();
Fluxbox::instance()->saveWindowSearch(win, this);
if (window_group != None)
Fluxbox::instance()->saveGroupSearch(window_group, this);
}
WinClient::~WinClient() {
@ -77,6 +82,8 @@ WinClient::~WinClient() {
FbTk::EventManager::instance()->remove(window());
clearStrut();
if (m_win != 0)
m_win->removeClient(*this);
@ -160,22 +167,27 @@ bool WinClient::sendFocus() {
return true;
}
void WinClient::sendClose() {
Display *disp = FbTk::App::instance()->display();
// fill in XClientMessage structure for delete message
XEvent ce;
ce.xclient.type = ClientMessage;
ce.xclient.message_type = FbAtoms::instance()->getWMProtocolsAtom();
ce.xclient.display = disp;
ce.xclient.window = 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(disp, window(), false, NoEventMask, &ce);
void WinClient::sendClose(bool forceful) {
if (forceful || !isClosable())
XKillClient(FbTk::App::instance()->display(), window());
else {
// send WM_DELETE message
Display *disp = FbTk::App::instance()->display();
// fill in XClientMessage structure for delete message
XEvent ce;
ce.xclient.type = ClientMessage;
ce.xclient.message_type = FbAtoms::instance()->getWMProtocolsAtom();
ce.xclient.display = disp;
ce.xclient.window = 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(disp, window(), false, NoEventMask, &ce);
}
}
void WinClient::reparent(Window win, int x, int y) {
@ -251,9 +263,8 @@ void WinClient::updateTransientInfo() {
return;
}
FluxboxWindow *transient_win = Fluxbox::instance()->searchWindow(win);
if (transient_win)
transient_for = transient_win->findClient(win);
transient_for = Fluxbox::instance()->searchWindow(win);
// make sure we don't have deadlock loop in transient chain
for (WinClient *w = this; w != 0; w = w->transient_for) {
@ -528,3 +539,60 @@ void WinClient::removeModal() {
if (transient_for)
transient_for->removeModal();
}
bool WinClient::validateClient() const {
Display *display = FbTk::App::instance()->display();
XSync(display, false);
XEvent e;
if (( XCheckTypedWindowEvent(display, window(), DestroyNotify, &e) ||
XCheckTypedWindowEvent(display, window(), UnmapNotify, &e))
&& XPutBackEvent(display, &e)) {
Fluxbox::instance()->ungrab();
return false;
}
return true;
}
void WinClient::setStrut(Strut *strut) {
clearStrut();
m_strut = strut;
}
void WinClient::clearStrut() {
if (m_strut != 0) {
screen().clearStrut(m_strut);
m_strut = 0;
}
}
bool WinClient::focus() {
if (m_win == 0)
return false;
else
return m_win->setCurrentClient(*this, true);
}
void WinClient::getWMProtocols() {
Atom *proto = 0;
int num_return = 0;
FbAtoms *fbatoms = FbAtoms::instance();
if (XGetWMProtocols(FbTk::App::instance()->display(), window(), &proto, &num_return)) {
for (int i = 0; i < num_return; ++i) {
if (proto[i] == fbatoms->getWMDeleteAtom())
closable = true;
else if (proto[i] == fbatoms->getWMTakeFocusAtom())
send_focus_message = true;
else if (proto[i] == fbatoms->getFluxboxStructureMessagesAtom())
screen().addNetizen(window());
}
XFree(proto);
} else {
cerr<<"Warning: Failed to read WM Protocols. "<<endl;
}
}

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: WinClient.hh,v 1.10 2003/07/21 15:26:56 rathnor Exp $
// $Id: WinClient.hh,v 1.11 2003/07/28 15:06:34 rathnor Exp $
#ifndef WINCLIENT_HH
#define WINCLIENT_HH
@ -32,6 +32,7 @@
#include <string>
class BScreen;
class Strut;
/// Holds client window info
class WinClient:public FbTk::FbWindow {
@ -44,7 +45,8 @@ public:
void updateRect(int x, int y, unsigned int width, unsigned int height);
bool sendFocus(); // returns whether we sent a message or not
// i.e. whether we assume the focus will get taken
void sendClose();
void sendClose(bool forceful = false);
inline bool isClosable() const { return closable; }
void reparent(Window win, int x, int y);
bool getAttrib(XWindowAttributes &attr) const;
bool getWMName(XTextProperty &textprop) const;
@ -55,8 +57,9 @@ public:
const std::string &getWMClassClass() const;
/// updates from wm class hints
void updateWMClassHint();
void getWMProtocols();
inline const std::string getTitle() const { return m_title; }
inline const std::string &getTitle() const { return m_title; }
void updateTitle();
void updateIconTitle();
BScreen &screen() { return m_screen; }
@ -80,6 +83,11 @@ public:
return (m_win == &win);
}
void setStrut(Strut *strut);
void clearStrut();
bool focus(); // calls Window->setCurrentClient to give focus to this client
const std::string &title() const { return m_title; }
const std::string &iconTitle() const { return m_icon_title; }
const FluxboxWindow *fbwindow() const { return m_win; }
@ -98,6 +106,9 @@ public:
void setGroupLeftWindow(Window win);
bool hasGroupLeftWindow() const;
// does this client have a pending unmap or destroy event?
bool validateClient() const;
/**
!! TODO !!
remove or move these to private
@ -114,7 +125,6 @@ public:
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;
bool send_focus_message;
// 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
@ -145,6 +155,7 @@ private:
// number of transients which we are modal for
// or indicates that we are modal if don't have any transients
int m_modal;
bool send_focus_message, closable;
std::string m_title, m_icon_title;
std::string m_class_name, m_instance_name;
@ -157,6 +168,8 @@ private:
WinClientSubj m_diesig;
BScreen &m_screen;
Strut *m_strut;
};
#endif // WINCLIENT_HH

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Window.cc,v 1.212 2003/07/28 12:49:18 fluxgen Exp $
// $Id: Window.cc,v 1.213 2003/07/28 15:06:34 rathnor Exp $
#include "Window.hh"
@ -262,7 +262,6 @@ FluxboxWindow::FluxboxWindow(WinClient &client, BScreen &scr, FbWinFrameTheme &t
m_old_decoration(DECOR_NORMAL),
m_client(&client),
m_frame(new FbWinFrame(tm, scr.imageControl(), scr.screenNumber(), 0, 0, 100, 100)),
m_strut(0),
m_layeritem(m_frame->window(), layer),
m_layernum(layer.getLayerNum()),
m_parent(scr.rootWindow()) {
@ -279,15 +278,13 @@ FluxboxWindow::~FluxboxWindow() {
cerr<<__FILE__<<"("<<__LINE__<<"): m_labelbuttons.size = "<<m_labelbuttons.size()<<endl;
#endif // DEBUG
clearStrut();
if (moving || resizing || m_attaching_tab) {
screen().hideGeometry();
XUngrabPointer(display, CurrentTime);
}
// no longer a valid window to do stuff with
Fluxbox::instance()->removeWindowSearch(frame().window().window());
Fluxbox::instance()->removeWindowSearchGroup(frame().window().window());
Client2ButtonMap::iterator it = m_labelbuttons.begin();
Client2ButtonMap::iterator it_end = m_labelbuttons.end();
@ -421,20 +418,15 @@ void FluxboxWindow::init() {
functions.resize = functions.move = functions.iconify = functions.maximize = true;
functions.close = decorations.close = false;
decorations.close = false;
functions.close = m_client->isClosable();
if (m_client->getBlackboxHint() != 0)
getBlackboxHints();
else
getMWMHints();
// get size, aspect, minimum/maximum size and other hints set
// by the client
getWMProtocols();
if (m_client->window_group != None)
Fluxbox::instance()->saveGroupSearch(m_client->window_group, this);
//!!
// fetch client size and placement
XWindowAttributes wattrib;
@ -448,8 +440,6 @@ void FluxboxWindow::init() {
m_client->old_bw = wattrib.border_width;
m_client->x = wattrib.x; m_client->y = wattrib.y;
fluxbox.saveWindowSearch(frame().window().window(), this);
m_timer.setTimeout(fluxbox.getAutoRaiseDelay());
m_timer.fireOnce(true);
@ -458,6 +448,8 @@ void FluxboxWindow::init() {
}
m_managed = true; //this window is managed
Fluxbox::instance()->saveWindowSearchGroup(frame().window().window(), this);
// update transient infomation
m_client->updateTransientInfo();
@ -603,13 +595,11 @@ void FluxboxWindow::attachClient(WinClient &client) {
if (client.fbwindow() != 0) {
FluxboxWindow *old_win = client.fbwindow(); // store old window
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) {
// setup eventhandlers for client
fb->saveWindowSearch((*client_it)->window(), this);
evm.add(*this, (*client_it)->window());
// reparent window to this
@ -671,7 +661,6 @@ void FluxboxWindow::attachClient(WinClient &client) {
client.m_win = this;
Fluxbox::instance()->saveWindowSearch(client.window(), this);
client.saveBlackboxAttribs(m_blackbox_attrib);
m_clientlist.push_back(&client);
}
@ -993,30 +982,6 @@ void FluxboxWindow::updateIconNameFromClient() {
}
void FluxboxWindow::getWMProtocols() {
Atom *proto = 0;
int num_return = 0;
FbAtoms *fbatoms = FbAtoms::instance();
if (XGetWMProtocols(display, m_client->window(), &proto, &num_return)) {
for (int i = 0; i < num_return; ++i) {
if (proto[i] == fbatoms->getWMDeleteAtom())
functions.close = true;
else if (proto[i] == fbatoms->getWMTakeFocusAtom())
m_client->send_focus_message = true;
else if (proto[i] == fbatoms->getFluxboxStructureMessagesAtom())
screen().addNetizen(m_client->window());
}
XFree(proto);
} else {
cerr<<"Warning: Failed to read WM Protocols. "<<endl;
}
}
void FluxboxWindow::getMWMHints() {
const WinClient::MwmHints *hint = m_client->getMwmHint();
@ -1185,7 +1150,7 @@ bool FluxboxWindow::setInputFocus() {
}
}
if (! validateClient())
if (! m_client->validateClient())
return false;
if (!m_client->transients.empty() && m_client->isModal()) {
@ -1256,7 +1221,9 @@ void FluxboxWindow::iconify() {
(*it)->fbwindow()->iconify();
}
}
if (Fluxbox::instance()->getFocusedWindow() == this)
WinClient *focused_client = Fluxbox::instance()->getFocusedWindow();
if (focused_client && focused_client->fbwindow() == this)
Fluxbox::instance()->revertFocus(screen());
}
@ -1318,16 +1285,6 @@ void FluxboxWindow::deiconify(bool reassoc, bool do_raise) {
raise();
}
/**
Send close request to client window
*/
void FluxboxWindow::close() {
#ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<")"<<endl;
#endif // DEBUG
m_client->sendClose();
}
/**
Set window in withdrawn state
*/
@ -1703,7 +1660,7 @@ void FluxboxWindow::installColormap(bool install) {
Fluxbox *fluxbox = Fluxbox::instance();
fluxbox->grab();
if (! validateClient())
if (! m_client->validateClient())
return;
int i = 0, ncmap = 0;
@ -2151,13 +2108,13 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) {
if (!ne.override_redirect && isVisible()) {
Fluxbox *fluxbox = Fluxbox::instance();
fluxbox->grab();
if (! validateClient())
if (! client->validateClient())
return;
setState(NormalState);
if (client->isTransient() || screen().doFocusNew()) {
setInputFocus();
setCurrentClient(*client, true);
}
else
setFocusFlag(false);
@ -2197,6 +2154,8 @@ void FluxboxWindow::unmapNotifyEvent(XUnmapEvent &ue) {
/**
Checks if event is for m_client->window.
If it isn't, we leave it until the window is unmapped, if it is,
we just hide it for now.
*/
void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) {
if (de.window == m_client->window()) {
@ -2295,7 +2254,7 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
default:
if (atom == FbAtoms::instance()->getWMProtocolsAtom()) {
getWMProtocols();
m_client->getWMProtocols();
//!!TODO check this area
// reset window actions
setupWindow();
@ -2771,18 +2730,6 @@ void FluxboxWindow::toggleDecoration() {
}
}
void FluxboxWindow::setStrut(Strut *strut) {
clearStrut();
m_strut = strut;
}
void FluxboxWindow::clearStrut() {
if (m_strut != 0) {
screen().clearStrut(m_strut);
m_strut = 0;
}
}
unsigned int FluxboxWindow::decorationMask() const {
unsigned int ret = 0;
if (decorations.titlebar)
@ -2825,21 +2772,6 @@ void FluxboxWindow::setDecorationMask(unsigned int mask) {
applyDecorations();
}
bool FluxboxWindow::validateClient() {
XSync(display, false);
XEvent e;
if (!m_client ||
( XCheckTypedWindowEvent(display, m_client->window(), DestroyNotify, &e) ||
XCheckTypedWindowEvent(display, m_client->window(), UnmapNotify, &e))
&& XPutBackEvent(display, &e)) {
Fluxbox::instance()->ungrab();
return false;
}
return true;
}
void FluxboxWindow::startMoving(Window win) {
moving = true;
Fluxbox *fluxbox = Fluxbox::instance();
@ -3096,7 +3028,12 @@ void FluxboxWindow::attachTo(int x, int y) {
parent().window(),
x, y, &dest_x, &dest_y, &child)) {
// search for a fluxboxwindow
FluxboxWindow *attach_to_win = Fluxbox::instance()->searchWindow(child);
WinClient *client = Fluxbox::instance()->searchWindow(child);
FluxboxWindow *attach_to_win = 0;
if (client)
attach_to_win = client->fbwindow();
cerr<<"client = "<<client<<", child = "<<hex<<child<<dec<<", fbwin = "<<attach_to_win<<endl;
if (attach_to_win != this &&
attach_to_win != 0) {
@ -3468,6 +3405,10 @@ void FluxboxWindow::removeExtraMenu(FbTk::Menu *menu) {
setupWindow();
}
void FluxboxWindow::close() {
if (m_client)
m_client->sendClose(false);
}
void FluxboxWindow::setupWindow() {
// sets up our window

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Window.hh,v 1.88 2003/07/28 12:42:32 fluxgen Exp $
// $Id: Window.hh,v 1.89 2003/07/28 15:06:35 rathnor Exp $
#ifndef WINDOW_HH
#define WINDOW_HH
@ -44,7 +44,6 @@
class WinClient;
class FbWinFrameTheme;
class BScreen;
class Strut;
class TextButton;
class FbWinFrame;
@ -168,7 +167,6 @@ public:
void moveClientLeft();
void moveClientRight();
bool validateClient();
bool setInputFocus();
void raiseAndFocus() { raise(); setInputFocus(); }
void setFocusFlag(bool flag);
@ -178,7 +176,7 @@ public:
void hide();
void iconify();
void deiconify(bool = true, bool = true);
/// destroy this window
/// close current client
void close();
/// set the window in withdrawn state
void withdraw();
@ -247,9 +245,6 @@ public:
void toggleDecoration();
void setStrut(Strut *strut);
void clearStrut();
unsigned int decorationMask() const;
void setDecorationMask(unsigned int mask);
@ -382,7 +377,6 @@ private:
void updateTitleFromClient();
/// gets icon name from client window
void updateIconNameFromClient();
void getWMProtocols();
void getMWMHints();
void getBlackboxHints();
void saveBlackboxAttribs();
@ -457,8 +451,6 @@ private:
m_last_button_y; ///< last known y position of the mouse button
std::auto_ptr<FbWinFrame> m_frame;
Strut *m_strut;
FbTk::XLayerItem m_layeritem;
int m_layernum;

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Workspace.cc,v 1.77 2003/07/25 10:03:55 rathnor Exp $
// $Id: Workspace.cc,v 1.78 2003/07/28 15:06:35 rathnor Exp $
#include "Workspace.hh"
@ -276,7 +276,7 @@ void Workspace::reconfigure() {
Windows::iterator it = m_windowlist.begin();
Windows::iterator it_end = m_windowlist.end();
for (; it != it_end; ++it) {
if ((*it)->validateClient())
if ((*it)->winClient().validateClient())
(*it)->reconfigure();
}
}

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: fluxbox.cc,v 1.175 2003/07/27 13:53:34 fluxgen Exp $
// $Id: fluxbox.cc,v 1.176 2003/07/28 15:06:35 rathnor Exp $
#include "fluxbox.hh"
@ -757,9 +757,9 @@ void Fluxbox::handleEvent(XEvent * const e) {
handleButtonEvent(e->xbutton);
break;
case ConfigureRequest: {
FluxboxWindow *win = (FluxboxWindow *) 0;
WinClient *winclient = (WinClient *) 0;
if ((win = searchWindow(e->xconfigurerequest.window))) {
if ((winclient = searchWindow(e->xconfigurerequest.window))) {
// already handled in FluxboxWindow::handleEvent
} else {
grab();
@ -836,9 +836,10 @@ void Fluxbox::handleEvent(XEvent * const e) {
cerr<<"MapRequest for 0x"<<hex<<e->xmaprequest.window<<dec<<endl;
#endif // DEBUG
FluxboxWindow *win = searchWindow(e->xmaprequest.window);
WinClient *winclient = searchWindow(e->xmaprequest.window);
FluxboxWindow *win = 0;
if (! win) {
if (! winclient) {
//!!! TODO
BScreen *scr = searchScreen(e->xmaprequest.parent);
if (scr != 0)
@ -846,7 +847,10 @@ void Fluxbox::handleEvent(XEvent * const e) {
else
cerr<<"Fluxbox Warning! Could not find screen to map window on!"<<endl;
} else {
win = winclient->fbwindow();
}
// we don't handle MapRequest in FluxboxWindow::handleEvent
if (win)
win->mapRequestEvent(e->xmaprequest);
@ -854,9 +858,6 @@ void Fluxbox::handleEvent(XEvent * const e) {
break;
case MapNotify: {
// handled directly in FluxboxWindow::handleEvent
FluxboxWindow *win = searchWindow(e->xmap.window);
if (win)
win->mapNotifyEvent(e->xmap);
} break;
case UnmapNotify:
handleUnmapNotify(e->xunmap);
@ -873,20 +874,16 @@ void Fluxbox::handleEvent(XEvent * const e) {
case CreateNotify:
break;
case DestroyNotify: {
FluxboxWindow *win = searchWindow(e->xdestroywindow.window);
if (win != 0) {
WinClient *client = win->findClient(e->xdestroywindow.window);
if (client != 0) {
WinClient *winclient = searchWindow(e->xdestroywindow.window);
if (winclient != 0) {
FluxboxWindow *win = winclient->fbwindow();
if (win)
win->destroyNotifyEvent(e->xdestroywindow);
delete client;
delete winclient;
if (win->numClients() == 0 ||
&win->winClient() == client && win->numClients() == 1) {
delete win;
}
}
if (win && win->numClients() == 0)
delete win;
}
}
@ -895,13 +892,13 @@ void Fluxbox::handleEvent(XEvent * const e) {
break;
case PropertyNotify: {
m_last_time = e->xproperty.time;
FluxboxWindow *win = searchWindow(e->xproperty.window);
if (win == 0)
WinClient *winclient = searchWindow(e->xproperty.window);
if (winclient == 0)
break;
// most of them are handled in FluxboxWindow::handleEvent
// but some special cases like ewmh propertys needs to be checked
for (size_t i=0; i<m_atomhandler.size(); ++i) {
if (m_atomhandler[i]->propertyNotify(*win, e->xproperty.atom))
if (m_atomhandler[i]->propertyNotify(*winclient, e->xproperty.atom))
break;
}
} break;
@ -942,10 +939,9 @@ void Fluxbox::handleEvent(XEvent * const e) {
e->xfocus.detail == NotifyPointer)
break;
FluxboxWindow *win = searchWindow(e->xfocus.window);
if (win && ! win->isFocused()) {
setFocusedWindow(win);
}
WinClient *winclient = searchWindow(e->xfocus.window);
if (winclient && !(m_focused_window == winclient))
setFocusedWindow(winclient);
} break;
case FocusOut:{
@ -953,8 +949,8 @@ void Fluxbox::handleEvent(XEvent * const e) {
if (e->xfocus.mode == NotifyUngrab ||
e->xfocus.detail == NotifyPointer)
break;
FluxboxWindow *win = searchWindow(e->xfocus.window);
if (win == 0 && FbTk::Menu::focused() == 0) {
WinClient *winclient = searchWindow(e->xfocus.window);
if (winclient == 0 && FbTk::Menu::focused() == 0) {
#ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl;
#endif // DEBUG
@ -1079,25 +1075,29 @@ void Fluxbox::handleButtonEvent(XButtonEvent &be) {
void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) {
FluxboxWindow *win = 0;
WinClient *winclient = 0;
BScreen *screen = searchScreen(ue.event);
if ( ue.event != ue.window && (screen != 0 || !ue.send_event))
return;
if ((win = searchWindow(ue.window)) != 0) {
WinClient *client = win->findClient(ue.window);
if ((winclient = searchWindow(ue.window)) != 0) {
if (client != 0) {
if (winclient != 0) {
FluxboxWindow *win = winclient->fbwindow();
win->unmapNotifyEvent(ue);
client = 0; // it's invalid now when win destroyed the client
if (!win) {
delete winclient;
return;
}
if (win == m_focused_window)
revertFocus(win->screen());
// this should delete client and adjust m_focused_window if necessary
win->unmapNotifyEvent(ue);
// finaly destroy window if empty
winclient = 0; // it's invalid now when win destroyed the client
// finally destroy window if empty
if (win->numClients() == 0) {
delete win;
win = 0;
@ -1120,14 +1120,14 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
return;
if (ce.message_type == m_fbatoms->getWMChangeStateAtom()) {
FluxboxWindow *win = searchWindow(ce.window);
if (! win || ! win->validateClient())
WinClient *winclient = searchWindow(ce.window);
if (! winclient || !winclient->fbwindow() || ! winclient->validateClient())
return;
if (ce.data.l[0] == IconicState)
win->iconify();
winclient->fbwindow()->iconify();
if (ce.data.l[0] == NormalState)
win->deiconify();
winclient->fbwindow()->deiconify();
} else if (ce.message_type == m_fbatoms->getFluxboxChangeWorkspaceAtom()) {
BScreen *screen = searchScreen(ce.window);
@ -1136,9 +1136,12 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
screen->changeWorkspaceID(ce.data.l[0]);
} else if (ce.message_type == m_fbatoms->getFluxboxChangeWindowFocusAtom()) {
FluxboxWindow *win = searchWindow(ce.window);
if (win && win->isVisible())
win->setInputFocus();
WinClient *winclient = searchWindow(ce.window);
if (winclient) {
FluxboxWindow *win = winclient->fbwindow();
if (win && win->isVisible())
win->setCurrentClient(*winclient, true);
}
} else if (ce.message_type == m_fbatoms->getFluxboxCycleWindowFocusAtom()) {
BScreen *screen = searchScreen(ce.window);
@ -1147,12 +1150,11 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
screen->prevFocus();
else
screen->nextFocus();
}
}
} else if (ce.message_type == m_fbatoms->getFluxboxChangeAttributesAtom()) {
FluxboxWindow *win = searchWindow(ce.window);
if (win && win->validateClient()) {
WinClient *winclient = searchWindow(ce.window);
FluxboxWindow *win = 0;
if (winclient && (win = winclient->fbwindow()) && winclient->validateClient()) {
FluxboxWindow::BlackboxHints net;
net.flags = ce.data.l[0];
net.attrib = ce.data.l[1];
@ -1162,11 +1164,13 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
win->changeBlackboxHints(net);
}
} else {
FluxboxWindow *win = searchWindow(ce.window);
WinClient *winclient = searchWindow(ce.window);
BScreen *screen = searchScreen(ce.window);
for (size_t i=0; i<m_atomhandler.size(); ++i) {
m_atomhandler[i]->checkClientMessage(ce, screen, win);
if (winclient && screen) {
for (size_t i=0; i<m_atomhandler.size(); ++i) {
m_atomhandler[i]->checkClientMessage(ce, screen, winclient);
}
}
}
}
@ -1325,8 +1329,6 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
// make sure each workspace get this
BScreen &scr = win.screen();
scr.removeWindow(&win);
if (m_focused_window == &win)
revertFocus(scr);
} else if ((&(win.workspaceSig())) == changedsub) { // workspace signal
for (size_t i=0; i<m_atomhandler.size(); ++i) {
@ -1372,10 +1374,14 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
if (m_atomhandler[i]->update())
m_atomhandler[i]->updateClientClose(client);
}
BScreen &screen = client.screen();
screen.updateNetizenWindowDel(client.window());
screen.removeClient(client);
if (m_focused_window == &client)
revertFocus(screen);
removeWindowSearch(client.window());
}
}
@ -1434,25 +1440,36 @@ void Fluxbox::removeAtomHandler(AtomHandler *atomh) {
}
}
FluxboxWindow *Fluxbox::searchWindow(Window window) {
std::map<Window, FluxboxWindow *>::iterator it = m_window_search.find(window);
return it == m_window_search.end() ? 0 : it->second;
WinClient *Fluxbox::searchWindow(Window window) {
std::map<Window, WinClient *>::iterator it = m_window_search.find(window);
if (it != m_window_search.end())
return it->second;
std::map<Window, FluxboxWindow *>::iterator git = m_window_search_group.find(window);
return git == m_window_search_group.end() ? 0 : &git->second->winClient();
}
FluxboxWindow *Fluxbox::searchGroup(Window window, FluxboxWindow *win) {
std::map<Window, FluxboxWindow *>::iterator it = m_group_search.find(window);
return it == m_group_search.end() ? 0 : it->second;
/* Not implemented until we know how it'll be used
* Recall that this refers to ICCCM groups, not fluxbox tabgroups
* See ICCCM 4.1.11 for details
*/
/*
WinClient *Fluxbox::searchGroup(Window window) {
}
*/
void Fluxbox::saveWindowSearch(Window window, FluxboxWindow *data) {
void Fluxbox::saveWindowSearch(Window window, WinClient *data) {
m_window_search[window] = data;
}
/* some windows relate to the whole group */
void Fluxbox::saveWindowSearchGroup(Window window, FluxboxWindow *data) {
m_window_search_group[window] = data;
}
void Fluxbox::saveGroupSearch(Window window, FluxboxWindow *data) {
m_group_search[window] = data;
void Fluxbox::saveGroupSearch(Window window, WinClient *data) {
m_group_search.insert(pair<Window, WinClient *>(window, data));
}
@ -1460,6 +1477,10 @@ void Fluxbox::removeWindowSearch(Window window) {
m_window_search.erase(window);
}
void Fluxbox::removeWindowSearchGroup(Window window) {
m_window_search_group.erase(window);
}
void Fluxbox::removeGroupSearch(Window window) {
m_group_search.erase(window);
}
@ -1996,9 +2017,9 @@ void Fluxbox::timeout() {
}
// set focused window
void Fluxbox::setFocusedWindow(FluxboxWindow *win) {
void Fluxbox::setFocusedWindow(WinClient *client) {
// already focused
if (m_focused_window == win) {
if (m_focused_window == client) {
#ifdef DEBUG
cerr<<"Focused window already win"<<endl;
#endif // DEBUG
@ -2006,19 +2027,19 @@ void Fluxbox::setFocusedWindow(FluxboxWindow *win) {
}
#ifdef DEBUG
cerr<<"-----------------"<<endl;
cerr<<"Setting Focused window = "<<win<<endl;
cerr<<"Setting Focused window = "<<client<<endl;
cerr<<"Current Focused window = "<<m_focused_window<<endl;
cerr<<"------------------"<<endl;
#endif // DEBUG
BScreen *old_screen = 0, *screen = 0;
FluxboxWindow *old_win = 0;
WinClient *old_client = 0;
Workspace *old_wkspc = 0, *wkspc = 0;
if (m_focused_window != 0) {
// check if m_focused_window is valid
bool found = false;
std::map<Window, FluxboxWindow *>::iterator it = m_window_search.begin();
std::map<Window, FluxboxWindow *>::iterator it_end = m_window_search.end();
std::map<Window, WinClient *>::iterator it = m_window_search.begin();
std::map<Window, WinClient *>::iterator it_end = m_window_search.end();
for (; it != it_end; ++it) {
if (it->second == m_focused_window) {
// we found it, end loop
@ -2030,26 +2051,32 @@ void Fluxbox::setFocusedWindow(FluxboxWindow *win) {
if (!found) {
m_focused_window = 0;
} else {
old_win = m_focused_window;
old_screen = &old_win->screen();
old_client = m_focused_window;
old_screen = &old_client->screen();
old_wkspc = old_screen->getWorkspace(old_win->workspaceNumber());
if (old_client->fbwindow()) {
FluxboxWindow *old_win = old_client->fbwindow();
old_wkspc = old_screen->getWorkspace(old_win->workspaceNumber());
old_win->setFocusFlag(false);
if (!client || client->fbwindow() != old_win)
old_win->setFocusFlag(false);
}
}
}
if (win && ! win->isIconic()) {
if (client && client->fbwindow() && !client->fbwindow()->isIconic()) {
FluxboxWindow *win = client->fbwindow();
// make sure we have a valid win pointer with a valid screen
ScreenList::iterator winscreen =
std::find(m_screen_list.begin(), m_screen_list.end(),
&win->screen());
&client->screen());
if (winscreen == m_screen_list.end()) {
m_focused_window = 0; // the window pointer wasn't valid, mark no window focused
} else {
screen = *winscreen;
wkspc = screen->getWorkspace(win->workspaceNumber());
m_focused_window = win; // update focused window
wkspc = screen->getWorkspace(win->workspaceNumber());
m_focused_window = client; // update focused window
win->setCurrentClient(*client, false); // don't setinputfocus
win->setFocusFlag(true); // set focus flag
}
} else

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: fluxbox.hh,v 1.68 2003/07/23 10:43:30 fluxgen Exp $
// $Id: fluxbox.hh,v 1.69 2003/07/28 15:06:36 rathnor Exp $
#ifndef FLUXBOX_HH
#define FLUXBOX_HH
@ -88,9 +88,10 @@ public:
inline Atom getFluxboxPidAtom() const { return m_fluxbox_pid; }
FluxboxWindow *searchGroup(Window, FluxboxWindow *);
FluxboxWindow *searchWindow(Window);
inline FluxboxWindow *getFocusedWindow() { return m_focused_window; }
// Not currently implemented until we decide how it'll be used
//WinClient *searchGroup(Window);
WinClient *searchWindow(Window);
inline WinClient *getFocusedWindow() { return m_focused_window; }
BScreen *searchScreen(Window w);
@ -151,7 +152,7 @@ public:
void watchKeyRelease(BScreen &screen, unsigned int mods);
void setFocusedWindow(FluxboxWindow *w);
void setFocusedWindow(WinClient *w);
void revertFocus(BScreen &screen);
void shutdown();
void load_rc(BScreen &scr);
@ -162,10 +163,14 @@ public:
void clearMenuFilenames();
void saveTitlebarFilename(const char *);
void saveSlitlistFilename(const char *val) { m_rc_slitlistfile = (val == 0 ? "" : val); }
void saveWindowSearch(Window win, FluxboxWindow *fbwin);
void saveGroupSearch(Window win, FluxboxWindow *fbwin);
void saveWindowSearch(Window win, WinClient *winclient);
// some windows relate to the group, not the client, so we record separately
// searchWindow on these windows will give the active client in the group
void saveWindowSearchGroup(Window win, FluxboxWindow *fbwin);
void saveGroupSearch(Window win, WinClient *winclient);
void save_rc();
void removeWindowSearch(Window win);
void removeWindowSearchGroup(Window win);
void removeGroupSearch(Window win);
void restart(const char *command = 0);
void reconfigure();
@ -243,14 +248,21 @@ private:
FbTk::Resource<unsigned int> m_rc_cache_life, m_rc_cache_max;
std::map<Window, FluxboxWindow *> m_window_search;
std::map<Window, FluxboxWindow *> m_group_search;
std::map<Window, WinClient *> m_window_search;
std::map<Window, FluxboxWindow *> m_window_search_group;
// A window is the group leader, which can map to several
// WinClients in the group, it is *not* fluxbox's concept of groups
// See ICCCM section 4.1.11
// The group leader (which may not be mapped, so may not have a WinClient)
// will have it's window being the group index
std::multimap<Window, WinClient *> m_group_search;
std::list<MenuTimestamp *> m_menu_timestamps;
typedef std::list<BScreen *> ScreenList;
ScreenList m_screen_list;
FluxboxWindow *m_focused_window, *m_masked_window;
WinClient *m_focused_window;
FluxboxWindow *m_masked_window;
FbTk::Timer m_timer;
BScreen *m_mousescreen, *m_keyscreen;