fix focus and raising for transient windows in particular

This commit is contained in:
rathnor 2003-07-20 18:05:40 +00:00
parent 8500132b0a
commit 037bd174bf
10 changed files with 104 additions and 51 deletions

12
BUGS
View file

@ -14,14 +14,10 @@ BUGS:
* After startup the font of the toolbar is to big; reload config works
around this.
=> is this fixed now?? (as of ResourceManager changes)
=> Don't think so, extra info = seems to happen for Multiple screens
* Saving of number of workspaces on restart
* Multiple transients:
in openoffice - focus jumps between until user does something
in mozilla - alt-tabbing does strange thigns with other transient
layer-wise (other transient flashes)
* gaim (0.64) crashes when remembering dimensions... is this a gaim
bug?
@ -78,6 +74,12 @@ Fixed bugs (or not-our-fault bugs):
indicate the change until you point to another option.
=> Fixed
* Multiple transients:
in openoffice - focus jumps between until user does something
in mozilla - alt-tabbing does strange thigns with other transient
layer-wise (other transient flashes)
=> fixed
------------------------------
Core dumps and notes

View file

@ -1,6 +1,9 @@
(Format: Year/Month/Day)
Changes for 0.9.5:
*03/07/20:
* Fix aspects of focus and raising, including transients (Simon)
- fixes focus toggling with transients and sloppy focus
WinClient.hh/cc Window.cc fluxbox.cc MultLayers.hh/cc XLayer.hh/cc Menu.hh
* Fix menu [re]drawing, particularly when selecting options (Simon)
Menu.hh/cc
* Fix disappearing Remember menu, plus titles of sub-window menus

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: Menu.hh,v 1.21 2003/07/20 10:41:56 rathnor Exp $
// $Id: Menu.hh,v 1.22 2003/07/20 18:05:39 rathnor Exp $
#ifndef FBTK_MENU_HH
#define FBTK_MENU_HH
@ -37,7 +37,6 @@
#include "RefCount.hh"
#include "Command.hh"
#include "Observer.hh"
#include "XLayerItem.hh"
#include "FbPixmap.hh"
#include "MenuTheme.hh"

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: MultLayers.cc,v 1.6 2003/02/18 15:08:12 rathnor Exp $
// $Id: MultLayers.cc,v 1.7 2003/07/20 18:05:39 rathnor Exp $
#include "MultLayers.hh"
#include "XLayer.hh"
@ -32,7 +32,9 @@ using namespace std;
using namespace FbTk;
MultLayers::MultLayers(int numlayers) {
MultLayers::MultLayers(int numlayers) :
m_lock(0)
{
for (int i=0; i < numlayers; ++i)
m_layers.push_back(new XLayer(*this, i));
}
@ -150,6 +152,8 @@ void MultLayers::moveToLayer(XLayerItem &item, int layernum) {
}
void MultLayers::restack() {
if (!isUpdatable())
return;
int layernum=0, winnum=0, size = this->size();

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: MultLayers.hh,v 1.5 2003/02/09 14:11:14 rathnor Exp $
// $Id: MultLayers.hh,v 1.6 2003/07/20 18:05:40 rathnor Exp $
#ifndef FBTK_MULTLAYERS_HH
#define FBTK_MULTLAYERS_HH
@ -59,9 +59,15 @@ public:
XLayer *getLayer(size_t num);
const XLayer *getLayer(size_t num) const;
inline bool isUpdatable() const { return m_lock == 0; }
inline void lock() { ++m_lock; }
inline void unlock() { if (--m_lock == 0) restack(); }
private:
std::vector<XLayer *> m_layers;
int m_lock;
};
};

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: XLayer.cc,v 1.8 2003/04/15 23:20:31 rathnor Exp $
// $Id: XLayer.cc,v 1.9 2003/07/20 18:05:40 rathnor Exp $
#include "XLayer.hh"
#include "XLayerItem.hh"
@ -39,6 +39,9 @@ XLayer::~XLayer() {
}
void XLayer::restack() {
if (!m_manager.isUpdatable())
return;
int num_windows = countWindows();
// each LayerItem can contain several windows
@ -78,6 +81,8 @@ int XLayer::countWindows() {
// Stack all windows associated with 'item' below the 'above' item
void XLayer::stackBelowItem(XLayerItem *item, XLayerItem *above) {
if (!m_manager.isUpdatable())
return;
Window *winlist;
size_t winnum, size, num = item->numWindows();

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.17 2003/07/10 11:58:13 fluxgen Exp $
// $Id: WinClient.cc,v 1.18 2003/07/20 18:05:39 rathnor Exp $
#include "WinClient.hh"
@ -54,7 +54,7 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb
wm_hint_flags(0),
send_focus_message(false),
m_win(fbwin),
modal(false),
m_modal(0),
m_title(""), m_icon_title(""),
m_class_name(""), m_instance_name(""),
m_blackbox_hint(0),
@ -245,8 +245,9 @@ void WinClient::updateTransientInfo() {
return;
if (win != None && m_win->screen().rootWindow() == win) {
modal = true;
return; // transient for root window...
// transient for root window... = transient for group
// I don't think we are group-aware yet
return;
}
FluxboxWindow *transient_win = Fluxbox::instance()->searchWindow(win);
@ -514,3 +515,15 @@ bool WinClient::hasGroupLeftWindow() const {
}
return false;
}
void WinClient::addModal() {
++m_modal;
if (transient_for)
transient_for->addModal();
}
void WinClient::removeModal() {
--m_modal;
if (transient_for)
transient_for->removeModal();
}

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.8 2003/06/23 14:16:05 rathnor Exp $
// $Id: WinClient.hh,v 1.9 2003/07/20 18:05:39 rathnor Exp $
#ifndef WINCLIENT_HH
#define WINCLIENT_HH
@ -70,7 +70,10 @@ public:
TransientList &transientList() { return transients; }
const TransientList &transientList() const { return transients; }
bool isTransient() const { return transient_for != 0; }
bool isModal() const { return modal; }
bool isModal() const { return m_modal > 0; }
void addModal(); // some transient of ours (or us) is modal
void removeModal(); // some transient (or us) is no longer modal
bool operator == (const FluxboxWindow &win) const {
return (m_win == &win);
@ -138,7 +141,9 @@ public:
enum { F_NOINPUT = 0, F_PASSIVE, F_LOCALLYACTIVE, F_GLOBALLYACTIVE };
private:
bool modal;
// number of transients which we are modal for
// or indicates that we are modal if don't have any transients
int m_modal;
std::string m_title, m_icon_title;
std::string m_class_name, m_instance_name;

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.206 2003/07/20 08:12:36 rathnor Exp $
// $Id: Window.cc,v 1.207 2003/07/20 18:05:39 rathnor Exp $
#include "Window.hh"
@ -145,6 +145,11 @@ void raiseFluxboxWindow(FluxboxWindow &win) {
if (win.oplock) return;
win.oplock = true;
// we need to lock actual restacking so that raising above active transient
// won't do anything nasty
if (!win.winClient().transientList().empty())
win.screen().layerManager().lock();
if (!win.isIconic()) {
win.screen().updateNetizenWindowRaise(win.clientWindow());
win.layerItem().raise();
@ -159,6 +164,9 @@ void raiseFluxboxWindow(FluxboxWindow &win) {
raiseFluxboxWindow(*(*it)->fbwindow());
}
win.oplock = false;
if (!win.winClient().transientList().empty())
win.screen().layerManager().unlock();
}
/// lower window and do the same for each transient it holds
@ -166,6 +174,11 @@ void lowerFluxboxWindow(FluxboxWindow &win) {
if (win.oplock) return;
win.oplock = true;
// we need to lock actual restacking so that raising above active transient
// won't do anything nasty
if (!win.winClient().transientList().empty())
win.screen().layerManager().lock();
if (!win.isIconic()) {
win.screen().updateNetizenWindowLower(win.clientWindow());
win.layerItem().lower();
@ -179,6 +192,8 @@ void lowerFluxboxWindow(FluxboxWindow &win) {
lowerFluxboxWindow(*(*it)->fbwindow());
}
win.oplock = false;
if (!win.winClient().transientList().empty())
win.screen().layerManager().unlock();
}
/// raise window and do the same for each transient it holds
@ -186,6 +201,9 @@ void tempRaiseFluxboxWindow(FluxboxWindow &win) {
if (win.oplock) return;
win.oplock = true;
if (!win.winClient().transientList().empty())
win.screen().layerManager().lock();
if (!win.isIconic()) {
// don't update netizen, as it is only temporary
win.layerItem().tempRaise();
@ -200,6 +218,10 @@ void tempRaiseFluxboxWindow(FluxboxWindow &win) {
tempRaiseFluxboxWindow(*(*it)->fbwindow());
}
win.oplock = false;
if (!win.winClient().transientList().empty())
win.screen().layerManager().unlock();
}
class SetClientCmd:public FbTk::Command {
@ -1107,8 +1129,6 @@ bool FluxboxWindow::setInputFocus() {
if (! validateClient())
return false;
bool ret = false;
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();
@ -1116,30 +1136,19 @@ bool FluxboxWindow::setInputFocus() {
if ((*it)->isModal())
return (*it)->fbwindow()->setCurrentClient(**it, true);
}
}
if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE ||
m_client->getFocusMode() == WinClient::F_PASSIVE) {
m_client->setInputFocus(RevertToPointerRoot, CurrentTime);
} else {
if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE ||
m_client->getFocusMode() == WinClient::F_PASSIVE) {
m_client->setInputFocus(RevertToPointerRoot, CurrentTime);
} else {
return false;
}
screen().setFocusedWindow(*m_client);
Fluxbox::instance()->setFocusedWindow(this);
frame().setFocus(true);
m_client->sendFocus();
if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus())
&& screen().doAutoRaise())
m_timer.start();
ret = true;
return false;
}
return ret;
if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus())
&& screen().doAutoRaise())
m_timer.start();
return true;
}
void FluxboxWindow::hide() {
@ -1224,8 +1233,9 @@ void FluxboxWindow::deiconify(bool reassoc, bool do_raise) {
frame().show();
if (was_iconic && screen().doFocusNew())
if (was_iconic && screen().doFocusNew()) {
setInputFocus();
}
if (focused != frame().focused())
frame().setFocus(focused);
@ -1579,9 +1589,11 @@ void FluxboxWindow::setFocusFlag(bool focus) {
if (focused)
gettimeofday(&m_last_focus_time, 0);
screen().setFocusedWindow(*m_client);
m_client->sendFocus();
frame().setFocus(focus);
if ((screen().isSloppyFocus() || screen().isSemiSloppyFocus()) &&
if (!focused && (screen().isSloppyFocus() || screen().isSemiSloppyFocus()) &&
screen().doAutoRaise())
m_timer.stop();
}
@ -2042,8 +2054,9 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) {
setState(NormalState);
if (client->isTransient() || screen().doFocusNew())
if (client->isTransient() || screen().doFocusNew()) {
setInputFocus();
}
else
setFocusFlag(false);
@ -2555,8 +2568,9 @@ void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) {
// if client is set, use setCurrent client, otherwise just setInputFocus
if ((!sa.leave || sa.inferior) &&
((client && setCurrentClient(*client, true)) || setInputFocus()))
((client && setCurrentClient(*client, true)) || setInputFocus())) {
installColormap(True);
}
}
}
}

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.171 2003/07/18 15:40:55 rathnor Exp $
// $Id: fluxbox.cc,v 1.172 2003/07/20 18:05:39 rathnor Exp $
#include "fluxbox.hh"
@ -891,11 +891,13 @@ void Fluxbox::handleEvent(XEvent * const e) {
break;
FluxboxWindow *win = searchWindow(e->xfocus.window);
if (win && ! win->isFocused())
if (win && ! win->isFocused()) {
setFocusedWindow(win);
}
} break;
case FocusOut:{
if (e->xfocus.mode == NotifyUngrab ||
e->xfocus.detail == NotifyPointer)
break;
@ -904,8 +906,7 @@ void Fluxbox::handleEvent(XEvent * const e) {
#ifdef DEBUG
cerr<<__FILE__<<"("<<__FUNCTION__<<") Focus out is not a FluxboxWindow !!"<<endl;
#endif // DEBUG
if (getFocusedWindow())
getFocusedWindow()->setInputFocus();
}
}
break;
@ -1084,8 +1085,9 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
} else if (ce.message_type == m_fbatoms->getFluxboxChangeWindowFocusAtom()) {
FluxboxWindow *win = searchWindow(ce.window);
if (win && win->isVisible() && win->setInputFocus())
if (win && win->isVisible() && win->setInputFocus()) {
win->installColormap(true);
}
} else if (ce.message_type == m_fbatoms->getFluxboxCycleWindowFocusAtom()) {
BScreen *screen = searchScreen(ce.window);