Skip to content
This repository has been archived by the owner on Nov 4, 2023. It is now read-only.

Notch support #442

Open
wants to merge 4 commits into
base: xenial
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions data/com.canonical.Unity8.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
<summary>Whether the OSK switch should be visible</summary>
<description>Toggle the visibility of the OSK switch</description>
</key>
<key type="b" name="disable-top-margin">
<default>false</default>
<summary>Disable top margin for the notch</summary>
<description>This will restore the previous behavior on devices with a notch. If this option is enabled some indicators might not be visible.</description>
</key>
</schema>

<schema path="/com/canonical/unity8/greeter/" id="com.canonical.Unity8.Greeter" gettext-domain="unity8">
Expand Down
18 changes: 18 additions & 0 deletions plugins/Utils/deviceconfigparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,24 @@ bool DeviceConfigParser::readBoolFromConfig(const QString &key, bool defaultValu
return ret;
}

int DeviceConfigParser::topMargin() const
{
return readIntegerFromConfig("TopMargin", 0);
}

int DeviceConfigParser::readIntegerFromConfig(const QString &key, int defaultValue) const
{
m_config->beginGroup(m_name);

int ret = defaultValue;
if (m_config->contains(key)) {
ret = m_config->value(key).toInt();
}

m_config->endGroup();
return ret;
}

QStringList DeviceConfigParser::readOrientationsFromConfig(const QString &key) const
{
m_config->beginGroup(m_name);
Expand Down
3 changes: 3 additions & 0 deletions plugins/Utils/deviceconfigparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class DeviceConfigParser: public QObject
Q_PROPERTY(Qt::ScreenOrientation invertedPortraitOrientation READ invertedPortraitOrientation NOTIFY changed)
Q_PROPERTY(QString category READ category NOTIFY changed)
Q_PROPERTY(bool supportsMultiColorLed READ supportsMultiColorLed NOTIFY changed)
Q_PROPERTY(int topMargin READ topMargin NOTIFY changed)

public:
DeviceConfigParser(QObject *parent = nullptr);
Expand All @@ -49,6 +50,7 @@ class DeviceConfigParser: public QObject
Qt::ScreenOrientation invertedPortraitOrientation() const;
QString category() const;
bool supportsMultiColorLed() const;
int topMargin() const;

Q_SIGNALS:
void changed();
Expand All @@ -61,6 +63,7 @@ class DeviceConfigParser: public QObject
QString readOrientationFromConfig(const QString &key) const;
Qt::ScreenOrientation stringToOrientation(const QString &orientationString, Qt::ScreenOrientation defaultValue) const;
bool readBoolFromConfig(const QString &key, bool defaultValue) const;
int readIntegerFromConfig(const QString &key, int defaultValue) const;
};

