Commit b7e30e48 authored by Aaron J. Seigo's avatar Aaron J. Seigo
Browse files

use KWindowInfo to check for transients; take more care with transients

it does a rather more thorough job and fixes the problem of utility
windows that are transients (e.g. toolboxes pulled out of app windows)
preventing windows from being minimized properly from the tasks widget

this is probably far older than the 2.5 year old bug report.

BUG:259255
parent d33bc89e
......@@ -232,7 +232,18 @@ bool Task::isOnAllDesktops() const
bool Task::isActive() const
{
return d->active;
if (d->active) {
return true;
}
const WId activeWindow = KWindowSystem::activeWindow();
foreach (WId window, d->transients) {
if (activeWindow == window) {
return true;
}
}
return false;
}
bool Task::isOnTop() const
......@@ -461,6 +472,7 @@ void Task::toggleMaximized()
void Task::setIconified(bool iconify)
{
kDebug() <<" going to iconify" << d->win;
if (iconify) {
KWindowSystem::minimizeWindow(d->win);
} else {
......@@ -524,7 +536,7 @@ void Task::activate()
void Task::activateRaiseOrIconify()
{
//kDebug() << isActive() << isIconified() << isOnTop();
kDebug() << isActive() << isIconified() << isOnTop();
if (!isActive() || isIconified()) {
activate();
} else if (!isOnTop()) {
......
......@@ -274,7 +274,7 @@ public:
::TaskManager::TaskChanges refresh(WindowProperties dirty);
//* @internal
#ifdef Q_WS_X11
void addTransient(WId w, const NETWinInfo& info);
void addTransient(WId w, const KWindowInfo &info);
#endif
//* @internal
void removeTransient(WId w);
......
......@@ -47,10 +47,10 @@ bool Task::updateDemandsAttentionState(WId w)
return empty != d->transientsDemandingAttention.isEmpty();
}
void Task::addTransient(WId w, const NETWinInfo& info)
void Task::addTransient(WId w, const KWindowInfo &info)
{
d->transients.insert(w);
if (info.state() & NET::DemandsAttention) {
if (info.hasState(NET::DemandsAttention)) {
d->transientsDemandingAttention.insert(w);
emit changed(TransientsChanged | StateChanged | AttentionChanged);
}
......
......@@ -232,8 +232,9 @@ Task *TaskManager::findTask(int desktop, const QPoint& p)
void TaskManager::windowAdded(WId w)
{
#ifdef Q_WS_X11
NETWinInfo info(QX11Info::display(), w, QX11Info::appRootWindow(),
NET::WMWindowType | NET::WMPid | NET::WMState);
KWindowInfo info(w,
NET::WMWindowType | NET::WMPid | NET::WMState | NET::WMName,
NET::WM2TransientFor);
// ignore NET::Tool and other special window types
NET::WindowType wType = info.windowType(NET::NormalMask | NET::DesktopMask | NET::DockMask |
......@@ -241,30 +242,17 @@ void TaskManager::windowAdded(WId w)
NET::OverrideMask | NET::TopMenuMask |
NET::UtilityMask | NET::SplashMask);
if (wType != NET::Normal && wType != NET::Override && wType != NET::Unknown &&
wType != NET::Dialog && wType != NET::Utility) {
return;
}
// ignore windows that want to be ignored by the taskbar
if ((info.state() & NET::SkipTaskbar) != 0) {
d->skiptaskbarWindows.insert(w); // remember them though
return;
}
Window transient_for_tmp;
if (XGetTransientForHint(QX11Info::display(), (Window)w, &transient_for_tmp)) {
WId transient_for = (WId)transient_for_tmp;
if (info.transientFor() > 0) {
const WId transientFor = info.transientFor();
// check if it's transient for a skiptaskbar window
if (d->skiptaskbarWindows.contains(transient_for)) {
if (d->skiptaskbarWindows.contains(transientFor)) {
return;
}
// lets see if this is a transient for an existing task
if (transient_for != QX11Info::appRootWindow() &&
transient_for != 0 && wType != NET::Utility) {
Task *t = findTask(transient_for);
if (transientFor != QX11Info::appRootWindow()) {
Task *t = findTask(transientFor);
if (t) {
if (t->window() != w) {
t->addTransient(w, info);
......@@ -274,6 +262,18 @@ void TaskManager::windowAdded(WId w)
}
}
}
if (wType != NET::Normal && wType != NET::Override && wType != NET::Unknown &&
wType != NET::Dialog && wType != NET::Utility) {
return;
}
// ignore windows that want to be ignored by the taskbar
if ((info.state() & NET::SkipTaskbar) != 0) {
d->skiptaskbarWindows.insert(w); // remember them though
return;
}
#endif
Task *t = new Task(w, 0);
......@@ -480,14 +480,29 @@ bool TaskManager::isOnTop(const Task *task) const
it.toBack();
while (it.hasPrevious()) {
Task *t = d->tasksByWId.value(it.previous());
const WId top = it.previous();
Task *t = d->tasksByWId.value(top);
if (!t) {
foreach (const WId transient, task->transients()) {
if (transient == top) {
return true;
}
}
continue;
}
if (t == task) {
return true;
}
foreach (const WId transient, task->transients()) {
if (transient == top) {
return true;
}
}
#ifndef Q_WS_WIN
if (!t->isIconified() && (t->isAlwaysOnTop() == task->isAlwaysOnTop())) {
return false;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment