550 lines
18 KiB
C++
550 lines
18 KiB
C++
/********************************************************************
|
|
KWin - the KDE window manager
|
|
This file is part of the KDE project.
|
|
|
|
Copyright (C) 2010 Rohan Prabhu <rohan@rohanprabhu.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*********************************************************************/
|
|
|
|
#include "client.h"
|
|
|
|
SWrapper::Client::Client(KWin::Client* client) :
|
|
Toplevel(client)
|
|
{
|
|
if (client != 0) {
|
|
QObject::connect(client, SIGNAL(s_clientMoved()), this, SLOT(sl_clientMoved()));
|
|
QObject::connect(client, SIGNAL(maximizeSet(QPair<bool, bool>)), this, SLOT(sl_maximizeSet(QPair<bool, bool>)));
|
|
QObject::connect(client, SIGNAL(s_minimized()), this, SIGNAL(minimized()));
|
|
QObject::connect(client, SIGNAL(s_activated()), this, SIGNAL(gotFocus()));
|
|
QObject::connect(client, SIGNAL(s_fullScreenSet(bool, bool)), this, SIGNAL(fullScreenSet(bool, bool)));
|
|
QObject::connect(client, SIGNAL(s_setKeepAbove(bool)), this, SIGNAL(onSetKeepAbove(bool)));
|
|
QObject::connect(client, SIGNAL(s_unminimized()), this, SIGNAL(unminimized()));
|
|
QObject::connect(this, SIGNAL(unminimized()), this, SIGNAL(restored()));
|
|
}
|
|
|
|
centralObject = client;
|
|
}
|
|
|
|
KWin::Client* SWrapper::Client::getCentralObject()
|
|
{
|
|
return centralObject;
|
|
}
|
|
|
|
/*
|
|
SWrapper::ClientResolution SWrapper::Client::clientResolve(const QScriptEngine*, const KWin::Client* client) {
|
|
if (client == 0) {
|
|
return ClientResolution(0, QScriptValue());
|
|
} else {
|
|
return
|
|
}
|
|
}
|
|
*/
|
|
|
|
void SWrapper::Client::setEngine(QScriptEngine* eng)
|
|
{
|
|
engine = eng;
|
|
}
|
|
|
|
void SWrapper::Client::sl_clientMoved()
|
|
{
|
|
emit clientMoved();
|
|
}
|
|
|
|
void SWrapper::Client::sl_maximizeSet(QPair<bool, bool> param)
|
|
{
|
|
QScriptValue temp = engine->newObject();
|
|
temp.setProperty("v", engine->toScriptValue(param.first));
|
|
temp.setProperty("h", engine->toScriptValue(param.second));
|
|
|
|
emit maximizeSet(temp);
|
|
}
|
|
|
|
/*
|
|
bool SWrapper::Client::clientRelease(const KWin::Client* client) {
|
|
if (client == 0) {
|
|
return false;
|
|
} else {
|
|
if (client->swrapper != 0) {
|
|
delete client->swrapper;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
*/
|
|
|
|
//newWrapper does not search clientMap for existing entries
|
|
//a search must be performed prior to this call.
|
|
//However, since now clientMap is actually a QHash, it wouldn't
|
|
//hurt to perform a check here as well.
|
|
SWrapper::ClientResolution SWrapper::Client::newWrapper(KWin::Client* client, QScriptEngine* eng)
|
|
{
|
|
SWrapper::Client* wrapper = new SWrapper::Client(client);
|
|
wrapper->setEngine(eng);
|
|
QScriptValue value;
|
|
|
|
// Use this value to avoid repeated function generations
|
|
// for function aliases.
|
|
QScriptValue func;
|
|
|
|
/*
|
|
* Step1: Prepping
|
|
* Connect all signals and slots from client to
|
|
* the wrapper object.
|
|
*/
|
|
|
|
|
|
//End of prepping
|
|
|
|
/*
|
|
* Step2: Conversion
|
|
* Wrap the object, set the data parameter
|
|
* and obtain a QScriptValue
|
|
*/
|
|
|
|
value = eng->newQObject(wrapper,
|
|
QScriptEngine::AutoOwnership,
|
|
QScriptEngine::ExcludeSuperClassContents | QScriptEngine::ExcludeDeleteLater
|
|
);
|
|
|
|
wrapper->tl_centralObject = client;
|
|
tl_append(value, eng);
|
|
|
|
//End of Conversion
|
|
|
|
/*
|
|
* Step3: Spice
|
|
* Add the static functions and other things
|
|
* that rely on the value of data() and not the
|
|
* wrapper address.
|
|
*/
|
|
|
|
value.setProperty("caption", eng->newFunction(caption, 0), QScriptValue::Undeletable);
|
|
value.setProperty("close", eng->newFunction(close, 0), QScriptValue::Undeletable);
|
|
value.setProperty("resize", eng->newFunction(resize, 1), QScriptValue::Undeletable);
|
|
value.setProperty("move", eng->newFunction(move, 1), QScriptValue::Undeletable);
|
|
value.setProperty("setGeometry", eng->newFunction(setGeometry, 1), QScriptValue::Undeletable);
|
|
value.setProperty("getWindowInfo", eng->newFunction(getWindowInfo, 0), QScriptValue::Undeletable);
|
|
value.setProperty("isTransient", eng->newFunction(isTransient, 0), QScriptValue::Undeletable);
|
|
value.setProperty("transientFor", eng->newFunction(transientFor, 0), QScriptValue::Undeletable);
|
|
value.setProperty("activate", eng->newFunction(activate, 1), QScriptValue::Undeletable);
|
|
value.setProperty("setCaption", eng->newFunction(setCaption, 1), QScriptValue::Undeletable);
|
|
value.setProperty("setFullScreen", eng->newFunction(setFullScreen, 2), QScriptValue::Undeletable);
|
|
value.setProperty("isFullScreen", eng->newFunction(isFullScreen, 0), QScriptValue::Undeletable);
|
|
value.setProperty("isFullScreenable", eng->newFunction(isFullScreenable, 0), QScriptValue::Undeletable);
|
|
value.setProperty("minimize", eng->newFunction(minimize, 0), QScriptValue::Undeletable);
|
|
value.setProperty("clientGroup", eng->newFunction(clientGroup, 0), QScriptValue::Undeletable);
|
|
value.setProperty("maximize", eng->newFunction(maximize, 0), QScriptValue::Undeletable);
|
|
value.setProperty("setMaximize", eng->newFunction(setMaximize, 2), QScriptValue::Undeletable);
|
|
value.setProperty("desktop", eng->newFunction(desktop, 0), QScriptValue::Undeletable);
|
|
value.setProperty("setKeepAbove", eng->newFunction(setKeepAbove, 0), QScriptValue::Undeletable);
|
|
value.setProperty("setKeepBelow", eng->newFunction(setKeepBelow, 0), QScriptValue::Undeletable);
|
|
|
|
BOOLATTACHCLIENT(isShade)
|
|
BOOLATTACHCLIENT(isShadeable)
|
|
BOOLATTACHCLIENT(isMinimized)
|
|
BOOLATTACHCLIENT(isMinimizable)
|
|
BOOLATTACHCLIENT(isMaximizable)
|
|
BOOLATTACHCLIENT(isResizable)
|
|
BOOLATTACHCLIENT(isMovable)
|
|
BOOLATTACHCLIENT(isMovableAcrossScreens)
|
|
BOOLATTACHCLIENT(isCloseable)
|
|
BOOLATTACHCLIENT(keepAbove)
|
|
BOOLATTACHCLIENT(keepBelow)
|
|
|
|
func = eng->newFunction(unminimize, 0);
|
|
value.setProperty("unminimize", func, QScriptValue::Undeletable);
|
|
value.setProperty("restore", func, QScriptValue::Undeletable);
|
|
|
|
ClientResolution final(wrapper, value);
|
|
|
|
//Finally, append the entire thing to the clientMap
|
|
//clientMap.insert(const_cast<KWin::Client*>(client), ClientResolution(wrapper, value));
|
|
|
|
//And.. we're done
|
|
(client->scriptCache)->insert(eng, final);
|
|
return final;
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::generate(KWin::Client* client, QScriptEngine* eng)
|
|
{
|
|
if (client == 0) {
|
|
return QScriptValue();
|
|
} else {
|
|
ClientResolution res = (client->scriptCache)->value(eng, ClientResolution(0, QScriptValue()));
|
|
|
|
if (res.first != 0) {
|
|
//The required object has been already created
|
|
//Return that instead of creating a new one
|
|
return res.second;
|
|
} else {
|
|
res = newWrapper(client, eng);
|
|
return res.second;
|
|
}
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::setMaximize(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
central->setMaximize((ctx->argument(0)).toBool(), (ctx->argument(1)).toBool());
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
BOOLEXPORTCLIENT(isShade)
|
|
BOOLEXPORTCLIENT(isShadeable)
|
|
BOOLEXPORTCLIENT(isMinimized)
|
|
BOOLEXPORTCLIENT(isMinimizable)
|
|
BOOLEXPORTCLIENT(isMaximizable)
|
|
BOOLEXPORTCLIENT(isResizable)
|
|
BOOLEXPORTCLIENT(isMovable)
|
|
BOOLEXPORTCLIENT(isMovableAcrossScreens)
|
|
BOOLEXPORTCLIENT(isCloseable)
|
|
BOOLEXPORTCLIENT(keepAbove)
|
|
BOOLEXPORTCLIENT(keepBelow)
|
|
|
|
QScriptValue SWrapper::Client::setKeepAbove(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
QScriptValue setValue = ctx->argument(0);
|
|
|
|
if ((central == 0) || (setValue.isUndefined())) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
central->setKeepAbove(eng->fromScriptValue<bool>(setValue));
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::setKeepBelow(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
QScriptValue setValue = ctx->argument(0);
|
|
|
|
if ((central == 0) || (setValue.isUndefined())) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
central->setKeepBelow(eng->fromScriptValue<bool>(setValue));
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::isNormal(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return eng->undefinedValue();
|
|
} else {
|
|
return eng->toScriptValue<bool>(!central->isSpecialWindow());
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::maximize(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
central->setMaximize(1, 1);
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::desktop(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return eng->undefinedValue();
|
|
} else {
|
|
return eng->toScriptValue(central->desktop());
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::clientGroup(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return QScriptValue();
|
|
} else {
|
|
return eng->toScriptValue<KWin::ClientGroup*>(central->clientGroup());
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::caption(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return QScriptValue();
|
|
} else {
|
|
return eng->toScriptValue(central->caption());
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::setCaption(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (ctx->argument(0).isUndefined()) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
QString cap = (ctx->argument(0)).toString();
|
|
central->setCaption(cap);
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::resize(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
QScriptValue arg = ctx->argument(0);
|
|
QSize size;
|
|
bool emitJs;
|
|
QScriptValue emitJsQs;
|
|
|
|
if (central == 0 || arg.isUndefined()) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
if (arg.isNumber()) {
|
|
size = QSize(arg.toInt32(), (ctx->argument(1)).toInt32());
|
|
emitJsQs = ctx->argument(2);
|
|
} else if (arg.isObject()) {
|
|
size = eng->fromScriptValue<QSize>(arg);
|
|
emitJsQs = ctx->argument(1);
|
|
}
|
|
|
|
if (emitJsQs.isUndefined() || !emitJsQs.isValid()) {
|
|
emitJs = true;
|
|
} else {
|
|
emitJs = emitJsQs.toBool();
|
|
}
|
|
|
|
if (size.isValid()) {
|
|
central->plainResize(size, KWin::NormalGeometrySet, emitJs);
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::move(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
QScriptValue arg = ctx->argument(0);
|
|
|
|
if (central == 0 || arg.isUndefined()) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
QPoint point;
|
|
bool emitJs;
|
|
QScriptValue emitJsQs;
|
|
|
|
if (arg.isNumber()) {
|
|
point = QPoint(arg.toInt32(), (ctx->argument(1)).toInt32());
|
|
emitJsQs = ctx->argument(2);
|
|
} else if (arg.isObject()) {
|
|
point = eng->fromScriptValue<QPoint>(arg);
|
|
emitJsQs = ctx->argument(1);
|
|
}
|
|
|
|
if (emitJsQs.isUndefined() || !emitJsQs.isValid()) {
|
|
emitJs = true;
|
|
} else {
|
|
emitJs = emitJsQs.toBool();
|
|
}
|
|
|
|
|
|
central->setGeometry(QRect(point, central->size()), KWin::NormalGeometrySet, emitJs);
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::setGeometry(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
QScriptValue arg = ctx->argument(0);
|
|
QRect rect;
|
|
bool emitJs;
|
|
QScriptValue emitJsQs;
|
|
|
|
if (central == 0 || arg.isUndefined()) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
if (arg.isNumber()) {
|
|
rect = QRect(arg.toInt32(), (ctx->argument(1)).toInt32(),
|
|
(ctx->argument(2)).toInt32(), (ctx->argument(3)).toInt32());
|
|
emitJsQs = ctx->argument(4);
|
|
} else if (arg.isObject()) {
|
|
rect = eng->fromScriptValue<QRect>(arg);
|
|
emitJsQs = ctx->argument(1);
|
|
}
|
|
|
|
if (emitJsQs.isUndefined() || !emitJsQs.isValid()) {
|
|
emitJs = true;
|
|
} else {
|
|
emitJs = emitJsQs.toBool();
|
|
}
|
|
|
|
central->setGeometry(rect, KWin::NormalGeometrySet, emitJs);
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::getWindowInfo(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return QScriptValue();
|
|
} else {
|
|
// For now at least, just get all properties. Tweaking will be taken care
|
|
// of later. TODO
|
|
KWindowInfo info = KWindowSystem::windowInfo(central->window(), -1U, -1U);
|
|
return SWrapper::WindowInfo::generate(info, eng, central);
|
|
}
|
|
}
|
|
|
|
/*
|
|
QString SWrapper::Client::caption() {
|
|
return centralObject->caption();
|
|
}*/
|
|
|
|
QScriptValue SWrapper::Client::unminimize(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
central->unminimize(false);
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::minimize(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
central->minimize(false);
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::close(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return QScriptValue();
|
|
} else {
|
|
central->closeWindow();
|
|
return eng->toScriptValue(true);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::isTransient(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return QScriptValue();
|
|
} else {
|
|
bool x = central->isTransient();
|
|
return eng->toScriptValue(x);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::transientFor(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return QScriptValue();
|
|
} else {
|
|
return eng->toScriptValue(central->transientFor());
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::setFullScreen(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
QScriptValue set = ctx->argument(0);
|
|
QScriptValue user = ctx->argument(0);
|
|
|
|
if (set.isUndefined() || user.isUndefined()) {
|
|
return QScriptValue();
|
|
}
|
|
|
|
if (central == 0) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
central->setFullScreen(set.toBool(), user.toBool());
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::isFullScreen(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return QScriptValue();
|
|
} else {
|
|
return eng->toScriptValue<bool>(central->isFullScreen());
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::isFullScreenable(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
|
|
if (central == 0) {
|
|
return QScriptValue();
|
|
} else {
|
|
return eng->toScriptValue<bool>(central->isFullScreenable());
|
|
}
|
|
}
|
|
|
|
QScriptValue SWrapper::Client::activate(QScriptContext* ctx, QScriptEngine* eng)
|
|
{
|
|
KWin::Client* central = eng->fromScriptValue<KWin::Client*>(ctx->thisObject());
|
|
QScriptValue force = ctx->argument(0);
|
|
bool _force = 0;
|
|
|
|
if (central == 0) {
|
|
return eng->toScriptValue<bool>(0);
|
|
} else {
|
|
if (!force.isBool()) {
|
|
_force = force.toBool();
|
|
}
|
|
|
|
(KWin::Workspace::self())->activateClient(central, _force);
|
|
return eng->toScriptValue<bool>(1);
|
|
}
|
|
}
|