shift-shell/compositor/WindowManagement.js

281 lines
9.1 KiB
JavaScript
Raw Normal View History

/*
* Copyright 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, 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 Library General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
* Main procedures
*/
function surfaceMapped(surface) {
// Determine if it's a shell window
var firstView = compositor.firstViewOf(surface);
var isShellWindow =
(typeof(firstView.role) != "undefined") ||
2014-12-10 17:16:18 +00:00
(surface.className == "plasmashell.desktop");
// Print some information
2014-12-10 17:16:18 +00:00
if (surface.className == "maliit-server.desktop") {
console.debug("Keyboard surface", surface, "mapped");
console.debug("\tappId:", surface.className);
console.debug("\ttitle:", surface.title);
console.debug("\tsize:", surface.size.width + "x" + surface.size.height);
} else if (isShellWindow) {
console.debug("Shell surface", surface, "mapped");
console.debug("\trole:", firstView.role);
console.debug("\tsize:", surface.size.width + "x" + surface.size.height);
} else {
console.debug("Application surface", surface, "mapped");
console.debug("\tappId:", surface.className);
console.debug("\ttitle:", surface.title);
console.debug("\tsize:", surface.size.width + "x" + surface.size.height);
}
2014-12-10 17:16:18 +00:00
if (surface.className == "maliit-server.desktop") {
mapKeyboardSurface(surface);
// Call a specialized method to deal with application or
// shell windows
2014-12-10 17:16:18 +00:00
} else if (isShellWindow)
mapShellSurface(surface, firstView);
else
mapApplicationSurface(surface);
}
function surfaceUnmapped(surface) {
// Determine if it's a shell window
var firstView = compositor.firstViewOf(surface);
var isShellWindow =
(typeof(firstView.role) != "undefined") ||
2014-12-10 17:16:18 +00:00
(surface.className == "plasmashell.desktop");
// Print some information
if (typeof(firstView.role) == "undefined") {
console.debug("Shell surface", surface, "unmapped");
console.debug("\trole:", firstView.role);
console.debug("\tsize:", surface.size.width + "x" + surface.size.height);
} else {
console.debug("Application surface", surface, "unmapped");
console.debug("\tappId:", surface.className);
console.debug("\ttitle:", surface.title);
}
2014-12-10 17:16:18 +00:00
//Is it maliit?
if (surface.className == "maliit-server.desktop") {
unmapKeyboardSurface(surface);
// Call a specialized method to deal with application or
// shell windows
2014-12-10 17:16:18 +00:00
} else if (isShellWindow)
unmapShellSurface(surface);
else
unmapApplicationSurface(surface);
}
function surfaceDestroyed(surface) {
console.debug("Surface", surface, "destroyed");
// Remove surface from model
var i;
for (i = 0; i < surfaceModel.count; i++) {
var entry = surfaceModel.get(i);
if (entry.surface === surface) {
// Destroy window representation and
// remove the surface from the model
if (entry.window.chrome)
entry.window.chrome.destroy();
entry.window.destroy();
surfaceModel.remove(i, 1);
break;
}
}
}
/*
* Map surfaces
*/
function mapApplicationSurface(surface) {
// Just exit if we already created a window representation
var i;
for (i = 0; i < surfaceModel.count; i++) {
var entry = surfaceModel.get(i);
if (entry.surface === surface) {
// Ask the client to resize
surface.requestSize(window.parent.width, window.parent.height);
return;
}
}
// Create surface item
var component = Qt.createComponent("ClientWindowWrapper.qml");
if (component.status !== Component.Ready) {
console.error(component.errorString());
return;
}
// Request a view for this output although with phones will
// likely have just one output
var child = compositor.viewForOutput(surface, _greenisland_output);
2014-12-09 18:07:50 +00:00
child.resizeSurfaceToItem = true;
child.width = compositorRoot.layers.windows.width;
child.height = compositorRoot.layers.windows.height;
// Create and setup window container
var window = component.createObject(compositorRoot.layers.windows, {"child": child});
compositorRoot.layers.windows.addWindow(window);
window.child.parent = window;
window.child.touchEventsEnabled = true;
window.width = surface.size.width;
window.height = surface.size.height;
2014-10-23 22:22:20 +00:00
// Switch to the applications layer and take focus
2014-11-28 17:46:09 +00:00
compositorRoot.state = "application";
compositorRoot.currentWindow = window;
window.child.takeFocus();
// Run map animation
if (typeof(window.runMapAnimation) != "undefined")
window.runMapAnimation();
// Add surface to the model
surfaceModel.append({"surface": surface, "window": window});
}
function mapShellSurface(surface, child) {
// Shell surfaces have only one view which is passed to us
// as an argument, check whether it's a view for this output
// or not
if (child.output !== _greenisland_output)
return;
// Just set z-index and exit if we already created a
// window representation
var i;
for (i = 0; i < surfaceModel.count; i++) {
var entry = surfaceModel.get(i);
if (entry.surface === surface) {
// Switch to layer and take focus
2014-12-11 09:38:20 +00:00
if (surface.className == "plasmashell.desktop") {
compositorRoot.showPanel = true;
} else {
2014-11-28 17:46:09 +00:00
compositorRoot.state = "homeScreen";
}
2014-12-11 09:38:20 +00:00
entry.window.child.takeFocus();
return;
}
}
// Create surface item
var component = Qt.createComponent("ShellWindowWrapper.qml");
if (component.status !== Component.Ready) {
console.error(component.errorString());
return;
}
// Create and setup window container
2014-10-23 21:00:43 +00:00
// XXX: We only support desktop roles for now
var window = component.createObject(compositorRoot, {"child": child});
2014-12-11 09:38:20 +00:00
window.parent = (surface.className == "plasmashell.desktop") ? compositorRoot.layers.panel : compositorRoot.layers.desktop;
window.child.parent = window;
window.child.touchEventsEnabled = true;
window.x = window.y = 0;
window.width = surface.size.width;
window.height = surface.size.height;
2014-10-23 22:22:20 +00:00
// Switch to the desktop layer and take focus
2014-11-02 21:05:23 +00:00
compositorRoot.showSplash = false;
2014-12-11 09:38:20 +00:00
if (surface.className == "plasmashell.desktop") {
compositorRoot.showPanel = true;
} else {
2014-11-28 17:46:09 +00:00
compositorRoot.state = "homeScreen";
2014-12-10 20:51:48 +00:00
compositorRoot.shellWindow = window;
}
2014-12-11 09:38:20 +00:00
window.child.takeFocus();
// Add surface to the model
surfaceModel.append({"surface": surface, "window": window});
}
2014-12-10 17:16:18 +00:00
function mapKeyboardSurface(surface) {
// Just exit if we already created a window representation
var i;
for (i = 0; i < surfaceModel.count; i++) {
var entry = surfaceModel.get(i);
if (entry.surface === surface) {
compositorRoot.showKeyboard = true;
return;
}
}
// Create surface item
var component = Qt.createComponent("ShellWindowWrapper.qml");
if (component.status !== Component.Ready) {
console.error(component.errorString());
return;
}
// Request a view for this output although with phones will
// likely have just one output
var child = compositor.viewForOutput(surface, _greenisland_output);
// Create and setup window container
var window = component.createObject(compositorRoot.layers.keyboard, {"child": child});
window.parent = compositorRoot.layers.keyboard;
window.child.parent = window;
window.child.touchEventsEnabled = true;
window.width = surface.size.width;
window.height = surface.size.height;
window.y = compositorRoot.layers.keyboard.height - window.height;
// Add surface to the model
surfaceModel.append({"surface": surface, "window": window});
compositorRoot.showKeyboard = true;
}
/*
* Unmap surfaces
*/
function unmapApplicationSurface(surface) {
// Reactivate home layer as soon as an application window is unmapped
2014-11-28 17:46:09 +00:00
compositorRoot.state = "homeScreen";
compositorRoot.currentWindow = null;
}
function unmapShellSurface(surface) {
// Hide panel layer if this is the sliding panel
2014-12-11 09:38:20 +00:00
if (surface.className == "plasmashell.desktop") {
compositorRoot.showPanel = false;
}
}
2014-12-10 17:16:18 +00:00
2014-12-10 20:51:48 +00:00
function unmapKeyboardSurface(surface) {
2014-12-10 17:16:18 +00:00
if (compositorRoot.currentWindow) {
compositorRoot.currentWindow.child.height = compositorRoot.layers.windows.height;
}
compositorRoot.showKeyboard = false;
}