mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-26 14:23: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)
|
||||
|
||||
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(shell org.kde.satellite.phone shells)
|
||||
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