Focus window under mouse after MouseLowerOp

BUG: 255052
REVIEW: 103975
icc-effect-5.14.5
Thomas Lübking 2012-02-13 23:50:49 +01:00
parent d39c190c40
commit 7e7846adce
3 changed files with 37 additions and 24 deletions

View File

@ -408,6 +408,25 @@ static inline bool isUsableFocusCandidate(Client *c, Client *prev, bool respectS
(!respectScreen || c->isOnScreen(prev ? prev->screen() : Workspace::self()->activeScreen()));
}
Client *Workspace::clientUnderMouse(int screen) const
{
QList<Client*>::const_iterator it = stackingOrder().constEnd();
while (it != stackingOrder().constBegin()) {
Client *client = *(--it);
// rule out clients which are not really visible.
// the screen test is rather superflous for xrandr & twinview since the geometry would differ -> TODO: might be dropped
if (!(client->isShown(false) && client->isOnCurrentDesktop() &&
client->isOnCurrentActivity() && client->isOnScreen(screen)))
continue;
if (client->geometry().contains(QCursor::pos())) {
return client;
}
}
return 0;
}
// deactivates 'c' and activates next client
bool Workspace::activateNextClient(Client* c)
{
@ -436,22 +455,10 @@ bool Workspace::activateNextClient(Client* c)
Client* get_focus = NULL;
if (options->nextFocusPrefersMouse) {
QList<Client*>::const_iterator it = stackingOrder().constEnd();
while (it != stackingOrder().constBegin()) {
Client *client = *(--it);
// rule out clients which are not really visible.
// the screen test is rather superflous for xrandr & twinview since the geometry would differ -> TODO: might be dropped
if (!(client->isShown(false) && client->isOnCurrentDesktop() &&
client->isOnCurrentActivity() && client->isOnScreen(c ? c->screen() : activeScreen())))
continue;
if (client->geometry().contains(QCursor::pos())) {
if (client != c && !client->isDesktop()) // should rather not happen, but it cannot get the focus. rest of usability is tested above
get_focus = client;
break; // unconditional break - we do not pass the focus to some client below an unusable one
}
get_focus = clientUnderMouse(c ? c->screen() : activeScreen());
if (get_focus && (get_focus == c || get_focus->isDesktop())) {
// should rather not happen, but it cannot get the focus. rest of usability is tested above
get_focus = 0;
}
}

View File

@ -816,13 +816,17 @@ bool Client::performMouseCommand(Options::MouseCommand command, const QPoint &gl
case Options::MouseRaise:
workspace()->raiseClient(this);
break;
case Options::MouseLower:
case Options::MouseLower: {
workspace()->lowerClient(this);
// As this most likely makes the window no longer visible change the
// keyboard focus to the next available window.
//workspace()->activateNextClient( this ); // Doesn't work when we lower a child window
workspace()->activateClient(workspace()->topClientOnDesktop(workspace()->currentDesktop(), -1));
// used to be activateNextClient(this), then topClientOnDesktop
// since this is a mouseOp it's however safe to use the client under the mouse instead
if (isActive()) {
Client *next = workspace()->clientUnderMouse(screen());
if (next && next != this)
workspace()->requestFocus(next, false);
}
break;
}
case Options::MouseShade :
toggleShade();
cancelShadeHoverTimer();
@ -1238,13 +1242,13 @@ void Workspace::slotWindowRaise()
*/
void Workspace::slotWindowLower()
{
Client* c = active_popup_client ? active_popup_client : active_client;
if (c) {
if ((Client* c = active_popup_client ? active_popup_client : active_client)) {
lowerClient(c);
// As this most likely makes the window no longer visible change the
// keyboard focus to the next available window.
//activateNextClient( c ); // Doesn't work when we lower a child window
activateClient(topClientOnDesktop(currentDesktop(), -1));
if (c->isActive())
activateClient(topClientOnDesktop(currentDesktop(), -1));
}
}

View File

@ -144,6 +144,8 @@ public:
*/
Client* mostRecentlyActivatedClient() const;
Client* clientUnderMouse(int screen) const;
void activateClient(Client*, bool force = false);
void requestFocus(Client* c, bool force = false);
void takeActivity(Client* c, int flags, bool handled); // Flags are ActivityFlags