Skip to content

Commit

Permalink
GWL: fix rtl layout issues (#10631)
Browse files Browse the repository at this point in the history
* Grouped-Windows-List:
* fix window label allocation out of bounds in rtl layout (fix #10280)
* fix window count badge position in rtl layout
* allocation code refactor
* moved some appGroup styling into theme
* minor code cleanup

* gwl: Invert progress bar in rtl layout

* gwl: align window rtl text lables correctly

* GWL: fix badge number positioning
  • Loading branch information
ronyala committed Jun 1, 2022
1 parent dd5908a commit 97f3445
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 48 deletions.
6 changes: 5 additions & 1 deletion data/theme/cinnamon.css
Expand Up @@ -1434,6 +1434,7 @@ StScrollBar StButton#vhandle:hover {
padding-left: 4px;
}
.grouped-window-list-number-label {
font-size: 10px;
z-index: 99;
text-shadow: black 1px 0px 2px;
color:#fff;
Expand All @@ -1442,10 +1443,13 @@ StScrollBar StButton#vhandle:hover {
.grouped-window-list-badge {
border-radius: 256px;
background-color: #000000;
margin: 0;
}
.grouped-window-list-button-label {
padding-left: 4px;
padding-left: 6px;
padding-right: 6px;
}

.grouped-window-list-thumbnail-alert {
background: rgba(255,52,52,0.3);
}
Expand Down
Expand Up @@ -21,6 +21,18 @@ const {
TitleDisplay
} = require('./constants');

const _reLetterRtl = new RegExp("\\p{Script=Hebrew}|\\p{Script=Arabic}", "u");
const _reLetter = new RegExp("\\p{L}", "u");
const getTextDirection = function(text) {
for (const l of text) {
if (l.match(_reLetterRtl))
return Clutter.TextDirection.RTL;
if (l.match(_reLetter))
return Clutter.TextDirection.LTR;
}
return Clutter.TextDirection.None;
}

// returns [x1,x2] so that the area between x1 and x2 is
// centered in length

Expand Down Expand Up @@ -118,35 +130,31 @@ class AppGroup {
this.badge = new St.BoxLayout({
style_class: 'grouped-window-list-badge',
important: true,
width: 12 * global.ui_scale,
height: 12 * global.ui_scale,
x_align: St.Align.START,
y_align: St.Align.MIDDLE,
show_on_set_parent: false,
style: 'margin: 0;',
});
this.numberLabel = new St.Label({
style: 'font-size: 10px;padding: 0px;',
style_class: 'grouped-window-list-number-label',
important: true,
text: '',
anchor_x: -3 * global.ui_scale,
anchor_y: 1 + (global.ui_scale > 1 ? 2 : 0)
});
this.numberLabel.clutter_text.ellipsize = false;
this.badge.add(this.numberLabel, {
x_align: St.Align.START,
y_align: St.Align.START,
});
this.actor.add_child(this.badge);
this.badge.set_text_direction(St.TextDirection.LTR);

this.label = new St.Label({
style_class: 'grouped-window-list-button-label',
important: true,
text: '',
x_align: St.Align.START,
show_on_set_parent: this.state.settings.titleDisplay > 1
});
this.label.x_align = St.Align.START;
this.actor.add_child(this.label);

this.groupState.set({tooltip: new Tooltips.PanelItemTooltip({actor: this.actor}, '', this.state.orientation)});
Expand Down Expand Up @@ -358,69 +366,69 @@ class AppGroup {
}

allocate(actor, box, flags) {
let allocWidth = box.x2 - box.x1;
let allocHeight = box.y2 - box.y1;
let childBox = new Clutter.ActorBox();
let direction = this.actor.get_text_direction();
let spacing = 0;
const allocWidth = box.x2 - box.x1;
const allocHeight = box.y2 - box.y1;
const childBox = new Clutter.ActorBox();
const direction = this.actor.get_text_direction();

// Set the icon to be left-justified (or right-justified) and centered vertically
let [minWidth, minHeight, naturalWidth, naturalHeight] = this.iconBox.get_preferred_size();
let yPadding = Math.floor(Math.max(0, allocHeight - naturalHeight) / 2);
const [minWidth, minHeight, naturalWidth, naturalHeight] = this.iconBox.get_preferred_size();
const iconYPadding = Math.floor(Math.max(0, allocHeight - naturalHeight) / 2);

childBox.y1 = box.y1 + yPadding;
childBox.y2 = childBox.y1 + Math.min(naturalHeight, allocHeight);
this.drawLabel = this.labelVisiblePref && allocWidth >= naturalWidth + 10 * global.ui_scale;

if (this.labelVisiblePref && allocWidth < naturalWidth + 10 * global.ui_scale) {
this.drawLabel = false;
} else {
this.drawLabel = this.labelVisiblePref;
}
childBox.y1 = box.y1 + iconYPadding;
childBox.y2 = childBox.y1 + Math.min(naturalHeight, allocHeight);

if (this.drawLabel && this.groupState.metaWindows.length > 0) {
if (direction === Clutter.TextDirection.LTR) {
childBox.x1 = box.x1 + 6;
} else {
childBox.x1 = Math.max(box.x1, box.x2 - naturalWidth);
}
spacing = childBox.x1;
childBox.x1 = direction === Clutter.TextDirection.LTR ?
box.x1 + 6 : Math.max(box.x1, box.x2 - 6 - naturalWidth);
childBox.x2 = Math.min(childBox.x1 + naturalWidth, box.x2);
} else {
let offset = 0;
if (this.state.orientation === St.Side.LEFT) {
offset += this.actor.style_length('border-left-width') * 2;
}
const offset = this.state.orientation === St.Side.LEFT ? this.actor.style_length('border-left-width') * 2 : 0;
[childBox.x1, childBox.x2] = center(allocWidth + offset, naturalWidth);
}

this.iconBox.allocate(childBox, flags);

let windowCountFactor = this.groupState.windowCount > 9 ? 1.5 : 2;
let badgeOffset = 2 * global.ui_scale;
// Set badge position
const windowCountFactor = this.groupState.windowCount > 9 ? 1.5 : 2;
const badgeOffset = 2 * global.ui_scale;
childBox.x1 = childBox.x1 - badgeOffset;
childBox.x2 = childBox.x1 + (this.numberLabel.width * windowCountFactor);
childBox.y1 = Math.max(childBox.y1 - badgeOffset, 0);
childBox.y2 = childBox.y1 + this.badge.get_preferred_height(childBox.get_width())[1];

this.badge.allocate(childBox, flags);

// Set label position
if (this.drawLabel) {
let iconSize = this.state.trigger('getPanelIconSize') * global.ui_scale;
spacing = iconSize - spacing;
[minWidth, minHeight, naturalWidth, naturalHeight] = this.label.get_preferred_size();
const textDirection = getTextDirection(this.label.get_text());
const labelNaturalHeight = this.label.get_preferred_size()[3];
const labelYPadding = Math.floor(Math.max(0, allocHeight - labelNaturalHeight) / 2);

childBox.y1 = box.y1 + labelYPadding;
childBox.y2 = childBox.y1 + Math.min(labelNaturalHeight, allocHeight);

yPadding = Math.floor(Math.max(0, allocHeight - naturalHeight) / 2);
childBox.y1 = box.y1 + yPadding;
childBox.y2 = childBox.y1 + Math.min(naturalHeight, allocHeight);
if (direction === Clutter.TextDirection.LTR) {
// Reuse the values from the previous allocation
childBox.x1 = Math.min(childBox.x2 + spacing, box.x2);
childBox.x1 = Math.min(this.iconBox.x + this.iconBox.width, box.x2);
childBox.x2 = box.x2;
} else {
childBox.x2 = Math.max(childBox.x1 - spacing, box.x1);
childBox.x1 = box.x1;
childBox.x2 = this.iconBox.x;
}

// Set text alignment
if (textDirection === St.TextDirection.LTR)
this.label.set_style('text-align: left;');
else if (textDirection === St.TextDirection.RTL)
this.label.set_style('text-align: right;');
else
if (direction === St.TextDirection.LTR)
this.label.set_style('text-align: left;');
else
this.label.set_style('text-align: right;');

this.label.allocate(childBox, flags);
}

Expand Down Expand Up @@ -455,8 +463,6 @@ class AppGroup {
if (this.label.text == null) {
this.label.set_text('');
}
// TODO: This should be set by the theme.
this.label.set_style('padding-right: 4px;');

if (!animate) {
this.label.show();
Expand Down Expand Up @@ -550,10 +556,15 @@ class AppGroup {

allocateProgress(childBox = null, flags = 0) {
if (!childBox) childBox = new Clutter.ActorBox();
childBox.x1 = 0;
childBox.y1 = 0;
childBox.x2 = Math.max((this.actor.width) * (this.progress / 100.0), 1.0);
childBox.y2 = this.actor.height;
if (St.Widget.get_default_direction() === St.TextDirection.RTL) {
childBox.x1 = Math.max(this.actor.width * ((100 - this.progress) / 100.0), 1.0);
childBox.x2 = this.actor.width;
} else {
childBox.x1 = 0;
childBox.x2 = Math.max(this.actor.width * (this.progress / 100.0), 1.0);
}
this.progressOverlay.allocate(childBox, flags);
}

Expand Down Expand Up @@ -1085,7 +1096,6 @@ class AppGroup {
handleTitleDisplayChange() {
each(this.groupState.metaWindows, (win) => {
this.onWindowTitleChanged(win, true);
this.handleButtonLabel(win);
});
}

Expand Down
Expand Up @@ -615,7 +615,7 @@ class GroupedWindowListApplet extends Applet.Applet {
each(this.appLists, (workspace) => {
each(workspace.appList, (appGroup) => {
if (titleDisplay === TitleDisplay.Focused) {
appGroup.hideLabel(false);
appGroup.hideLabel();
}
appGroup.handleTitleDisplayChange();
});
Expand Down

0 comments on commit 97f3445

Please sign in to comment.