fix focus and raising for transient windows in particular
This commit is contained in:
parent
8500132b0a
commit
037bd174bf
10 changed files with 104 additions and 51 deletions
12
BUGS
12
BUGS
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue