Commit d6466d57 authored by Michael Gratton's avatar Michael Gratton 🤞 Committed by Michael Gratton

Fix GTK+ widget style issues under GTK+ < 3.20.

parent ec9acc89
......@@ -49,20 +49,59 @@ public class ConversationListBox : Gtk.ListBox {
protected const string EXPANDED_CLASS = "geary-expanded";
private const string FIRST_CLASS = "geary-first";
private const string LAST_CLASS = "geary-last";
#if !GTK_3_20
// GTK < 3.20+ style workarounds. Keep this in sync
// with geary.css.
private const int CANT_USE_PADDING_WORKAROUND = 18;
#endif
// The email being displayed by this row, if any
public Geary.Email? email { get; private set; default = null; }
// Is the row showing the email's message body or just headers?
public bool is_expanded { get; protected set; default = false; }
public bool is_expanded {
get {
return this._is_expanded;
}
protected set {
#if !GTK_3_20
// GTK+ < 3.20 style workaround. Keep this in sync
// with geary.css
this.margin_bottom = value ? 6 : 0;
#endif
this._is_expanded = value;
}
}
private bool _is_expanded = false;
// Designate this row as the first visible row in the
// conversation listbox, or not. See Bug 764710 and
// ::update_first_last_row() below.
internal bool is_first {
set {
set_style_context_class(FIRST_CLASS, value);
#if !GTK_3_20
// GTK < 3.20+ style workarounds. Keep this in sync
// with geary.css.
this.margin_top = CANT_USE_PADDING_WORKAROUND;
#endif
}
}
// Designate this row as the last visible row in the
// conversation listbox, or not. See Bug 764710 and
// ::update_last_row() below.
// ::update_first_last_row() below.
internal bool is_last {
set { set_style_context_class(LAST_CLASS, value); }
set {
set_style_context_class(LAST_CLASS, value);
#if !GTK_3_20
// GTK < 3.20+ style workarounds. Keep this in sync
// with geary.css.
this.margin_bottom = CANT_USE_PADDING_WORKAROUND;
#endif
}
}
......@@ -75,6 +114,13 @@ public class ConversationListBox : Gtk.ListBox {
public ConversationRow(Geary.Email? email) {
this.email = email;
show();
#if !GTK_3_20
// GTK < 3.20+ style workarounds. Keep this in sync with
// geary.css.
this.margin_start = CANT_USE_PADDING_WORKAROUND;
this.margin_end = CANT_USE_PADDING_WORKAROUND;
#endif
}
// Request the row be expanded, if supported.
......@@ -249,7 +295,8 @@ public class ConversationListBox : Gtk.ListBox {
// The id of the draft referred to by the current composer.
private Geary.EmailIdentifier? draft_id = null;
// Last visible row in the list, if any
// First and last visible row in the list, if any
private ConversationRow? first_row = null;
private ConversationRow? last_row = null;
// Cached search terms to apply to new messages
......@@ -291,6 +338,10 @@ public class ConversationListBox : Gtk.ListBox {
get_style_context().add_class("background");
get_style_context().add_class("conversation-listbox");
#if !GTK_3_20
// GTK < 3.20+ style workaround
get_style_context().remove_class("list");
#endif
set_adjustment(adjustment);
set_selection_mode(Gtk.SelectionMode.NONE);
......@@ -356,7 +407,7 @@ public class ConversationListBox : Gtk.ListBox {
}
}
update_last_row();
update_first_last_row();
EmailRow? last_email = this.last_row as EmailRow;
if (last_email != null && !this.cancellable.is_cancelled()) {
......@@ -448,7 +499,7 @@ public class ConversationListBox : Gtk.ListBox {
row.enable_should_scroll();
row.should_scroll.connect(() => { scroll_to(row); });
add(row);
update_last_row();
update_first_last_row();
embed.composer.draft_id_changed.connect((id) => { this.draft_id = id; });
embed.vanished.connect(() => {
......@@ -684,7 +735,7 @@ public class ConversationListBox : Gtk.ListBox {
if (!this.cancellable.is_cancelled()) {
EmailRow row = add_email(full_email);
update_last_row();
update_first_last_row();
yield row.view.start_loading(this.cancellable);
}
}
......@@ -793,9 +844,24 @@ public class ConversationListBox : Gtk.ListBox {
// Due to Bug 764710, we can only use the CSS :last-child selector
// for GTK themes after 3.20.3, so for now manually maintain a
// class on the last box so we can emulate it
private void update_last_row() {
private void update_first_last_row() {
ConversationRow? first = null;
ConversationRow? last = null;
this.foreach((child) => { last = (ConversationRow) child; });
this.foreach((child) => {
if (first == null) {
first = (ConversationRow) child;
}
last = (ConversationRow) child;
});
if (this.first_row != first) {
if (this.first_row != null) {
this.first_row.is_first = false;
}
this.first_row = first;
this.first_row.is_first = true;
}
if (this.last_row != last) {
if (this.last_row != null) {
......
......@@ -301,6 +301,12 @@ public class ConversationMessage : Gtk.Grid {
this.contact_store = contact_store;
this.always_load_remote_images = always_load_remote_images;
#if !GTK_3_20
// GTK < 3.20+ style workarounds. Keep this in sync with
// geary.css.
this.summary.border_width = 12;
#endif
// Actions
add_action(ACTION_COPY_EMAIL, true, VariantType.STRING)
......
......@@ -6,6 +6,14 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
/*
* Since GTK+ 3.20 introduced some significant breaking changes to CSS
* node names for styling GTK+ widgets, we need to duplicate selectors
* that either either refer to a widget by node name (e.g. "GtkLabel"
* vs "label"), or that referrs to any child nodes introduced by 3.20
* (e.g. "frame > border").
*/
.geary-folder-frame, /* GTK < 3.20 */
.geary-folder-frame > border {
border-left-width: 0;
......@@ -24,9 +32,11 @@
border-bottom-width: 0;
}
.geary-composer-box, /* GTK < 3.20 */
.geary-composer-box > border {
border-width: 0px;
}
.geary-composer-body, /* GTK < 3.20 */
.geary-composer-body > border {
border-left-width: 0;
border-right-width: 0;
......@@ -44,12 +54,14 @@
/* FolderPopover */
.list-row.geary-folder-popover-list-row, /* GTK < 3.20 */
row.geary-folder-popover-list-row {
padding: 6px;
border-color: @borders;
border-style: groove;
border-bottom-width: 1px;
}
.list-row.geary-folder-popover-list-row > GtkLabel, /* GTK < 3.20 */
row.geary-folder-popover-list-row > label {
color: @theme_text_color;
}
......@@ -59,6 +71,7 @@ row.geary-folder-popover-list-row > label {
.conversation-listbox {
padding: 18px;
}
.conversation-listbox > .list-row, /* GTK < 3.20 */
.conversation-listbox > row {
margin: 0;
border: 1px solid @borders;
......@@ -67,71 +80,86 @@ row.geary-folder-popover-list-row > label {
box-shadow: 0 4px 8px 1px rgba(0,0,0,0.4);
transition: margin 0.1s;
}
.conversation-listbox > .list-row > GtkBox, /* GTK < 3.20 */
.conversation-listbox > row > box {
background: @theme_base_color;
transition: background 0.25s;
}
.conversation-listbox > .list-row:hover > GtkBox, /* GTK < 3.20 */
.conversation-listbox > row:hover > box {
background: shade(@theme_base_color, 0.96);
}
.conversation-listbox > .list-row.geary-expanded, /* GTK < 3.20 */
.conversation-listbox > row.geary-expanded {
margin-bottom: 6px;
border-bottom-width: 1px;
}
.conversation-listbox > .list-row.geary-match GtkFlowBox > *.geary-match, /* GTK < 3.20 */
.conversation-listbox > row.geary-match flowboxchild.geary-match {
color: @theme_selected_fg_color;
background: @theme_selected_bg_color;
}
.conversation-listbox > .list-row.geary-last, /* GTK < 3.20 */
.conversation-listbox > row.geary-last {
margin-bottom: 0;
}
/* ConversationEmail */
.geary-unread .geary-message-summary {
.geary-unread, ConversationMessage, /* GTK < 3.20 */
.geary-unread grid.geary-message-summary {
border-color: @theme_selected_bg_color;
transition: border 0.25s;
}
/* ConversationMessage */
.geary-message-summary {
ConversationMessage, /* GTK < 3.20 */
grid.geary-message-summary {
border-top: 4px solid transparent;
padding: 12px;
padding-top: 8px;
transition: border 4s;
}
.geary-headers GtkLabel, /* GTK < 3.20 */
.geary-headers label {
margin: 0;
padding: 1px;
}
.geary-headers GtkLabel.geary-header, /* GTK < 3.20 */
.geary-headers label.geary-header {
padding-right: 6px;
}
.geary-headers GtkFlowBox > *, /* GTK < 3.20 */
.geary-headers flowboxchild {
margin: 0;
padding: 1px;
}
.geary-headers GtkFlowBox > * GtkLabel, /* GTK < 3.20 */
.geary-headers flowboxchild label {
margin: 0;
padding: 0;
}
.geary-headers GtkLabel.geary-from, /* GTK < 3.20 */
.geary-headers label.geary-from {
font-weight: bold;
}
.geary-header-value flowboxchild:active {
.geary-header-value > *:active, /* GTK < 3.20 */
.geary-header-value > flowboxchild:active {
background: mix(@theme_base_color, @theme_bg_color, 0.5);
}
.geary-header-value flowboxchild:hover {
.geary-header-value > *:hover, /* GTK < 3.20 */
.geary-header-value > flowboxchild:hover {
background: @theme_base_color;
}
.geary-header-value flowboxchild label.dim-label {
margin-left: 6px;
.geary-header-value > * GtkLabel.dim-label, /* GTK < 3.20 */
.geary-header-value > flowboxchild label.dim-label {
padding-left: 6px; /* Would be margin-left, but GTK 3.14 doesn't like it */
}
.geary-submessages .geary-message {
......@@ -140,6 +168,7 @@ row.geary-folder-popover-list-row > label {
/* Composer */
.geary-composer-embed GtkHeaderBar, /* GTK < 3.20 */
.geary-composer-embed headerbar {
border-top: 1px solid @borders;
border-radius: 0px;
......@@ -147,6 +176,7 @@ row.geary-folder-popover-list-row > label {
/* EmptyPlaceholder */
.geary-empty-placeholder > GtkImage, /* GTK < 3.20 */
.geary-empty-placeholder > image {
margin-bottom: 12px;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment