transient fixes by making them WinClients
This commit is contained in:
parent
de68c88ed8
commit
d63bf127ad
7 changed files with 251 additions and 315 deletions
|
@ -1,6 +1,8 @@
|
|||
(Format: Year/Month/Day)
|
||||
Changes for 0.9.2:
|
||||
*03/05/07:
|
||||
* Fixed transient grouping issues (transients now WinClients) (Simon)
|
||||
WinClient.hh/cc Window.hh/cc Workspace.cc Screen.cc
|
||||
* Fixed screen problem with redrawing menus (Henrik)
|
||||
The m_screen_num wasn't set in X Window assignment operator
|
||||
FbTk/FbWindow.cc
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// $Id: Screen.cc,v 1.146 2003/05/07 13:50:41 rathnor Exp $
|
||||
// $Id: Screen.cc,v 1.147 2003/05/07 16:21:25 rathnor Exp $
|
||||
|
||||
|
||||
#include "Screen.hh"
|
||||
|
@ -973,8 +973,14 @@ void BScreen::removeClient(WinClient &client) {
|
|||
focused_list.remove(&client);
|
||||
if (cyc == &client) {
|
||||
cycling_window = focused_list.end();
|
||||
} else if (focused && &focused->winClient() == &client)
|
||||
Fluxbox::instance()->revertFocus(&focused->getScreen());
|
||||
} else if (focused && &focused->winClient() == &client) {
|
||||
// if we are focused, then give our focus to our transient parent
|
||||
// or revert normally
|
||||
if (client.transientFor() && client.transientFor()->fbwindow())
|
||||
client.transientFor()->fbwindow()->setInputFocus();
|
||||
else
|
||||
Fluxbox::instance()->revertFocus(&focused->getScreen());
|
||||
}
|
||||
}
|
||||
|
||||
FluxboxWindow *BScreen::getIcon(unsigned int index) {
|
||||
|
|
|
@ -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.6 2003/05/04 23:38:06 rathnor Exp $
|
||||
// $Id: WinClient.cc,v 1.7 2003/05/07 16:21:26 rathnor Exp $
|
||||
|
||||
#include "WinClient.hh"
|
||||
|
||||
|
@ -54,6 +54,7 @@ WinClient::WinClient(Window win, FluxboxWindow &fbwin):FbTk::FbWindow(win),
|
|||
mwm_hint(0),
|
||||
blackbox_hint(0),
|
||||
m_win(&fbwin),
|
||||
modal(false),
|
||||
m_title(""), m_icon_title(""),
|
||||
m_diesig(*this) { }
|
||||
|
||||
|
@ -62,42 +63,22 @@ WinClient::~WinClient() {
|
|||
cerr<<__FILE__<<"(~"<<__FUNCTION__<<")[this="<<this<<"]"<<endl;
|
||||
#endif // DEBUG
|
||||
|
||||
// this takes care of any focus issues
|
||||
m_diesig.notify();
|
||||
|
||||
Fluxbox *fluxbox = Fluxbox::instance();
|
||||
|
||||
if (transient_for != 0) {
|
||||
if (transientFor() == m_win) {
|
||||
transient_for = 0;
|
||||
}
|
||||
|
||||
if (transient_for != 0) {
|
||||
FluxboxWindow::ClientList::iterator client_it =
|
||||
transientFor()->clientList().begin();
|
||||
FluxboxWindow::ClientList::iterator client_it_end =
|
||||
transientFor()->clientList().end();
|
||||
for (; client_it != client_it_end; ++client_it) {
|
||||
(*client_it)->transientList().remove(m_win);
|
||||
}
|
||||
|
||||
transient_for->setInputFocus();
|
||||
transient_for = 0;
|
||||
}
|
||||
assert(transient_for != this);
|
||||
transient_for->transientList().remove(this);
|
||||
transient_for = 0;
|
||||
}
|
||||
|
||||
while (!transients.empty()) {
|
||||
FluxboxWindow::ClientList::iterator it =
|
||||
transients.back()->clientList().begin();
|
||||
FluxboxWindow::ClientList::iterator it_end =
|
||||
transients.back()->clientList().end();
|
||||
for (; it != it_end; ++it) {
|
||||
if ((*it)->transientFor() == m_win)
|
||||
(*it)->transient_for = 0;
|
||||
}
|
||||
|
||||
while (!transients.empty()) {
|
||||
transients.back()->transient_for = 0;
|
||||
transients.pop_back();
|
||||
}
|
||||
|
||||
|
||||
if (window_group != 0) {
|
||||
fluxbox->removeGroupSearch(window_group);
|
||||
window_group = 0;
|
||||
|
@ -199,17 +180,7 @@ void WinClient::updateTransientInfo() {
|
|||
return;
|
||||
// remove us from parent
|
||||
if (transientFor() != 0) {
|
||||
//!! TODO
|
||||
// since we don't know which client in transientFor()
|
||||
// that we're transient for then we just remove us
|
||||
// from every client in transientFor() clientlist
|
||||
FluxboxWindow::ClientList::iterator client_it =
|
||||
transientFor()->clientList().begin();
|
||||
FluxboxWindow::ClientList::iterator client_it_end =
|
||||
transientFor()->clientList().end();
|
||||
for (; client_it != client_it_end; ++client_it) {
|
||||
(*client_it)->transientList().remove(m_win);
|
||||
}
|
||||
transientFor()->transientList().remove(this);
|
||||
}
|
||||
|
||||
transient_for = 0;
|
||||
|
@ -223,21 +194,19 @@ void WinClient::updateTransientInfo() {
|
|||
if (win == window())
|
||||
return;
|
||||
|
||||
if (win != 0 && m_win->getScreen().getRootWindow() == win) {
|
||||
m_win->modal = true;
|
||||
return;
|
||||
if (win != None && m_win->getScreen().getRootWindow() == win) {
|
||||
modal = true;
|
||||
return; // transient for root window...
|
||||
}
|
||||
|
||||
transient_for = Fluxbox::instance()->searchWindow(win);
|
||||
if (transient_for != 0 &&
|
||||
window_group != None && win == window_group) {
|
||||
transient_for = Fluxbox::instance()->searchGroup(win, m_win);
|
||||
}
|
||||
|
||||
FluxboxWindow *transient_win = Fluxbox::instance()->searchWindow(win);
|
||||
if (transient_win)
|
||||
transient_for = transient_win->findClient(win);
|
||||
|
||||
// make sure we don't have deadlock loop in transient chain
|
||||
for (FluxboxWindow *w = m_win; w != 0; w = w->m_client->transient_for) {
|
||||
if (w == w->m_client->transient_for) {
|
||||
w->m_client->transient_for = 0;
|
||||
for (WinClient *w = this; w != 0; w = w->transient_for) {
|
||||
if (w == w->transient_for) {
|
||||
w->transient_for = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -245,13 +214,10 @@ void WinClient::updateTransientInfo() {
|
|||
if (transientFor() != 0) {
|
||||
// we need to add ourself to the right client in
|
||||
// the transientFor() window so we search client
|
||||
WinClient *client = transientFor()->findClient(win);
|
||||
assert(client != 0);
|
||||
client->transientList().push_back(m_win);
|
||||
// make sure we only have on instance of this
|
||||
client->transientList().unique();
|
||||
if (transientFor()->isStuck())
|
||||
m_win->stick();
|
||||
transient_for->transientList().push_back(this);
|
||||
|
||||
if (transientFor()->fbwindow() && transientFor()->fbwindow()->isStuck())
|
||||
m_win->stick();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.2 2003/04/14 12:08:21 fluxgen Exp $
|
||||
// $Id: WinClient.hh,v 1.3 2003/05/07 16:21:26 rathnor Exp $
|
||||
|
||||
#ifndef WINCLIENT_HH
|
||||
#define WINCLIENT_HH
|
||||
|
@ -36,7 +36,7 @@ class FluxboxWindow;
|
|||
/// Holds client window info
|
||||
class WinClient:public FbTk::FbWindow {
|
||||
public:
|
||||
typedef std::list<FluxboxWindow *> TransientList;
|
||||
typedef std::list<WinClient *> TransientList;
|
||||
|
||||
WinClient(Window win, FluxboxWindow &fbwin);
|
||||
|
||||
|
@ -56,10 +56,13 @@ public:
|
|||
|
||||
/// updates transient window information
|
||||
void updateTransientInfo();
|
||||
FluxboxWindow *transientFor() { return transient_for; }
|
||||
const FluxboxWindow *transientFor() const { return transient_for; }
|
||||
WinClient *transientFor() { return transient_for; }
|
||||
const WinClient *transientFor() const { return transient_for; }
|
||||
TransientList &transientList() { return transients; }
|
||||
const TransientList &transientList() const { return transients; }
|
||||
bool isTransient() const { return transient_for != 0; }
|
||||
bool isModal() const { return modal; }
|
||||
|
||||
bool operator == (const FluxboxWindow &win) const {
|
||||
return (m_win == &win);
|
||||
}
|
||||
|
@ -73,8 +76,8 @@ public:
|
|||
remove or move these to private
|
||||
*/
|
||||
|
||||
FluxboxWindow *transient_for; // which window are we a transient for?
|
||||
std::list<FluxboxWindow *> transients; // which windows are our transients?
|
||||
WinClient *transient_for; // which window are we a transient for?
|
||||
std::list<WinClient *> transients; // which windows are our transients?
|
||||
Window window_group;
|
||||
|
||||
|
||||
|
@ -105,6 +108,7 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
bool modal;
|
||||
std::string m_title, m_icon_title;
|
||||
WinClientSubj m_diesig;
|
||||
};
|
||||
|
|
366
src/Window.cc
366
src/Window.cc
|
@ -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.159 2003/05/07 11:33:56 fluxgen Exp $
|
||||
// $Id: Window.cc,v 1.160 2003/05/07 16:21:26 rathnor Exp $
|
||||
|
||||
#include "Window.hh"
|
||||
|
||||
|
@ -121,8 +121,20 @@ static Bool queueScanner(Display *, XEvent *e, char *args) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/// raise window and do the same for each transient it holds
|
||||
/// returns the deepest transientFor, asserting against a close loop
|
||||
WinClient *getRootTransientFor(WinClient *client) {
|
||||
while (client->transientFor()) {
|
||||
assert(client != client->transientFor());
|
||||
client = client->transientFor();
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
/// raise window and do the same for each transient of the current window
|
||||
void raiseFluxboxWindow(FluxboxWindow &win) {
|
||||
if (win.oplock) return;
|
||||
win.oplock = true;
|
||||
|
||||
if (!win.isIconic()) {
|
||||
win.getScreen().updateNetizenWindowRaise(win.getClientWindow());
|
||||
|
@ -130,33 +142,40 @@ void raiseFluxboxWindow(FluxboxWindow &win) {
|
|||
}
|
||||
|
||||
// for each transient do raise
|
||||
std::list<FluxboxWindow *>::const_iterator it = win.getTransients().begin();
|
||||
std::list<FluxboxWindow *>::const_iterator it_end = win.getTransients().end();
|
||||
WinClient::TransientList::const_iterator it = win.winClient().transientList().begin();
|
||||
WinClient::TransientList::const_iterator it_end = win.winClient().transientList().end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (!(*it)->isIconic())
|
||||
raiseFluxboxWindow(*(*it));
|
||||
if ((*it)->fbwindow() && !(*it)->fbwindow()->isIconic())
|
||||
// TODO: should we also check if it is the active client?
|
||||
raiseFluxboxWindow(*(*it)->fbwindow());
|
||||
}
|
||||
win.oplock = false;
|
||||
}
|
||||
|
||||
/// lower window and do the same for each transient it holds
|
||||
void lowerFluxboxWindow(FluxboxWindow &win) {
|
||||
if (win.oplock) return;
|
||||
win.oplock = true;
|
||||
|
||||
if (!win.isIconic()) {
|
||||
win.getScreen().updateNetizenWindowLower(win.getClientWindow());
|
||||
win.getLayerItem().lower();
|
||||
}
|
||||
|
||||
// for each transient do lower
|
||||
std::list<FluxboxWindow *>::const_iterator it = win.getTransients().begin();
|
||||
std::list<FluxboxWindow *>::const_iterator it_end = win.getTransients().end();
|
||||
WinClient::TransientList::const_iterator it = win.winClient().transientList().begin();
|
||||
WinClient::TransientList::const_iterator it_end = win.winClient().transientList().end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (!(*it)->isIconic())
|
||||
lowerFluxboxWindow(*(*it));
|
||||
if ((*it)->fbwindow() && !(*it)->fbwindow()->isIconic())
|
||||
// TODO: should we also check if it is the active client?
|
||||
lowerFluxboxWindow(*(*it)->fbwindow());
|
||||
}
|
||||
win.oplock = false;
|
||||
}
|
||||
|
||||
/// raise window and do the same for each transient it holds
|
||||
void tempRaiseFluxboxWindow(FluxboxWindow &win) {
|
||||
if (win.oplock) return;
|
||||
win.oplock = true;
|
||||
|
||||
if (!win.isIconic()) {
|
||||
// don't update netizen, as it is only temporary
|
||||
|
@ -164,12 +183,14 @@ void tempRaiseFluxboxWindow(FluxboxWindow &win) {
|
|||
}
|
||||
|
||||
// for each transient do raise
|
||||
std::list<FluxboxWindow *>::const_iterator it = win.getTransients().begin();
|
||||
std::list<FluxboxWindow *>::const_iterator it_end = win.getTransients().end();
|
||||
WinClient::TransientList::const_iterator it = win.winClient().transientList().begin();
|
||||
WinClient::TransientList::const_iterator it_end = win.winClient().transientList().end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (!(*it)->isIconic())
|
||||
tempRaiseFluxboxWindow(*(*it));
|
||||
if ((*it)->fbwindow() && !(*it)->fbwindow()->isIconic())
|
||||
// TODO: should we also check if it is the active client?
|
||||
tempRaiseFluxboxWindow(*(*it)->fbwindow());
|
||||
}
|
||||
win.oplock = false;
|
||||
}
|
||||
|
||||
class SetClientCmd:public FbTk::Command {
|
||||
|
@ -195,14 +216,15 @@ void LayerMenuItem<FluxboxWindow>::click(int button, int time) {
|
|||
FluxboxWindow::FluxboxWindow(WinClient &client, BScreen &scr, FbWinFrameTheme &tm,
|
||||
FbTk::MenuTheme &menutheme,
|
||||
FbTk::XLayer &layer):
|
||||
oplock(false),
|
||||
m_hintsig(*this),
|
||||
m_statesig(*this),
|
||||
m_layersig(*this),
|
||||
m_workspacesig(*this),
|
||||
m_diesig(*this),
|
||||
moving(false), resizing(false), shaded(false), maximized(false),
|
||||
iconic(false), transient(false), focused(false),
|
||||
stuck(false), modal(false), send_focus_message(false), m_managed(false),
|
||||
iconic(false), focused(false),
|
||||
stuck(false), send_focus_message(false), m_managed(false),
|
||||
screen(scr),
|
||||
timer(this),
|
||||
display(0),
|
||||
|
@ -227,14 +249,15 @@ FluxboxWindow::FluxboxWindow(WinClient &client, BScreen &scr, FbWinFrameTheme &t
|
|||
FluxboxWindow::FluxboxWindow(Window w, BScreen &scr, FbWinFrameTheme &tm,
|
||||
FbTk::MenuTheme &menutheme,
|
||||
FbTk::XLayer &layer):
|
||||
oplock(false),
|
||||
m_hintsig(*this),
|
||||
m_statesig(*this),
|
||||
m_layersig(*this),
|
||||
m_workspacesig(*this),
|
||||
m_diesig(*this),
|
||||
moving(false), resizing(false), shaded(false), maximized(false),
|
||||
iconic(false), transient(false), focused(false),
|
||||
stuck(false), modal(false), send_focus_message(false), m_managed(false),
|
||||
iconic(false), focused(false),
|
||||
stuck(false), send_focus_message(false), m_managed(false),
|
||||
screen(scr),
|
||||
timer(this),
|
||||
display(0),
|
||||
|
@ -399,10 +422,10 @@ void FluxboxWindow::init() {
|
|||
m_managed = true; //this window is managed
|
||||
|
||||
// update transient infomation
|
||||
updateTransientInfo();
|
||||
m_client->updateTransientInfo();
|
||||
|
||||
// adjust the window decorations based on transience and window sizes
|
||||
if (transient) {
|
||||
if (m_client->isTransient()) {
|
||||
decorations.maximize = functions.maximize = false;
|
||||
decorations.handle = decorations.border = false;
|
||||
}
|
||||
|
@ -419,7 +442,7 @@ void FluxboxWindow::init() {
|
|||
upsize();
|
||||
|
||||
bool place_window = true;
|
||||
if (fluxbox->isStartup() || transient ||
|
||||
if (fluxbox->isStartup() || m_client->isTransient() ||
|
||||
m_client->normal_hint_flags & (PPosition|USPosition)) {
|
||||
setGravityOffsets();
|
||||
|
||||
|
@ -454,8 +477,10 @@ void FluxboxWindow::init() {
|
|||
m_frame.resizeForClient(wattrib.width, wattrib.height);
|
||||
|
||||
// if we're a transient then we should be on the same layer as our parent
|
||||
if (isTransient())
|
||||
getLayerItem().setLayer(getTransientFor()->getLayerItem().getLayer());
|
||||
if (m_client->isTransient() &&
|
||||
m_client->transientFor()->fbwindow() &&
|
||||
m_client->transientFor()->fbwindow() != this)
|
||||
getLayerItem().setLayer(m_client->transientFor()->fbwindow()->getLayerItem().getLayer());
|
||||
else // if no parent then set default layer
|
||||
moveToLayer(m_layernum);
|
||||
|
||||
|
@ -535,14 +560,6 @@ void FluxboxWindow::attachClient(WinClient &client) {
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// add client and move over all attached clients
|
||||
|
@ -571,14 +588,6 @@ void FluxboxWindow::attachClient(WinClient &client) {
|
|||
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);
|
||||
}
|
||||
|
@ -632,7 +641,7 @@ bool FluxboxWindow::removeClient(WinClient &client) {
|
|||
client.m_win = 0;
|
||||
m_clientlist.remove(&client);
|
||||
|
||||
if (m_client == &client && m_clientlist.size() == 0)
|
||||
if (m_client == &client && m_clientlist.empty())
|
||||
m_client = 0;
|
||||
|
||||
FbTk::EventManager &evm = *FbTk::EventManager::instance();
|
||||
|
@ -719,7 +728,7 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
|
|||
}
|
||||
|
||||
bool FluxboxWindow::isGroupable() const {
|
||||
if (isResizable() && isMaximizable() && !isTransient())
|
||||
if (isResizable() && isMaximizable() && !winClient().isTransient())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -1136,12 +1145,12 @@ bool FluxboxWindow::setInputFocus() {
|
|||
|
||||
bool ret = false;
|
||||
|
||||
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();
|
||||
if (!m_client->transients.empty() && m_client->isModal()) {
|
||||
WinClient::TransientList::iterator it = m_client->transients.begin();
|
||||
WinClient::TransientList::iterator it_end = m_client->transients.end();
|
||||
for (; it != it_end; ++it) {
|
||||
if ((*it)->modal)
|
||||
return (*it)->setInputFocus();
|
||||
if ((*it)->isModal())
|
||||
return (*it)->fbwindow()->setCurrentClient(**it,true);
|
||||
}
|
||||
} else {
|
||||
if (focus_mode == F_LOCALLYACTIVE || focus_mode == F_PASSIVE) {
|
||||
|
@ -1184,7 +1193,6 @@ void FluxboxWindow::show() {
|
|||
Unmaps the window and removes it from workspace list
|
||||
*/
|
||||
void FluxboxWindow::iconify() {
|
||||
|
||||
if (isIconic()) // no need to iconify if we're already
|
||||
return;
|
||||
|
||||
|
@ -1202,22 +1210,28 @@ void FluxboxWindow::iconify() {
|
|||
client.setEventMask(NoEventMask);
|
||||
client.hide();
|
||||
client.setEventMask(PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
|
||||
if (client.transientFor()) {
|
||||
if (! client.transientFor()->isIconic()) {
|
||||
client.transientFor()->iconify();
|
||||
}
|
||||
if (client.transientFor() &&
|
||||
client.transientFor()->fbwindow()) {
|
||||
if (!client.transientFor()->fbwindow()->isIconic()) {
|
||||
client.transientFor()->fbwindow()->iconify();
|
||||
}
|
||||
}
|
||||
|
||||
if (client.transientList().size()) {
|
||||
for_each(client.transientList().begin(),
|
||||
client.transientList().end(),
|
||||
mem_fun(&FluxboxWindow::iconify));
|
||||
if (!client.transientList().empty()) {
|
||||
WinClient::TransientList::iterator it = client.transientList().begin();
|
||||
WinClient::TransientList::iterator it_end = client.transientList().end();
|
||||
for (; it != it_end; it++)
|
||||
if ((*it)->fbwindow())
|
||||
(*it)->fbwindow()->iconify();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FluxboxWindow::deiconify(bool reassoc, bool do_raise) {
|
||||
if (oplock) return;
|
||||
oplock = true;
|
||||
|
||||
if (iconic || reassoc) {
|
||||
screen.reassociateWindow(this, screen.getCurrentWorkspace()->workspaceID(), false);
|
||||
} else if (moving || workspace_number != screen.getCurrentWorkspace()->workspaceID())
|
||||
|
@ -1245,22 +1259,22 @@ void FluxboxWindow::deiconify(bool reassoc, bool do_raise) {
|
|||
m_frame.setFocus(focused);
|
||||
|
||||
|
||||
if (reassoc && m_client->transients.size()) {
|
||||
if (reassoc && !m_client->transients.empty()) {
|
||||
// deiconify all transients
|
||||
client_it = clientList().begin();
|
||||
for (; client_it != client_it_end; ++client_it) {
|
||||
|
||||
std::list<FluxboxWindow *>::iterator trans_it =
|
||||
//TODO: Can this get stuck in a loop?
|
||||
WinClient::TransientList::iterator trans_it =
|
||||
(*client_it)->transientList().begin();
|
||||
std::list<FluxboxWindow *>::iterator trans_it_end =
|
||||
WinClient::TransientList::iterator trans_it_end =
|
||||
(*client_it)->transientList().end();
|
||||
for (; trans_it != trans_it_end; ++trans_it) {
|
||||
(*trans_it)->deiconify(true, false);
|
||||
}
|
||||
if ((*trans_it)->fbwindow())
|
||||
(*trans_it)->fbwindow()->deiconify(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
oplock = false;
|
||||
if (do_raise)
|
||||
raise();
|
||||
}
|
||||
|
@ -1412,34 +1426,30 @@ void FluxboxWindow::raise() {
|
|||
deiconify();
|
||||
|
||||
// get root window
|
||||
FluxboxWindow *win = this;
|
||||
while (win->getTransientFor()) {
|
||||
win = win->getTransientFor();
|
||||
assert(win != win->getTransientFor());
|
||||
}
|
||||
WinClient *client = getRootTransientFor(m_client);
|
||||
|
||||
// if we don't have any root window use this as root
|
||||
if (win == 0)
|
||||
win = this;
|
||||
if (client == 0)
|
||||
client = m_client;
|
||||
|
||||
// raise this window and every transient in it
|
||||
raiseFluxboxWindow(*win);
|
||||
if (client->fbwindow())
|
||||
raiseFluxboxWindow(*client->fbwindow());
|
||||
}
|
||||
|
||||
void FluxboxWindow::lower() {
|
||||
if (isIconic())
|
||||
deiconify();
|
||||
|
||||
// get root window (i.e the bottom window)
|
||||
FluxboxWindow *bottom = this;
|
||||
while (bottom->getTransientFor()) {
|
||||
bottom = bottom->getTransientFor();
|
||||
assert(bottom != bottom->getTransientFor());
|
||||
}
|
||||
// get root window
|
||||
WinClient *client = getRootTransientFor(m_client);
|
||||
|
||||
if (bottom == 0)
|
||||
bottom = this;
|
||||
// if we don't have any root window use this as root
|
||||
if (client == 0)
|
||||
client = m_client;
|
||||
|
||||
lowerFluxboxWindow(*bottom);
|
||||
if (client->fbwindow())
|
||||
lowerFluxboxWindow(*client->fbwindow());
|
||||
}
|
||||
|
||||
void FluxboxWindow::tempRaise() {
|
||||
|
@ -1447,17 +1457,14 @@ void FluxboxWindow::tempRaise() {
|
|||
deiconify();
|
||||
|
||||
// get root window
|
||||
FluxboxWindow *win = this;
|
||||
while (win->getTransientFor()) {
|
||||
win = win->getTransientFor();
|
||||
assert(win != win->getTransientFor());
|
||||
}
|
||||
WinClient *client = getRootTransientFor(m_client);
|
||||
|
||||
// if we don't have any root window use this as root
|
||||
if (win == 0)
|
||||
win = this;
|
||||
if (client == 0)
|
||||
client = m_client;
|
||||
|
||||
// raise this window and every transient in it
|
||||
tempRaiseFluxboxWindow(*win);
|
||||
if (client->fbwindow())
|
||||
tempRaiseFluxboxWindow(*client->fbwindow());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1466,84 +1473,103 @@ void FluxboxWindow::raiseLayer() {
|
|||
if (getLayerNum() == (Fluxbox::instance()->getMenuLayer()+1))
|
||||
return;
|
||||
|
||||
FluxboxWindow *win = this;
|
||||
|
||||
while (win->getTransientFor()) {
|
||||
win = win->getTransientFor();
|
||||
assert(win != win->getTransientFor());
|
||||
}
|
||||
// get root window
|
||||
WinClient *client = getRootTransientFor(m_client);
|
||||
|
||||
// if we don't have any root window use this as root
|
||||
if (client == 0)
|
||||
client = m_client;
|
||||
|
||||
if (!win->isIconic()) {
|
||||
screen.updateNetizenWindowRaise(win->getClientWindow());
|
||||
win->getLayerItem().raiseLayer();
|
||||
win->setLayerNum(win->getLayerItem().getLayerNum());
|
||||
}
|
||||
FluxboxWindow *win = client->fbwindow();
|
||||
if (!win) return;
|
||||
|
||||
std::list<FluxboxWindow *>::const_iterator it = win->getTransients().begin();
|
||||
std::list<FluxboxWindow *>::const_iterator it_end = win->getTransients().end();
|
||||
if (!win->isIconic())
|
||||
screen.updateNetizenWindowRaise(client->window());
|
||||
|
||||
win->getLayerItem().raiseLayer();
|
||||
|
||||
// remember number just in case a transient happens to revisit this window
|
||||
int layer_num = win->getLayerItem().getLayerNum();
|
||||
win->setLayerNum(layer_num);
|
||||
|
||||
WinClient::TransientList::const_iterator it = client->transientList().begin();
|
||||
WinClient::TransientList::const_iterator it_end = client->transientList().end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (!(*it)->isIconic()) {
|
||||
screen.updateNetizenWindowRaise((*it)->getClientWindow());
|
||||
(*it)->getLayerItem().raiseLayer();
|
||||
(*it)->setLayerNum((*it)->getLayerItem().getLayerNum());
|
||||
win = (*it)->fbwindow();
|
||||
if (win && !win->isIconic()) {
|
||||
screen.updateNetizenWindowRaise((*it)->window());
|
||||
win->getLayerItem().moveToLayer(layer_num);
|
||||
win->setLayerNum(layer_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FluxboxWindow::lowerLayer() {
|
||||
FluxboxWindow *win = (FluxboxWindow *) 0, *bottom = this;
|
||||
|
||||
while (bottom->getTransientFor()) {
|
||||
bottom = bottom->getTransientFor();
|
||||
assert(bottom != bottom->getTransientFor());
|
||||
}
|
||||
|
||||
win = bottom;
|
||||
// get root window
|
||||
WinClient *client = getRootTransientFor(m_client);
|
||||
|
||||
// if we don't have any root window use this as root
|
||||
if (client == 0)
|
||||
client = m_client;
|
||||
|
||||
FluxboxWindow *win = client->fbwindow();
|
||||
if (!win) return;
|
||||
|
||||
if (!win->isIconic()) {
|
||||
screen.updateNetizenWindowLower(win->getClientWindow());
|
||||
win->getLayerItem().lowerLayer();
|
||||
win->setLayerNum(win->getLayerItem().getLayerNum());
|
||||
screen.updateNetizenWindowLower(client->window());
|
||||
}
|
||||
std::list<FluxboxWindow *>::const_iterator it = win->getTransients().begin();
|
||||
std::list<FluxboxWindow *>::const_iterator it_end = win->getTransients().end();
|
||||
win->getLayerItem().lowerLayer();
|
||||
// remember number just in case a transient happens to revisit this window
|
||||
int layer_num = win->getLayerItem().getLayerNum();
|
||||
win->setLayerNum(layer_num);
|
||||
|
||||
WinClient::TransientList::const_iterator it = client->transientList().begin();
|
||||
WinClient::TransientList::const_iterator it_end = client->transientList().end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (!(*it)->isIconic()) {
|
||||
screen.updateNetizenWindowLower((*it)->getClientWindow());
|
||||
(*it)->getLayerItem().lowerLayer();
|
||||
(*it)->setLayerNum((*it)->getLayerItem().getLayerNum());
|
||||
win = (*it)->fbwindow();
|
||||
if (win && !win->isIconic()) {
|
||||
screen.updateNetizenWindowLower((*it)->window());
|
||||
win->getLayerItem().moveToLayer(layer_num);
|
||||
win->setLayerNum(layer_num);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FluxboxWindow::moveToLayer(int layernum) {
|
||||
Fluxbox * fluxbox = Fluxbox::instance();
|
||||
|
||||
FluxboxWindow *win = this;
|
||||
|
||||
// don't let it set its layer into menu area
|
||||
if (layernum <= fluxbox->getMenuLayer()) {
|
||||
layernum = fluxbox->getMenuLayer() + 1;
|
||||
}
|
||||
|
||||
while (win->getTransientFor()) {
|
||||
win = win->getTransientFor();
|
||||
assert(win != win->getTransientFor());
|
||||
}
|
||||
// get root window
|
||||
WinClient *client = getRootTransientFor(m_client);
|
||||
|
||||
// if we don't have any root window use this as root
|
||||
if (client == 0)
|
||||
client = m_client;
|
||||
|
||||
FluxboxWindow *win = client->fbwindow();
|
||||
if (!win) return;
|
||||
|
||||
if (!win->isIconic()) {
|
||||
screen.updateNetizenWindowRaise(win->getClientWindow());
|
||||
win->getLayerItem().moveToLayer(layernum);
|
||||
win->setLayerNum(win->getLayerItem().getLayerNum());
|
||||
screen.updateNetizenWindowRaise(client->window());
|
||||
}
|
||||
std::list<FluxboxWindow *>::const_iterator it = win->getTransients().begin();
|
||||
std::list<FluxboxWindow *>::const_iterator it_end = win->getTransients().end();
|
||||
win->getLayerItem().lowerLayer();
|
||||
// remember number just in case a transient happens to revisit this window
|
||||
layernum = win->getLayerItem().getLayerNum();
|
||||
win->setLayerNum(layernum);
|
||||
|
||||
WinClient::TransientList::const_iterator it = client->transientList().begin();
|
||||
WinClient::TransientList::const_iterator it_end = client->transientList().end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (!(*it)->isIconic()) {
|
||||
screen.updateNetizenWindowRaise((*it)->getClientWindow());
|
||||
(*it)->getLayerItem().moveToLayer(layernum);
|
||||
(*it)->setLayerNum((*it)->getLayerItem().getLayerNum());
|
||||
win = (*it)->fbwindow();
|
||||
if (win && !win->isIconic()) {
|
||||
screen.updateNetizenWindowRaise((*it)->window());
|
||||
win->getLayerItem().moveToLayer(layernum);
|
||||
win->setLayerNum(layernum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1992,7 +2018,7 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) {
|
|||
|
||||
setState(NormalState);
|
||||
|
||||
if (transient || screen.doFocusNew())
|
||||
if (client->isTransient() || screen.doFocusNew())
|
||||
setInputFocus();
|
||||
else
|
||||
setFocusFlag(false);
|
||||
|
@ -2003,7 +2029,7 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) {
|
|||
iconic = false;
|
||||
|
||||
// Auto-group from tab?
|
||||
if (!transient) {
|
||||
if (!client->isTransient()) {
|
||||
cerr<<__FILE__<<"("<<__FUNCTION__<<") TODO check grouping here"<<endl;
|
||||
}
|
||||
|
||||
|
@ -2055,12 +2081,18 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
|
|||
break;
|
||||
|
||||
case XA_WM_TRANSIENT_FOR: {
|
||||
bool was_transient = isTransient();
|
||||
updateTransientInfo();
|
||||
// TODO: this property notify should be handled by winclient
|
||||
// but for now we'll justhave to update all transient info
|
||||
//bool was_transient = isTransient();
|
||||
ClientList::iterator it = clientList().begin();
|
||||
ClientList::iterator it_end = clientList().end();
|
||||
for (; it != it_end; it++)
|
||||
(*it)->updateTransientInfo();
|
||||
reconfigure();
|
||||
// TODO: this is broken whilst we don't know which client
|
||||
// update our layer to be the same layer as our transient for
|
||||
if (isTransient() && isTransient() != was_transient)
|
||||
getLayerItem().setLayer(getTransientFor()->getLayerItem().getLayer());
|
||||
//if (isTransient() && isTransient() != was_transient)
|
||||
// getLayerItem().setLayer(getTransientFor()->getLayerItem().getLayer());
|
||||
|
||||
} break;
|
||||
|
||||
|
@ -2097,7 +2129,8 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
|
|||
functions.resize=false;
|
||||
functions.maximize=false;
|
||||
} else {
|
||||
if (! isTransient()) {
|
||||
// TODO: is broken while handled by FbW, needs to be in WinClient
|
||||
if (! winClient().isTransient()) {
|
||||
decorations.maximize = true;
|
||||
decorations.handle = true;
|
||||
functions.maximize = true;
|
||||
|
@ -2929,12 +2962,6 @@ void FluxboxWindow::updateIcon() {
|
|||
}
|
||||
}
|
||||
|
||||
void FluxboxWindow::updateTransientInfo() {
|
||||
for_each(clientList().begin(),
|
||||
clientList().end(),
|
||||
mem_fun(&WinClient::updateTransientInfo));
|
||||
}
|
||||
|
||||
void FluxboxWindow::restore(WinClient *client, bool remap) {
|
||||
if (client->m_win != this)
|
||||
return;
|
||||
|
@ -2989,39 +3016,6 @@ 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;
|
||||
|
|
|
@ -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.66 2003/05/01 13:19:36 rathnor Exp $
|
||||
// $Id: Window.hh,v 1.67 2003/05/07 16:21:26 rathnor Exp $
|
||||
|
||||
#ifndef WINDOW_HH
|
||||
#define WINDOW_HH
|
||||
|
@ -238,8 +238,6 @@ public:
|
|||
@name accessors
|
||||
*/
|
||||
//@{
|
||||
bool isTransient() const;
|
||||
bool hasTransient() const;
|
||||
inline bool isManaged() const { return m_managed; }
|
||||
inline bool isFocused() const { return focused; }
|
||||
inline bool isVisible() const { return m_frame.isVisible(); }
|
||||
|
@ -267,11 +265,6 @@ public:
|
|||
inline const FbTk::XLayerItem &getLayerItem() const { return m_layeritem; }
|
||||
inline FbTk::XLayerItem &getLayerItem() { return m_layeritem; }
|
||||
|
||||
const std::list<FluxboxWindow *> &getTransients() const;
|
||||
std::list<FluxboxWindow *> &getTransients();
|
||||
const FluxboxWindow *getTransientFor() const;
|
||||
FluxboxWindow *getTransientFor();
|
||||
|
||||
Window getClientWindow() const;
|
||||
|
||||
FbTk::FbWindow &getFbWindow() { return m_frame.window(); }
|
||||
|
@ -335,6 +328,9 @@ public:
|
|||
FluxboxWindow &m_win;
|
||||
};
|
||||
|
||||
bool oplock; // Used to help stop transient loops occurring by locking a window
|
||||
// during certain operations
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
|
@ -348,8 +344,6 @@ private:
|
|||
/// try to attach current attaching client to a window at pos x, y
|
||||
void attachTo(int x, int y);
|
||||
|
||||
void updateTransientInfo();
|
||||
|
||||
bool getState();
|
||||
/// gets title string from client window and updates frame's title
|
||||
void updateTitleFromClient();
|
||||
|
@ -387,8 +381,8 @@ private:
|
|||
std::string m_class_name; /// class name from WM_CLASS
|
||||
|
||||
//Window state
|
||||
bool moving, resizing, shaded, maximized, iconic, transient,
|
||||
focused, stuck, modal, send_focus_message, m_managed;
|
||||
bool moving, resizing, shaded, maximized, iconic,
|
||||
focused, stuck, send_focus_message, m_managed;
|
||||
WinClient *m_attaching_tab;
|
||||
|
||||
BScreen &screen; /// screen on which this window exist
|
||||
|
|
|
@ -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.58 2003/05/04 23:38:06 rathnor Exp $
|
||||
// $Id: Workspace.cc,v 1.59 2003/05/07 16:21:26 rathnor Exp $
|
||||
|
||||
#include "Workspace.hh"
|
||||
|
||||
|
@ -57,13 +57,13 @@ using namespace std;
|
|||
|
||||
namespace { // anonymous
|
||||
|
||||
int countTransients(const FluxboxWindow &win) {
|
||||
if (win.getTransients().size() == 0)
|
||||
int countTransients(const WinClient &client) {
|
||||
if (client.transientList().empty())
|
||||
return 0;
|
||||
// now go throu the entire tree and count transients
|
||||
size_t ret = win.getTransients().size();
|
||||
std::list<FluxboxWindow *>::const_iterator it = win.getTransients().begin();
|
||||
std::list<FluxboxWindow *>::const_iterator it_end = win.getTransients().end();
|
||||
size_t ret = client.transientList().size();
|
||||
WinClient::TransientList::const_iterator it = client.transientList().begin();
|
||||
WinClient::TransientList::const_iterator it_end = client.transientList().end();
|
||||
for (; it != it_end; ++it)
|
||||
ret += countTransients(*(*it));
|
||||
|
||||
|
@ -219,52 +219,22 @@ int Workspace::removeWindow(FluxboxWindow *w) {
|
|||
if (w->isFocused()) {
|
||||
if (screen.isSloppyFocus()) {
|
||||
Fluxbox::instance()->revertFocus(&screen);
|
||||
} else if (w->isTransient() && w->getTransientFor() &&
|
||||
w->getTransientFor()->isVisible()) {
|
||||
w->getTransientFor()->setInputFocus();
|
||||
} else {
|
||||
FluxboxWindow *top = 0;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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()->revertFocus(&screen);
|
||||
// go up the transient tree looking for a focusable window
|
||||
WinClient *client = 0;
|
||||
if (w->numClients() > 0) {
|
||||
client = w->winClient().transientFor();
|
||||
while (client) {
|
||||
if (client->fbwindow() &&
|
||||
client->fbwindow() != w && // can't be this window
|
||||
client->fbwindow()->isVisible() &&
|
||||
client->fbwindow()->setCurrentClient(*client, true))
|
||||
break;
|
||||
client = client->transientFor();
|
||||
}
|
||||
}
|
||||
if (client == 0) // we were unsuccessful
|
||||
Fluxbox::instance()->revertFocus(&screen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue