mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-28 14:43:09 +00:00
QML compositor based on Green Island
Add an initial compositor written with QML for Green Island.
This commit is contained in:
parent
28e7ccacd8
commit
2b09246010
7 changed files with 352 additions and 0 deletions
|
|
@ -33,6 +33,7 @@ feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAG
|
||||||
|
|
||||||
include(CheckIncludeFiles)
|
include(CheckIncludeFiles)
|
||||||
|
|
||||||
|
plasma_install_package(compositor org.kde.satellite.compositor.phone greenisland/compositors)
|
||||||
plasma_install_package(look-and-feel org.kde.satellite.phone look-and-feel)
|
plasma_install_package(look-and-feel org.kde.satellite.phone look-and-feel)
|
||||||
plasma_install_package(shell org.kde.satellite.phone shells)
|
plasma_install_package(shell org.kde.satellite.phone shells)
|
||||||
install(DIRECTORY wallpaper/ DESTINATION "${WALLPAPER_INSTALL_DIR}/org.kde.satellite.lockers")
|
install(DIRECTORY wallpaper/ DESTINATION "${WALLPAPER_INSTALL_DIR}/org.kde.satellite.lockers")
|
||||||
|
|
|
||||||
24
compositor/contents/ClientWindowWrapper.qml
Normal file
24
compositor/contents/ClientWindowWrapper.qml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
WindowWrapper {
|
||||||
|
objectName: "clientWindow"
|
||||||
|
}
|
||||||
60
compositor/contents/Compositor.qml
Normal file
60
compositor/contents/Compositor.qml
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import "WindowManagement.js" as WindowManagement
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
readonly property alias layers: layers
|
||||||
|
readonly property real topBarHeight: units.iconSizes.small
|
||||||
|
|
||||||
|
id: compositorRoot
|
||||||
|
color: "black"
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: surfaceModel
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: compositor
|
||||||
|
onSurfaceMapped: WindowManagement.surfaceMapped(surface)
|
||||||
|
onSurfaceUnmapped: WindowManagement.surfaceUnmapped(surface)
|
||||||
|
onSurfaceDestroyed: WindowManagement.surfaceDestroyed(surface)
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
readonly property alias desktop: desktopLayer
|
||||||
|
readonly property alias windows: windowsLayer
|
||||||
|
|
||||||
|
id: layers
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: desktopLayer
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: windowsLayer
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: topBarHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
compositor/contents/ShellWindowWrapper.qml
Normal file
24
compositor/contents/ShellWindowWrapper.qml
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
WindowWrapper {
|
||||||
|
objectName: "shellWindow"
|
||||||
|
}
|
||||||
192
compositor/contents/WindowManagement.js
Normal file
192
compositor/contents/WindowManagement.js
Normal file
|
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
* 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) {
|
||||||
|
// Get the first view and if it has a role property than this
|
||||||
|
// is definitely a shell window
|
||||||
|
var firstView = compositor.firstViewOf(surface);
|
||||||
|
if (typeof(firstView.role) == "undefined") {
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
console.debug("Shell surface", surface, "mapped");
|
||||||
|
console.debug("\trole:", firstView.role);
|
||||||
|
console.debug("\tsize:", surface.size.width + "x" + surface.size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call a specialized method to deal with application or
|
||||||
|
// shell windows
|
||||||
|
if (typeof(firstView.role) == "undefined")
|
||||||
|
mapApplicationSurface(surface);
|
||||||
|
else
|
||||||
|
mapShellSurface(surface, firstView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function surfaceUnmapped(surface) {
|
||||||
|
// Get the first view and if it has a role property than this
|
||||||
|
// is definitely a shell window
|
||||||
|
var firstView = compositor.firstViewOf(surface);
|
||||||
|
if (typeof(firstView.role) == "undefined") {
|
||||||
|
console.debug("Application surface", surface, "unmapped");
|
||||||
|
console.debug("\tappId:", surface.className);
|
||||||
|
console.debug("\ttitle:", surface.title);
|
||||||
|
} else {
|
||||||
|
console.debug("Shell surface", surface, "unmapped");
|
||||||
|
console.debug("\trole:", firstView.role);
|
||||||
|
console.debug("\tsize:", surface.size.width + "x" + surface.size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call a specialized method to deal with application or
|
||||||
|
// shell windows
|
||||||
|
if (typeof(firstView.role) == "undefined")
|
||||||
|
unmapApplicationSurface(surface);
|
||||||
|
else
|
||||||
|
unmapShellSurface(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)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create surface item
|
||||||
|
var component = Qt.createComponent("ClientWindowWrapper.qml");
|
||||||
|
if (component.status !== Component.Ready) {
|
||||||
|
console.error(component.errorString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window position: y is hard coded to the top bar height
|
||||||
|
var pos = Qt.point(0, compositorRoot.topBarHeight);
|
||||||
|
|
||||||
|
// 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, {"child": child});
|
||||||
|
window.child.parent = window;
|
||||||
|
window.child.touchEventsEnabled = true;
|
||||||
|
window.width = surface.size.width;
|
||||||
|
window.height = surface.size.height;
|
||||||
|
|
||||||
|
// Move window
|
||||||
|
window.x = pos.x;
|
||||||
|
window.y = pos.y;
|
||||||
|
|
||||||
|
// Reparent and give focus
|
||||||
|
window.parent = compositorRoot.layers.windows;
|
||||||
|
window.child.takeFocus();
|
||||||
|
|
||||||
|
// Set size to parent (windows layer)
|
||||||
|
window.child.resizeSurfaceToItem = true;
|
||||||
|
window.width = window.parent.width;
|
||||||
|
window.height = window.parent.height;
|
||||||
|
|
||||||
|
// Log coordinates for debugging purpose
|
||||||
|
console.debug("\tposition:", window.x + "," + window.y);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// Create surface item
|
||||||
|
var component = Qt.createComponent("ShellWindowWrapper.qml");
|
||||||
|
if (component.status !== Component.Ready) {
|
||||||
|
console.error(component.errorString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and setup window container
|
||||||
|
var window = component.createObject(compositorRoot, {"child": child});
|
||||||
|
window.child.parent = window;
|
||||||
|
window.child.touchEventsEnabled = true;
|
||||||
|
window.width = surface.size.width;
|
||||||
|
window.height = surface.size.height;
|
||||||
|
|
||||||
|
// Set initial position
|
||||||
|
// XXX: We only support desktop roles for now
|
||||||
|
window.x = window.y = 0;
|
||||||
|
|
||||||
|
// Set appropriate parent
|
||||||
|
// XXX: We only support desktop roles for now
|
||||||
|
window.parent = compositorRoot.layers.desktop;
|
||||||
|
|
||||||
|
// Log coordinates for debugging purpose
|
||||||
|
console.debug("\tposition:", window.x + "," + window.y);
|
||||||
|
|
||||||
|
// Add surface to the model
|
||||||
|
surfaceModel.append({"surface": surface, "window": window});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unmap surfaces
|
||||||
|
*/
|
||||||
|
|
||||||
|
function unmapApplicationSurface(surface) {
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmapShellSurface(surface) {
|
||||||
|
}
|
||||||
37
compositor/contents/WindowWrapper.qml
Normal file
37
compositor/contents/WindowWrapper.qml
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtCompositor 1.0
|
||||||
|
import GreenIsland 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property var child
|
||||||
|
property var role: child.surface.windowProperties.role
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (child)
|
||||||
|
child.surface.clientRenderingEnabled = visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
SurfaceRenderer {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: child
|
||||||
|
}
|
||||||
|
}
|
||||||
14
compositor/metadata.desktop
Normal file
14
compositor/metadata.desktop
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Phone
|
||||||
|
Type=Service
|
||||||
|
|
||||||
|
X-KDE-ServiceTypes=GreenIsland/Compositor
|
||||||
|
X-KDE-ParentApp=
|
||||||
|
X-KDE-PluginInfo-Author=Pier Luigi Fiorini
|
||||||
|
X-KDE-PluginInfo-Category=
|
||||||
|
X-KDE-PluginInfo-Email=pierluigi.fiorini@gmail.com
|
||||||
|
X-KDE-PluginInfo-License=GPLv2+
|
||||||
|
X-KDE-PluginInfo-Name=org.kde.satellite.compositor.phone
|
||||||
|
X-KDE-PluginInfo-Version=0.1
|
||||||
|
X-KDE-PluginInfo-Website=
|
||||||
|
|
||||||
Loading…
Reference in a new issue