diff --git a/data/theme/gnome-shell-sass/widgets/_misc.scss b/data/theme/gnome-shell-sass/widgets/_misc.scss
index aa543a0e5..8b40e7006 100644
--- a/data/theme/gnome-shell-sass/widgets/_misc.scss
+++ b/data/theme/gnome-shell-sass/widgets/_misc.scss
@@ -53,3 +53,8 @@
@include fontsize($base_font_size - 1);
color: $warning_color;
}
+
+.screen-corner {
+ -screen-corner-radius: $panel_corner_radius;
+ -screen-corner-background-color: black;
+}
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
index c0a77eddc..91babbb44 100644
--- a/js/js-resources.gresource.xml
+++ b/js/js-resources.gresource.xml
@@ -89,6 +89,7 @@
ui/remoteSearch.js
ui/ripples.js
ui/runDialog.js
+ ui/screenCorner.js
ui/screenShield.js
ui/screencast.js
ui/screenshot.js
diff --git a/js/ui/layout.js b/js/ui/layout.js
index 9013aa97b..bd97d0cc8 100644
--- a/js/ui/layout.js
+++ b/js/ui/layout.js
@@ -12,6 +12,7 @@ const DND = imports.ui.dnd;
const Main = imports.ui.main;
const Params = imports.misc.params;
const Ripples = imports.ui.ripples;
+const ScreenCorner = imports.ui.screenCorner;
var STARTUP_ANIMATION_TIME = 500;
var KEYBOARD_ANIMATION_TIME = 150;
@@ -200,6 +201,7 @@ var LayoutManager = GObject.registerClass({
this.primaryMonitor = null;
this.primaryIndex = -1;
this.hotCorners = [];
+ this._screenCorners = [];
this._keyboardIndex = -1;
this._rightPanelBarrier = null;
@@ -440,6 +442,25 @@ var LayoutManager = GObject.registerClass({
this.emit('hot-corners-changed');
}
+ _updateScreenCorners() {
+ // destroy old corners
+ this._screenCorners.forEach(corner => {
+ if (corner)
+ corner.destroy();
+ });
+ this._screenCorners = [];
+
+ // build new corners
+ for (let monitor of this.monitors) {
+ for (let corner of Object.values(Meta.DisplayCorner)) {
+ var actor = new ScreenCorner.ScreenCorner(corner, monitor);
+
+ this.addTopChrome(actor, { trackFullscreen: true });
+ this._screenCorners.push(actor);
+ }
+ }
+ }
+
_addBackgroundMenu(bgManager) {
BackgroundMenu.addBackgroundMenu(bgManager.backgroundActor, this);
}
@@ -540,6 +561,7 @@ var LayoutManager = GObject.registerClass({
this._updateMonitors();
this._updateBoxes();
this._updateHotCorners();
+ this._updateScreenCorners();
this._updateBackgrounds();
this._updateFullscreen();
this._updateVisibility();
diff --git a/js/ui/screenCorner.js b/js/ui/screenCorner.js
new file mode 100644
index 000000000..e7d296813
--- /dev/null
+++ b/js/ui/screenCorner.js
@@ -0,0 +1,79 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+/* exported ScreenCorner */
+
+const { Clutter, GObject, Meta, St } = imports.gi;
+const Cairo = imports.cairo;
+
+const Layout = imports.ui.layout;
+
+var ScreenCorner = GObject.registerClass(
+class ScreenCorner extends St.DrawingArea {
+ _init(corner, monitor) {
+ super._init({ style_class: 'screen-corner' });
+
+ this._corner = corner;
+
+ this.add_constraint(new Layout.MonitorConstraint({ index: monitor.index }));
+
+ if (corner === Meta.DisplayCorner.TOPRIGHT ||
+ corner === Meta.DisplayCorner.BOTTOMRIGHT)
+ this.x_align = Clutter.ActorAlign.END;
+
+ if (corner === Meta.DisplayCorner.BOTTOMLEFT ||
+ corner === Meta.DisplayCorner.BOTTOMRIGHT)
+ this.y_align = Clutter.ActorAlign.END;
+ }
+
+ vfunc_repaint() {
+ let node = this.get_theme_node();
+
+ let cornerRadius = node.get_length("-screen-corner-radius");
+ let backgroundColor = node.get_color('-screen-corner-background-color');
+
+ let cr = this.get_context();
+ cr.setOperator(Cairo.Operator.SOURCE);
+
+ switch (this._corner) {
+ case Meta.DisplayCorner.TOPLEFT:
+ cr.arc(cornerRadius, cornerRadius,
+ cornerRadius, Math.PI, 3 * Math.PI / 2);
+ cr.lineTo(0, 0);
+ break;
+
+ case Meta.DisplayCorner.TOPRIGHT:
+ cr.arc(0, cornerRadius,
+ cornerRadius, 3 * Math.PI / 2, 2 * Math.PI);
+ cr.lineTo(cornerRadius, 0);
+ break;
+
+ case Meta.DisplayCorner.BOTTOMLEFT:
+ cr.arc(cornerRadius, 0,
+ cornerRadius, Math.PI / 2, Math.PI);
+ cr.lineTo(0, cornerRadius);
+ break;
+
+ case Meta.DisplayCorner.BOTTOMRIGHT:
+ cr.arc(0, 0,
+ cornerRadius, 0, Math.PI / 2);
+ cr.lineTo(cornerRadius, cornerRadius);
+ break;
+ }
+
+ cr.closePath();
+
+ Clutter.cairo_set_source_color(cr, backgroundColor);
+ cr.fill();
+
+ cr.$dispose();
+ }
+
+ vfunc_style_changed() {
+ super.vfunc_style_changed();
+
+ let node = this.get_theme_node();
+
+ let cornerRadius = node.get_length("-screen-corner-radius");
+
+ this.set_size(cornerRadius, cornerRadius);
+ }
+});