make better decisions about when to allow stealing the focus

This commit is contained in:
Mark Tiefenbruck 2007-12-21 21:24:13 -08:00
parent 0906477984
commit 0a67bdce41
3 changed files with 35 additions and 23 deletions

View file

@ -749,7 +749,7 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce,
// ce.data.l[0] == 2 means the request came from a pager // ce.data.l[0] == 2 means the request came from a pager
if (winclient->fbwindow() && (ce.data.l[0] == 2 || if (winclient->fbwindow() && (ce.data.l[0] == 2 ||
winclient->fbwindow()->allowsFocusFromClient())) { winclient->fbwindow()->focusRequestFromClient(*winclient))) {
winclient->focus(); winclient->focus();
winclient->fbwindow()->raise(); winclient->fbwindow()->raise();
} }

View file

@ -545,10 +545,12 @@ void FluxboxWindow::init() {
iconify(); iconify();
} else if (m_workspace_number == screen().currentWorkspaceID()) { } else if (m_workspace_number == screen().currentWorkspaceID()) {
iconic = true; iconic = true;
deiconify(); deiconify(false);
// check if we should prevent this window from gaining focus // check if we should prevent this window from gaining focus
if (!allowsFocusFromClient() || Fluxbox::instance()->isStartup()) m_focused = false; // deiconify sets this
m_focused = false; if (!Fluxbox::instance()->isStartup() &&
screen().focusControl().focusNew())
m_focused = focusRequestFromClient(*m_client);
} }
if (fullscreen) { if (fullscreen) {
@ -655,7 +657,7 @@ void FluxboxWindow::attachClient(WinClient &client, int x, int y) {
// we use m_focused as a signal to focus the window when mapped // we use m_focused as a signal to focus the window when mapped
if (focus_new && !is_startup) if (focus_new && !is_startup)
m_focused = true; m_focused = focusRequestFromClient(client);
focused_win = (focus_new || is_startup) ? &client : m_client; focused_win = (focus_new || is_startup) ? &client : m_client;
client.saveBlackboxAttribs(m_blackbox_attrib, client.saveBlackboxAttribs(m_blackbox_attrib,
@ -1008,6 +1010,7 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
WinClient *old = m_client; WinClient *old = m_client;
m_client = &client; m_client = &client;
m_client->raise(); m_client->raise();
if (setinput != m_focused || setinput && m_client != old)
m_client->focusSig().notify(); m_client->focusSig().notify();
titleSig().notify(); titleSig().notify();
@ -1019,7 +1022,6 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
frame().setLabelButtonFocus(*button); frame().setLabelButtonFocus(*button);
frame().setShapingClient(&client, false); frame().setShapingClient(&client, false);
setinput = setinput || m_focused && !screen().focusControl().isCycling();
bool ret = setinput && focus(); bool ret = setinput && focus();
if (setinput) { if (setinput) {
// restore old client until focus event comes // restore old client until focus event comes
@ -2222,31 +2224,34 @@ void FluxboxWindow::mapRequestEvent(XMapRequestEvent &re) {
// Note: this function never gets called from WithdrawnState // Note: this function never gets called from WithdrawnState
// initial state is handled in restoreAttributes() and init() // initial state is handled in restoreAttributes() and init()
// if the user doesn't want the window, then ignore request if (screen().focusControl().focusNew())
if (!allowsFocusFromClient()) m_focused = focusRequestFromClient(*client);
return;
setCurrentClient(*client, false); // focus handled on MapNotify setCurrentClient(*client, false); // focus handled on MapNotify
deiconify(); deiconify();
} }
bool FluxboxWindow::allowsFocusFromClient() { bool FluxboxWindow::focusRequestFromClient(WinClient &from) {
// check what to do if window is on another workspace if (from.fbwindow() != this)
if (screen().currentWorkspaceID() != workspaceNumber() && !isStuck()) {
BScreen::FollowModel model = screen().getFollowModel();
if (model == BScreen::IGNORE_OTHER_WORKSPACES)
return false; return false;
}
bool ret = true;
// check what to do if window is on another workspace
if (screen().currentWorkspaceID() != workspaceNumber() && !isStuck() &&
screen().getFollowModel() == BScreen::IGNORE_OTHER_WORKSPACES)
ret = false;
FluxboxWindow *cur = FocusControl::focusedFbWindow(); FluxboxWindow *cur = FocusControl::focusedFbWindow();
WinClient *client = FocusControl::focusedWindow(); WinClient *client = FocusControl::focusedWindow();
if (cur && client && (m_client->isTransient() || cur->isTyping()) && if (ret && cur && getRootTransientFor(&from) != getRootTransientFor(client))
getRootTransientFor(m_client) != getRootTransientFor(client)) ret = !(cur->isFullscreen() && getOnHead() == cur->getOnHead()) &&
return false; !cur->isTyping();
return true; if (!ret)
Fluxbox::instance()->attentionHandler().addAttention(from);
return ret;
} }
@ -2509,8 +2514,15 @@ void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent &cr) {
case Above: case Above:
case TopIf: case TopIf:
default: default:
setCurrentClient(*client, m_focused); if (isFocused() && focusRequestFromClient(*client) ||
!FocusControl::focusedWindow()) {
setCurrentClient(*client, true);
raise(); raise();
} else if (getRootTransientFor(client) ==
getRootTransientFor(FocusControl::focusedWindow())) {
setCurrentClient(*client, false);
raise();
}
break; break;
case Below: case Below:

View file

@ -244,7 +244,7 @@ public:
* @return true if it took focus. * @return true if it took focus.
*/ */
bool focus(); bool focus();
bool allowsFocusFromClient(); bool focusRequestFromClient(WinClient &from);
/// Raises the window and takes focus (if possible). /// Raises the window and takes focus (if possible).
void raiseAndFocus() { raise(); focus(); } void raiseAndFocus() { raise(); focus(); }