diff --git a/data/gnome-shell-icons.gresource.xml b/data/gnome-shell-icons.gresource.xml
index 275e68adf..db65673b4 100644
--- a/data/gnome-shell-icons.gresource.xml
+++ b/data/gnome-shell-icons.gresource.xml
@@ -5,6 +5,7 @@
scalable/actions/carousel-arrow-next-symbolic.svg
scalable/actions/carousel-arrow-previous-symbolic.svg
scalable/actions/dark-mode-symbolic.svg
+ scalable/actions/notification-expand-symbolic.svg
scalable/actions/ornament-check-symbolic.svg
scalable/actions/ornament-dot-checked-symbolic.svg
scalable/actions/ornament-dot-unchecked-symbolic.svg
diff --git a/data/icons/scalable/actions/notification-expand-symbolic.svg b/data/icons/scalable/actions/notification-expand-symbolic.svg
new file mode 100644
index 000000000..d90d00d0d
--- /dev/null
+++ b/data/icons/scalable/actions/notification-expand-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/data/theme/gnome-shell-sass/widgets/_message-list.scss b/data/theme/gnome-shell-sass/widgets/_message-list.scss
index ce07e412d..5de60208f 100644
--- a/data/theme/gnome-shell-sass/widgets/_message-list.scss
+++ b/data/theme/gnome-shell-sass/widgets/_message-list.scss
@@ -109,7 +109,8 @@
}
}
- // close button
+ // buttons in the message header
+ .message-expand-button,
.message-close-button {
@extend .icon-button;
color: $fg_color;
@@ -119,6 +120,16 @@
&:insensitive { background-color: transparentize($fg_color, 0.9);}
&:active { background-color: transparentize($fg_color, 0.8);}
}
+
+ .message-expand-button {
+ padding: 6px;
+ background-color: transparentize($fg_color, 0.9);
+
+ &:ltr { margin-right: $base_padding; }
+ &:rtl { margin-left: $base_padding; }
+
+ &:hover { background-color: transparentize($fg_color, 0.8);}
+ }
}
// container for message contents
diff --git a/js/ui/calendar.js b/js/ui/calendar.js
index 7d6e670db..fa683de0c 100644
--- a/js/ui/calendar.js
+++ b/js/ui/calendar.js
@@ -1014,7 +1014,6 @@ class CalendarMessageList extends St.Widget {
vertical: true,
x_expand: true,
y_expand: true,
- y_align: Clutter.ActorAlign.START,
});
this._sectionList.connectObject(
'child-added', this._sync.bind(this),
diff --git a/js/ui/messageList.js b/js/ui/messageList.js
index 4fea3a15e..ad93594ef 100644
--- a/js/ui/messageList.js
+++ b/js/ui/messageList.js
@@ -370,6 +370,14 @@ class MessageHeader extends St.BoxLayout {
});
this.add_child(headerContent);
+ this.expandButton = new St.Button({
+ style_class: 'message-expand-button',
+ icon_name: 'notification-expand-symbolic',
+ y_align: Clutter.ActorAlign.CENTER,
+ pivot_point: new Graphene.Point({x: 0.5, y: 0.5}),
+ });
+ this.add_child(this.expandButton);
+
this.closeButton = new St.Button({
style_class: 'message-close-button',
icon_name: 'window-close-symbolic',
@@ -436,7 +444,7 @@ export const Message = GObject.registerClass({
accessible_role: Atk.Role.NOTIFICATION,
can_focus: true,
x_expand: true,
- y_expand: true,
+ y_expand: false,
});
this.expanded = false;
@@ -499,6 +507,24 @@ export const Message = GObject.registerClass({
this._header.closeButton.connect('clicked', this.close.bind(this));
this._header.closeButton.visible = this.canClose();
+
+ this._header.expandButton.connect('clicked', () => {
+ if (this.expanded)
+ this.unexpand(true);
+ else
+ this.expand(true);
+ });
+ this._bodyLabel.connect('notify::allocation', this._updateExpandButton.bind(this));
+ this._updateExpandButton();
+ }
+
+ _updateExpandButton() {
+ if (!this._bodyLabel.has_allocation())
+ return;
+ const layout = this._bodyLabel.clutter_text.get_layout();
+ const canExpand = layout.is_ellipsized() || this.expanded || !!this._actionBin.child;
+ // Use opacity to not trigger a relayout
+ this._header.expandButton.opacity = canExpand ? 255 : 0;
}
close() {
@@ -567,6 +593,7 @@ export const Message = GObject.registerClass({
setActionArea(actor) {
this._actionBin.child = actor;
this._actionBin.visible = actor && this.expanded;
+ this._updateExpandButton();
}
addMediaControl(iconName, callback) {
@@ -597,6 +624,11 @@ export const Message = GObject.registerClass({
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
});
+ this._header.expandButton.ease({
+ rotation_angle_z: 180,
+ duration,
+ });
+
this.emit('expanded');
}
@@ -617,6 +649,11 @@ export const Message = GObject.registerClass({
},
});
+ this._header.expandButton.ease({
+ rotation_angle_z: 0,
+ duration,
+ });
+
this.emit('unexpanded');
}