Bug 529405 - CTabFolder has maximize/minimize icons and no chevron
Summary: CTabFolder has maximize/minimize icons and no chevron
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.7   Edit
Hardware: All All
: P2 critical (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-01-04 05:25 EST by Simeon Andreev CLA
Modified: 2020-11-05 04:52 EST (History)
3 users (show)

See Also:


Attachments
Screenshot showing the minimize/maximize buttons and no chevron for CTabFolder. (4.19 KB, image/png)
2018-01-04 05:25 EST, Simeon Andreev CLA
no flags Details
Screenshot with expected chevron and no minimize/maximize button. (4.25 KB, image/png)
2018-01-04 05:27 EST, Simeon Andreev CLA
no flags Details
Chevron is painted as a menu if minimize/maximize buttons are clicked. It goes away on click anywhere else. (4.56 KB, image/png)
2018-01-04 05:33 EST, Simeon Andreev CLA
no flags Details
Example plugin to reproduce the problem with. Run plugin code as Java application. (3.54 KB, application/zip)
2018-01-04 06:05 EST, Simeon Andreev CLA
no flags Details
Chevron and tabs have mismatched height, resulting in odd behavior when resizing and selecting tabs. (28.77 KB, image/gif)
2018-01-04 06:36 EST, Simeon Andreev CLA
no flags Details
When the chevron/min/max toolbar cannot be drawn due to small size, a fixed size fixed button representation is drawn. (4.67 KB, image/png)
2018-01-04 08:54 EST, Simeon Andreev CLA
no flags Details
Hovering on the toolbar representation shows the available actions, chevron/min/max. (5.57 KB, image/png)
2018-01-04 08:55 EST, Simeon Andreev CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Simeon Andreev CLA 2018-01-04 05:25:23 EST
Created attachment 272123 [details]
Screenshot showing the minimize/maximize buttons and no chevron for CTabFolder.

See attached screenshot. The minimize/maximize buttons are disabled both in this example and in our actual product (where there is content that could potentially be maximized/minimized, but should not be).

No chevron is available to switch between tabs. The only option to switch betwen tabs is to resize the window.

Snippet to reproduce the problem with:

Display display = new Display();
Shell shell = new Shell(display);
shell.setSize(200, 200);
shell.setLayout(new FillLayout());
shell.setText("Bug");

CTabFolder tabFolder = new CTabFolder(shell, SWT.NONE);
SashForm tab1Contents = new SashForm(tabFolder, SWT.NONE);
CTabItem tab1 = new CTabItem(tabFolder, SWT.NONE);
tab1.setText("tab 1");
tab1.setControl(tab1Contents);

CTabFolder nestedTabFolder = new CTabFolder(tab1Contents, SWT.NONE);

CTabItem nestedTab1 = new CTabItem(nestedTabFolder, SWT.NONE);
nestedTab1.setText("nested tab 1");
CTabItem nestedTab2 = new CTabItem(nestedTabFolder, SWT.NONE);
nestedTab2.setText("nested tab 2");

shell.open();

nestedTabFolder.setTabHeight(nestedTabFolder.getTabHeight());

while (!shell.isDisposed()) {
	if (!display.readAndDispatch())
		display.sleep();
}
display.dispose();


The window must be small enough to show *only one* of the nested tabs.


Behavior is observed both on RHEL 7.2 (GTK 3.14) and on Windows 10. Also when using SWT_GTK3=0 on RHEL.

Originally seen with:

RHEL 7.2
gtk3-3.14.13-16.el7.x86_64

Eclipse SDK
Version: Photon (4.8)
Build id: I20171217-2000
Comment 1 Simeon Andreev CLA 2018-01-04 05:27:21 EST
Created attachment 272124 [details]
Screenshot with expected chevron and no minimize/maximize button.

When I remove the call to org.eclipse.swt.custom.CTabFolder.setTabHeight(int), there are no minimize/maximize buttons and the chevron is present.
Comment 2 Simeon Andreev CLA 2018-01-04 05:33:01 EST
Created attachment 272125 [details]
Chevron is painted as a menu if minimize/maximize buttons are clicked. It goes away on click anywhere else.
Comment 3 Andrey Loskutov CLA 2018-01-04 05:40:44 EST
I can't reproduce in a *standalone* SWT application, without OSGI and workbench.
I assume this is caused by platform UI contributions => moving to UI.
Comment 4 Andrey Loskutov CLA 2018-01-04 05:47:36 EST
Simeo, I can't reproduce it with the given snippet at all. Can you please provide full project with the code which reproduces the issue for you?
Comment 5 Simeon Andreev CLA 2018-01-04 05:49:30 EST
I can reproduce with the snippet from my first comment, both on Windows and on Linux. Just import org.eclipse.swt.tests and replace the contents of BugTemplate.main with the snippet.


Have you resized the window until only one nested tab is visible?
Comment 6 Simeon Andreev CLA 2018-01-04 06:02:23 EST
Calls to setMaximizeVisible/setMinimizeVisible (which usually show/hide the respective buttons), are ignored as soon as the height is "fixed".

Removing the patch from Bug 502111 allows an "overflow" of the tab folder items (probably the chevron), and then the chevron is painted properly (without min/max buttons).
Comment 7 Simeon Andreev CLA 2018-01-04 06:05:35 EST
Created attachment 272126 [details]
Example plugin to reproduce the problem with. Run plugin code as Java application.
Comment 8 Simeon Andreev CLA 2018-01-04 06:07:18 EST
Moved back to SWT, since its definitely an SWT issue.
Comment 9 Andrey Loskutov CLA 2018-01-04 06:09:22 EST
OK, looks like on my system I have to explicitly set the tab height to a smaller value as nestedTabFolder.getTabHeight() returns.

With this:
nestedTabFolder.setTabHeight(20);
I can also reproduce the problem (nestedTabFolder.getTabHeight() returns 28).
Comment 10 Simeon Andreev CLA 2018-01-04 06:17:25 EST
(In reply to Andrey Loskutov from comment #9)
> OK, looks like on my system I have to explicitly set the tab height to a
> smaller value as nestedTabFolder.getTabHeight() returns.
> 
> With this:
> nestedTabFolder.setTabHeight(20);
> I can also reproduce the problem (nestedTabFolder.getTabHeight() returns 28).

As far as I can tell, the chevron is too big for the default height, so it always "overflows" on the "next" line. Setting the tab height, due to the fix for Bug 502111, prevents this overflow, resulting in no chevron. I'm not sure why the min/max buttons are shown yet.

I.e. I think this is a regression from Bug 502111.
Comment 11 Simeon Andreev CLA 2018-01-04 06:26:30 EST
Maybe the default tab height and the chevron should have the same heights? There are also other drawing artifacts caused by the mismatched heights.

Namely, clicking on the "overflown" chevron to open another tab results in bigger tabs, so that the chevron fits in the line. Clicking on another tab then, *again* results in a resize of the tabs, so that they are smaller again. Very awkward to look at.

Also, if the shell from the snippet is not wide enough to paint both tabs and the tabs don't have a fixed height (no call to setTabHeight), the tabs have the size of the chevron. But if the shell is wide enough to paint both tabs, the tabs are shorter than the chevron.
Comment 12 Simeon Andreev CLA 2018-01-04 06:36:00 EST
Created attachment 272127 [details]
Chevron and tabs have mismatched height, resulting in odd behavior when resizing and selecting tabs.
Comment 13 Simeon Andreev CLA 2018-01-04 08:53:40 EST
OK, the visible buttons are not actually minimize and maximize buttons. Instead, they are there to represent a ToolBar of the CTabFolder, if this toolbar is too big to be drawn (e.g. is overflowing, see screenshots in Bug 502111).

On mouse over this representation, the possible actions are shown in their entire size. This always includes the chevron, and may include the actual minimize/maximize buttons, if they are set to visible.

I think the choice of icons for this representation is unfortunate, since e.g. in this case there are no minimize/maximize actions. Furthermore, this representation is always fixed size. The larger the tabs, the less adequate it looks.

The representation is drawn at the end of CTabFolder.onPaint:

if (hoverTb) {
	Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
	int x = getSize().x - (trim.width + trim.x);
	hoverRect = new Rectangle(x - 16 - SPACING, 2, 16, getTabHeight() - 2);
	gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
	x = hoverRect.x;
	int y = hoverRect.y;
	gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
	gc.fillRectangle(x + hoverRect.width - 6, y, 5, 5);
	gc.drawRectangle(x + hoverRect.width - 6, y, 5, 5);
	gc.drawLine(x + hoverRect.width - 6, y+2, x + hoverRect.width - 6 + 5, y + 2);
	gc.fillRectangle(x, y, 5 , 2);
	gc.drawRectangle(x, y, 5 , 2);
}

Eclipse 3.8 behavior is clearly better; the chevron is the same size as the tab items and is always shown. The min/max buttons are also always shown, when set to visible. They are also the same size as the tab items. There, the chevron/min/max are not part of a toolbar of the CTabFolder. Its something custom instead, not entirely sure what.

From my perspective, the hover looks  jarring, see attached screenshot "toolbar_representation_on_hover.png". Furthermore, the area of the toolbar representation must be scaled to fit the tabs better, see screenshot "toolbar_representation.png".

I'm not sure how to proceed here. If the hover-bar should be kept, at the very least it *must* have an icon that indicates a chevron, and it *cannot* have icons that indicate min/max if the tab folder doesn't show min/max buttons.
Comment 14 Simeon Andreev CLA 2018-01-04 08:54:47 EST
Created attachment 272128 [details]
When the chevron/min/max toolbar cannot be drawn due to small size, a fixed size fixed button representation is drawn.
Comment 15 Simeon Andreev CLA 2018-01-04 08:55:23 EST
Created attachment 272129 [details]
Hovering on the toolbar representation shows the available actions, chevron/min/max.
Comment 16 Andrey Loskutov CLA 2018-01-04 09:57:41 EST
(In reply to Simeon Andreev from comment #15)
> Created attachment 272129 [details]
> Hovering on the toolbar representation shows the available actions,
> chevron/min/max.

Now that I know that should show a "hovering" toolbar, I can't express my feelings. The resulting UI is surprisingly useless and IMHO looks broken.

I don't know how to fix this, because the whole idea of a "tab folder controls as floating menu on hover" is something exceptionally odd. I've never seen something comparable in any UI.

Ideally this "hover" thing should just go away and the min/max and/or chevron buttons should be always shown at the right place (if required) - which means, that the tabs area should simply have some reasonable minimum size.
Comment 17 Andrey Loskutov CLA 2018-01-04 10:02:03 EST
(In reply to Simeon Andreev from comment #15)
> Created attachment 272129 [details]
> Hovering on the toolbar representation shows the available actions,
> chevron/min/max.

BTW, in the example screenshot there is enough place (width) for all three buttons - so they are not shown by default just because the tab height is set to a smaller value? If this is the reason, we should probably restrict setting the tab height to smaller values as the Math.min(maxIcon.height, chevron.height). Looking at the exceptionally complicated CTabfolder code this would be probably the simplest solution.

Simeon - WDYT?
Comment 18 Simeon Andreev CLA 2018-01-04 11:40:26 EST
(In reply to Andrey Loskutov from comment #17)
> [...] we should probably restrict
> setting the tab height to smaller values as the Math.min(maxIcon.height,
> chevron.height). Looking at the exceptionally complicated CTabfolder code
> this would be probably the simplest solution.
> 
> Simeon - WDYT?

I think the simplest solution would be to not mess with the tab height in our product, or to set it to something that is high enough.

I feel uneasy with restricting the API here, considering that:

1. There would be no feedback to the caller, that indicates why tabs never get smaller than 28px.
2. We don't really need to touch the API, if we are going for "big enough" tabs. Same applies for any other users of the class.
3. The minimum height of 28px is pretty large. I was unable to determine why exactly 28px, 20px I think should have been enough. But anything above 16px is already too much as a minimum for this type of element size?
Comment 19 Christoph Laeubrich CLA 2020-02-29 01:17:24 EST
I have seen a similar behavior, and can confirm that this is extremely confusing and disturbing to users as the first reaction is: WTF? My Toolbar is gone!

It has also taken a lot of time to get used to the idea that hovering the (very small!) min/max buttons reveals the toolbar. If a toolbar contains more than simple buttons (e.g. radios/search controls) things are getting even worse as the user can't see the controls or button state anymore, because of this I'll raise importance of this bug.

I'm using an E4 RCP application, is there any way to disable or workaround this behavior? Can I specify a CSS style?
Comment 20 Simeon Andreev CLA 2020-02-29 10:45:44 EST
(In reply to Christoph Laeubrich from comment #19)
> I'm using an E4 RCP application, is there any way to disable or workaround
> this behavior? Can I specify a CSS style?

We had a call to CTabFolder.setTabHeight() with a value that was apparently "too low", resulting in the odd drawing at the top right. We increased the height to avoid the problem.

I don't know about styles, I assume not. The code which draws the "buttons" is in org.eclipse.swt.custom.CTabFolder.onPaint(Event), I don't see anything about applying themes. The code literally draws lines / fills rectangles:

		Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
		int x = getSize().x - (trim.width + trim.x);
		hoverRect = new Rectangle(x - 16 - SPACING, 2, 16, getTabHeight() - 2);
		gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
		x = hoverRect.x;
		int y = hoverRect.y;
		gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
		gc.fillRectangle(x + hoverRect.width - 6, y, 5, 5);
		gc.drawRectangle(x + hoverRect.width - 6, y, 5, 5);
		gc.drawLine(x + hoverRect.width - 6, y+2, x + hoverRect.width - 6 + 5, y + 2);
		gc.fillRectangle(x, y, 5 , 2);
		gc.drawRectangle(x, y, 5 , 2);

There are no actual widgets used. So unlikely for a theme / CSS styling to be able to fix this.