#endif
19 changes: 19 additions & 0 deletions qml/DeviceConfiguration.qml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ QtObject {
readonly property alias invertedLandscapeOrientation: priv.invertedLandscapeOrientation
readonly property alias portraitOrientation: priv.portraitOrientation
readonly property alias invertedPortraitOrientation: priv.invertedPortraitOrientation
readonly property alias topMargin: priv.topMargin

readonly property alias category: priv.category

Expand All @@ -55,6 +56,7 @@ QtObject {
property int invertedPortraitOrientation: deviceConfigParser.invertedPortraitOrientation
property string category: deviceConfigParser.category
property bool supportsMultiColorLed: deviceConfigParser.supportsMultiColorLed
property int topMargin: deviceConfigParser.topMargin

states: [
State {
Expand Down Expand Up @@ -104,6 +106,22 @@ QtObject {
category: "phone"
}
},
State {
name: "has-notch"
PropertyChanges {
target: priv
primaryOrientation: root.useNativeOrientation
supportedOrientations: Qt.PortraitOrientation
| Qt.LandscapeOrientation
| Qt.InvertedLandscapeOrientation
landscapeOrientation: Qt.LandscapeOrientation
invertedLandscapeOrientation: Qt.InvertedLandscapeOrientation
portraitOrientation: Qt.PortraitOrientation
invertedPortraitOrientation: Qt.InvertedPortraitOrientation
category: "phone"
topMargin: 20
}
},
State {
name: "manta"
PropertyChanges {
Expand Down Expand Up @@ -147,6 +165,7 @@ QtObject {
portraitOrientation: Qt.PortraitOrientation
invertedPortraitOrientation: Qt.InvertedPortraitOrientation
category: "desktop"
topMargin: 0
}
},
State {
Expand Down
127 changes: 67 additions & 60 deletions qml/OrientedShell.qml
Original file line number Diff line number Diff line change
Expand Up @@ -263,74 +263,81 @@ Item {
shellSnapshot: shellSnapshot
}

Shell {
id: shell
objectName: "shell"
width: root.width
height: root.height
orientation: root.angleToOrientation(orientationAngle)
orientations: root.orientations
nativeWidth: root.width
nativeHeight: root.height
mode: applicationArguments.mode
interactiveBlur: applicationArguments.interactiveBlur
hasMouse: pointerInputDevices > 0
hasKeyboard: keyboardsModel.count > 0
hasTouchscreen: touchScreensModel.count > 0
supportsMultiColorLed: deviceConfiguration.supportsMultiColorLed
lightIndicators: root.lightIndicators

// Since we dont have proper multiscreen support yet
// hardcode screen count to only show osk on this screen
// when it's the only one connected.
// FIXME once multiscreen has landed
oskEnabled: (!hasKeyboard && screens.count === 1) ||
unity8Settings.alwaysShowOsk || forceOSKEnabled

usageScenario: {
if (unity8Settings.usageMode === "Windowed") {
return "desktop";
} else {
if (deviceConfiguration.category === "phone") {
return "phone";
Item {
id: shellContainer
objectName: "shellContainer"
anchors.fill: parent
anchors.topMargin: !unity8Settings.disableTopMargin ? deviceConfiguration.topMargin : 0

Shell {
id: shell
objectName: "shell"
width: parent.width
height: parent.height
orientation: root.angleToOrientation(orientationAngle)
orientations: root.orientations
nativeWidth: parent.width
nativeHeight: parent.height
mode: applicationArguments.mode
interactiveBlur: applicationArguments.interactiveBlur
hasMouse: pointerInputDevices > 0
hasKeyboard: keyboardsModel.count > 0
hasTouchscreen: touchScreensModel.count > 0
supportsMultiColorLed: deviceConfiguration.supportsMultiColorLed
lightIndicators: root.lightIndicators

// Since we dont have proper multiscreen support yet
// hardcode screen count to only show osk on this screen
// when it's the only one connected.
// FIXME once multiscreen has landed
oskEnabled: (!hasKeyboard && screens.count === 1) ||
unity8Settings.alwaysShowOsk || forceOSKEnabled

usageScenario: {
if (unity8Settings.usageMode === "Windowed") {
return "desktop";
} else {
return "tablet";
if (deviceConfiguration.category === "phone") {
return "phone";
} else {
return "tablet";
}
}
}
}

property real transformRotationAngle
property real transformOriginX
property real transformOriginY
property real transformRotationAngle
property real transformOriginX
property real transformOriginY

transform: Rotation {
origin.x: shell.transformOriginX; origin.y: shell.transformOriginY; axis { x: 0; y: 0; z: 1 }
angle: shell.transformRotationAngle
transform: Rotation {
origin.x: shell.transformOriginX; origin.y: shell.transformOriginY; axis { x: 0; y: 0; z: 1 }
angle: shell.transformRotationAngle
}
}
}

Rectangle {
id: shellCover
color: "black"
anchors.fill: parent
visible: false
}
Rectangle {
id: shellCover
color: "black"
anchors.fill: parent
visible: false
}

ItemSnapshot {
id: shellSnapshot
target: shell
visible: false
width: root.width
height: root.height

property real transformRotationAngle
property real transformOriginX
property real transformOriginY

transform: Rotation {
origin.x: shellSnapshot.transformOriginX; origin.y: shellSnapshot.transformOriginY;
axis { x: 0; y: 0; z: 1 }
angle: shellSnapshot.transformRotationAngle
ItemSnapshot {
id: shellSnapshot
target: shell
visible: false
width: parent.width
height: parent.height

property real transformRotationAngle
property real transformOriginX
property real transformOriginY

transform: Rotation {
origin.x: shellSnapshot.transformOriginX; origin.y: shellSnapshot.transformOriginY;
axis { x: 0; y: 0; z: 1 }
angle: shellSnapshot.transformRotationAngle
}
}
}
}
4 changes: 2 additions & 2 deletions qml/Rotation/HalfLoopRotationAnimation.qml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ SequentialAnimation {
ScriptAction { script: {
info.transitioning = true;
shell.orientationAngle = root.toAngle;
shell.x = (orientedShell.width - shell.width) / 2
shell.y = (orientedShell.height - shell.height) / 2;
shell.x = (shellContainer.width - shell.width) / 2
shell.y = (shellContainer.height - shell.height) / 2;
shell.transformOriginX = shell.width / 2;
shell.transformOriginY = shell.height / 2;
shell.updateFocusedAppOrientation();
Expand Down
12 changes: 6 additions & 6 deletions qml/Rotation/NinetyRotationAnimation.qml
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ SequentialAnimation {
property var info
property var shell

readonly property real fromY: fromAngle === 0 || fromAngle === 90 ? 0 : orientedShell.height - orientedShell.width;
readonly property real toY: toAngle === 0 || toAngle === 90 ? 0 : orientedShell.height - orientedShell.width;
readonly property real fromY: fromAngle === 0 || fromAngle === 90 ? 0 : shellContainer.height - shellContainer.width;
readonly property real toY: toAngle === 0 || toAngle === 90 ? 0 : shellContainer.height - shellContainer.width;
readonly property bool flipShellDimensions: toAngle == 90 || toAngle == 270

ScriptAction { script: {
info.transitioning = true;

shell.orientationAngle = root.toAngle;
shell.x = 0;
shell.width = flipShellDimensions ? orientedShell.height : orientedShell.width;
shell.height = flipShellDimensions ? orientedShell.width : orientedShell.height;
shell.transformOriginX = orientedShell.width / 2;
shell.transformOriginY = orientedShell.width / 2;
shell.width = flipShellDimensions ? shellContainer.height : shellContainer.width;
shell.height = flipShellDimensions ? shellContainer.width : shellContainer.height;
shell.transformOriginX = shellContainer.width / 2;
shell.transformOriginY = shellContainer.width / 2;
shell.updateFocusedAppOrientation();
shellCover.visible = true;

Expand Down
13 changes: 7 additions & 6 deletions qml/Rotation/UpdateShellTransformations.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,18 @@ ScriptAction {
shell.transformRotationAngle = rotationAngle;

// They must all be bindings as orientedShell's size can change
// ( shellContainer takes into account the margin in case a notch is present )

if (rotationAngle === 90 || rotationAngle === 270) {
shell.width = Qt.binding(function() { return orientedShell.height; });
shell.height = Qt.binding(function() { return orientedShell.width; });
shell.width = Qt.binding(function() { return shellContainer.height; });
shell.height = Qt.binding(function() { return shellContainer.width; });
} else {
shell.width = Qt.binding(function() { return orientedShell.width; });
shell.height = Qt.binding(function() { return orientedShell.height; });
shell.width = Qt.binding(function() { return shellContainer.width; });
shell.height = Qt.binding(function() { return shellContainer.height; });
}

shell.x = Qt.binding(function() { return (orientedShell.width - shell.width) / 2; });
shell.y = Qt.binding(function() { return (orientedShell.height - shell.height) / 2; });
shell.x = Qt.binding(function() { return (shellContainer.width - shell.width) / 2; });
shell.y = Qt.binding(function() { return (shellContainer.height - shell.height) / 2; });
shell.transformOriginX = Qt.binding(function() { return shell.width / 2; });
shell.transformOriginY = Qt.binding(function() { return shell.height / 2; });
}
Expand Down
31 changes: 31 additions & 0 deletions tests/mocks/GSettings.1.0/fake_gsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ GSettingsControllerQml::GSettingsControllerQml()
, m_edgeDragWidth(2)
, m_enableIndicatorMenu(true)
, m_oskSwitchVisible(false)
, m_disableTopMargin(false)
{
}

Expand Down Expand Up @@ -173,6 +174,19 @@ void GSettingsControllerQml::setOskSwitchVisible(bool oskSwitchVisible)
}
}

bool GSettingsControllerQml::disableTopMargin() const
{
return m_disableTopMargin;
}

void GSettingsControllerQml::setDisableTopMargin(bool disableTopMargin)
{
if (m_disableTopMargin != disableTopMargin) {
m_disableTopMargin = disableTopMargin;
Q_EMIT disableTopMarginChanged(disableTopMargin);
}
}

GSettingsSchemaQml::GSettingsSchemaQml(QObject *parent): QObject(parent) {
}

Expand Down Expand Up @@ -241,6 +255,8 @@ void GSettingsQml::componentComplete()
this, &GSettingsQml::enableIndicatorMenuChanged);
connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::oskSwitchVisibleChanged,
this, &GSettingsQml::oskSwitchVisibleChanged);
connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::disableTopMarginChanged,
this, &GSettingsQml::disableTopMarginChanged);

Q_EMIT disableHeightChanged();
Q_EMIT pictureUriChanged();
Expand Down Expand Up @@ -374,6 +390,14 @@ QVariant GSettingsQml::oskSwitchVisible() const
return QVariant();
}

QVariant GSettingsQml::disableTopMargin() const
{
if (m_valid && m_schema->id() == "com.canonical.Unity8") {
return GSettingsControllerQml::instance()->disableTopMargin();
}
return QVariant();
}

void GSettingsQml::setLifecycleExemptAppids(const QVariant &appIds)
{
if (m_valid && m_schema->id() == "com.canonical.qtmir") {
Expand Down Expand Up @@ -415,3 +439,10 @@ void GSettingsQml::setOskSwitchVisible(const QVariant &oskSwitchVisible)
GSettingsControllerQml::instance()->setOskSwitchVisible(oskSwitchVisible.toBool());
}
}

void GSettingsQml::setDisableTopMargin(const QVariant &disableTopMargin)
{
if (m_valid && m_schema->id() == "com.canonical.Unity8") {
GSettingsControllerQml::instance()->setDisableTopMargin(disableTopMargin.toBool());
}
}
Loading