Merge branch 'Plasma/5.11'

This commit is contained in:
Martin Flöser 2017-11-16 20:34:52 +01:00
commit f0f4e494fe
10 changed files with 34 additions and 26 deletions

View file

@ -104,9 +104,9 @@ void AbstractClient::updateMouseGrab()
{
}
bool AbstractClient::belongToSameApplication(const AbstractClient *c1, const AbstractClient *c2, bool active_hack)
bool AbstractClient::belongToSameApplication(const AbstractClient *c1, const AbstractClient *c2, SameApplicationChecks checks)
{
return c1->belongsToSameApplication(c2, active_hack);
return c1->belongsToSameApplication(c2, checks);
}
bool AbstractClient::isTransient() const

View file

@ -656,8 +656,12 @@ public:
**/
virtual void killWindow() = 0;
// TODO: remove boolean trap
static bool belongToSameApplication(const AbstractClient* c1, const AbstractClient* c2, bool active_hack = false);
enum class SameApplicationCheck {
RelaxedForActive = 1 << 0,
AllowCrossProcesses = 1 << 1
};
Q_DECLARE_FLAGS(SameApplicationChecks, SameApplicationCheck)
static bool belongToSameApplication(const AbstractClient* c1, const AbstractClient* c2, SameApplicationChecks checks = SameApplicationChecks());
bool hasApplicationMenu() const;
bool applicationMenuActive() const {
@ -778,8 +782,7 @@ protected:
* Default implementation does nothig.
**/
virtual void doMinimize();
// TODO: remove boolean trap
virtual bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const = 0;
virtual bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const = 0;
virtual void doSetSkipTaskbar();
virtual void doSetSkipPager();
@ -1174,5 +1177,6 @@ inline void AbstractClient::setPendingGeometryUpdate(PendingGeometry_t update)
Q_DECLARE_METATYPE(KWin::AbstractClient*)
Q_DECLARE_METATYPE(QList<KWin::AbstractClient*>)
Q_DECLARE_OPERATORS_FOR_FLAGS(KWin::AbstractClient::SameApplicationChecks)
#endif

View file

@ -609,7 +609,7 @@ bool Workspace::allowClientActivation(const KWin::AbstractClient *c, xcb_timesta
// Unconditionally allow intra-client passing around for lower stealing protections
// unless the active client has High interest
if (AbstractClient::belongToSameApplication(c, ac, true) && protection < FSP::High) {
if (AbstractClient::belongToSameApplication(c, ac, AbstractClient::SameApplicationCheck::RelaxedForActive) && protection < FSP::High) {
qCDebug(KWIN_CORE) << "Activation: Belongs to active application";
return true;
}
@ -659,7 +659,7 @@ bool Workspace::allowFullClientRaising(const KWin::AbstractClient *c, xcb_timest
return true; // no active client -> always allow
}
// TODO window urgency -> return true?
if (AbstractClient::belongToSameApplication(c, ac, true)) {
if (AbstractClient::belongToSameApplication(c, ac, AbstractClient::SameApplicationCheck::RelaxedForActive)) {
qCDebug(KWIN_CORE) << "Raising: Belongs to active application";
return true;
}
@ -753,13 +753,13 @@ xcb_timestamp_t Client::readUserTimeMapTimestamp(const KStartupInfoId *asn_id, c
// from already running application if this application
// is not the active one (unless focus stealing prevention is turned off).
Client* act = dynamic_cast<Client*>(workspace()->mostRecentlyActivatedClient());
if (act != NULL && !belongToSameApplication(act, this, true)) {
if (act != NULL && !belongToSameApplication(act, this, SameApplicationCheck::RelaxedForActive)) {
bool first_window = true;
auto sameApplicationActiveHackPredicate = [this](const Client *cl) {
// ignore already existing splashes, toolbars, utilities and menus,
// as the app may show those before the main window
return !cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu()
&& cl != this && Client::belongToSameApplication(cl, this, true);
&& cl != this && Client::belongToSameApplication(cl, this, SameApplicationCheck::RelaxedForActive);
};
if (isTransient()) {
auto clientMainClients = [this] () -> ClientList {

View file

@ -603,7 +603,6 @@ void DecorationInputTest::testModifierClickUnrestrictedMove_data()
const QVector<std::pair<Test::ShellSurfaceType, QByteArray>> surfaceTypes{
{Test::ShellSurfaceType::WlShell, QByteArrayLiteral("WlShell")},
{Test::ShellSurfaceType::XdgShellV5, QByteArrayLiteral("XdgShellV5")},
{Test::ShellSurfaceType::XdgShellV6, QByteArrayLiteral("XdgShellV6")},
};
for (const auto &type: surfaceTypes) {
@ -702,7 +701,6 @@ void DecorationInputTest::testModifierScrollOpacity_data()
const QVector<std::pair<Test::ShellSurfaceType, QByteArray>> surfaceTypes{
{Test::ShellSurfaceType::WlShell, QByteArrayLiteral("WlShell")},
{Test::ShellSurfaceType::XdgShellV5, QByteArrayLiteral("XdgShellV5")},
{Test::ShellSurfaceType::XdgShellV6, QByteArrayLiteral("XdgShellV6")},
};
for (const auto &type: surfaceTypes) {

View file

@ -2102,13 +2102,13 @@ void Client::addDamage(const QRegion &damage)
Toplevel::addDamage(damage);
}
bool Client::belongsToSameApplication(const AbstractClient *other, bool active_hack) const
bool Client::belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const
{
const Client *c2 = dynamic_cast<const Client*>(other);
if (!c2) {
return false;
}
return Client::belongToSameApplication(this, c2, active_hack);
return Client::belongToSameApplication(this, c2, checks);
}
void Client::updateTabGroupStates(TabGroup::States states)

View file

@ -238,7 +238,7 @@ public:
/// Does 'delete c;'
static void deleteClient(Client* c);
static bool belongToSameApplication(const Client* c1, const Client* c2, bool active_hack = false);
static bool belongToSameApplication(const Client* c1, const Client* c2, SameApplicationChecks checks = SameApplicationChecks());
static bool sameAppWindowRoleMatch(const Client* c1, const Client* c2, bool active_hack);
void killWindow() override;
@ -380,7 +380,7 @@ private:
protected:
virtual void debug(QDebug& stream) const;
void addDamage(const QRegion &damage) override;
bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const override;
bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const override;
void doSetActive() override;
void doSetKeepAbove() override;
void doSetKeepBelow() override;

View file

@ -273,7 +273,7 @@ bool Toplevel::resourceMatch(const Toplevel* c1, const Toplevel* c2)
// Client
//****************************************
bool Client::belongToSameApplication(const Client* c1, const Client* c2, bool active_hack)
bool Client::belongToSameApplication(const Client* c1, const Client* c2, SameApplicationChecks checks)
{
bool same_app = false;
@ -292,16 +292,18 @@ bool Client::belongToSameApplication(const Client* c1, const Client* c2, bool ac
same_app = true; // same client leader
// tests that mean they most probably don't belong together
else if (c1->pid() != c2->pid()
else if ((c1->pid() != c2->pid() && !checks.testFlag(SameApplicationCheck::AllowCrossProcesses))
|| c1->wmClientMachine(false) != c2->wmClientMachine(false))
; // different processes
else if (c1->wmClientLeader() != c2->wmClientLeader()
&& c1->wmClientLeader() != c1->window() // if WM_CLIENT_LEADER is not set, it returns window(),
&& c2->wmClientLeader() != c2->window()) // don't use in this test then
&& c2->wmClientLeader() != c2->window() // don't use in this test then
&& !checks.testFlag(SameApplicationCheck::AllowCrossProcesses))
; // different client leader
else if (!resourceMatch(c1, c2))
; // different apps
else if (!sameAppWindowRoleMatch(c1, c2, active_hack))
else if (!sameAppWindowRoleMatch(c1, c2, checks.testFlag(SameApplicationCheck::RelaxedForActive))
&& !checks.testFlag(SameApplicationCheck::AllowCrossProcesses))
; // "different" apps
else if (c1->pid() == 0 || c2->pid() == 0)
; // old apps that don't have _NET_WM_PID, consider them different

View file

@ -629,9 +629,13 @@ QByteArray ShellClient::windowRole() const
return QByteArray();
}
bool ShellClient::belongsToSameApplication(const AbstractClient *other, bool active_hack) const
bool ShellClient::belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const
{
Q_UNUSED(active_hack)
if (checks.testFlag(SameApplicationCheck::AllowCrossProcesses)) {
if (other->desktopFileName() == desktopFileName()) {
return true;
}
}
if (auto s = other->surface()) {
return s->client() == surface()->client();
}
@ -960,7 +964,7 @@ void ShellClient::takeFocus()
// check that it doesn't belong to the desktop
const auto &clients = waylandServer()->clients();
for (auto c: clients) {
if (!belongsToSameApplication(c, false)) {
if (!belongsToSameApplication(c, SameApplicationChecks())) {
continue;
}
if (c->isDesktop()) {

View file

@ -163,7 +163,7 @@ public:
protected:
void addDamage(const QRegion &damage) override;
bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const override;
bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const override;
void doSetActive() override;
Layer layerForDock() const override;
void changeMaximize(bool horizontal, bool vertical, bool adjust) override;

View file

@ -200,7 +200,7 @@ bool TabBoxHandlerImpl::checkApplications(TabBoxClient* client) const
continue;
}
if ((c = dynamic_cast< TabBoxClientImpl* >(client.data()))) {
if (AbstractClient::belongToSameApplication(c->client(), current)) {
if (AbstractClient::belongToSameApplication(c->client(), current, AbstractClient::SameApplicationCheck::AllowCrossProcesses)) {
return false;
}
}
@ -212,7 +212,7 @@ bool TabBoxHandlerImpl::checkApplications(TabBoxClient* client) const
return false;
}
if ((c = dynamic_cast< TabBoxClientImpl* >(pointer.data()))) {
if (AbstractClient::belongToSameApplication(c->client(), current)) {
if (AbstractClient::belongToSameApplication(c->client(), current, AbstractClient::SameApplicationCheck::AllowCrossProcesses)) {
return true;
}
}