Bug 465280 (swtGetAlloc_ret_0_0) - [GTK3] OS.gtk_widget_get_allocation returns (0,0) for invisible controls
Summary: [GTK3] OS.gtk_widget_get_allocation returns (0,0) for invisible controls
Status: VERIFIED FIXED
Alias: swtGetAlloc_ret_0_0
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.7   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 4.7.1   Edit
Assignee: Leo Ufimtsev CLA
QA Contact: Sravan Kumar Lakkimsetti CLA
URL:
Whiteboard:
Keywords:
: 481851 (view as bug list)
Depends on:
Blocks: 458120
  Show dependency tree
 
Reported: 2015-04-23 06:39 EDT by Nobody - feel free to take it CLA
Modified: 2017-08-01 10:42 EDT (History)
13 users (show)

See Also:


Attachments
Snippet to reproduce the issue (1.21 KB, text/plain)
2015-04-23 06:39 EDT, Nobody - feel free to take it CLA
no flags Details
Some jUnits to demonstrate issue (3.69 KB, text/x-java)
2017-06-09 17:48 EDT, Leo Ufimtsev CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nobody - feel free to take it CLA 2015-04-23 06:39:30 EDT
Created attachment 252671 [details]
Snippet to reproduce the issue

In GTK2 (and windows) if you call getSize on a control that has been set to not be visible the getSize method still returns non-zero values but with GTK3 it returns (0,0) if the control is not visible.

This inconsistent behavior is causing a test to fail under PlatformUI, namely UIDialogsAuto#testShowView.

Find attached a snippet to reproduce the issue.
Comment 1 Alexander Kurtakov CLA 2015-10-20 09:07:39 EDT
From https://lwn.net/Articles/544395/ :
Invisible widgets now return a size of 0x0.
Comment 2 Eric Williams CLA 2015-10-20 14:09:31 EDT
(In reply to Alexander Kurtakov from comment #1)
> From https://lwn.net/Articles/544395/ :
> Invisible widgets now return a size of 0x0.

Calling getSize() on a control will return the width and height of topHandle for that control, which is the swtFixed container/object for that particular control.

In Gtk3, widgets that are not visible will return a size of 0x0. For widgets (buttons, labels, etc.) this will be 1x1 (with x and y coordinates of -1). In the case of swtFixed, it appears to be 0x0. 

Gtk2 returns the size allocated to the widget regardless of whether it is visible or not.
Comment 3 Eric Williams CLA 2015-10-20 14:21:55 EDT
(In reply to Eric Williams from comment #2)
> In Gtk3, widgets that are not visible will return a size of 0x0. For widgets
> (buttons, labels, etc.) this will be 1x1 (with x and y coordinates of -1).
> In the case of swtFixed, it appears to be 0x0.

I should clarify: native widgets (which are not visible) return a size of 1x1 and coordinates of -1. SWT widgets have swtFixed containers/objects, therefore calling getSize() on an SWT widget returns 0x0, since the call uses the GtkAllocation of the swtFixed container/object.
Comment 4 Eclipse Genie CLA 2015-10-27 15:15:47 EDT
New Gerrit change created: https://git.eclipse.org/r/59050
Comment 5 Eclipse Genie CLA 2015-12-01 08:56:15 EST
New Gerrit change created: https://git.eclipse.org/r/61651
Comment 6 Snjezana Peco CLA 2015-12-01 09:01:26 EST
*** Bug 481851 has been marked as a duplicate of this bug. ***
Comment 7 Lars Vogel CLA 2015-12-01 10:19:06 EST
Can this be reviewed for M4? It breaks our e4 tools, see Bug 481851.
Comment 9 Lakshmi P Shanmugam CLA 2015-12-04 08:56:21 EST
Hi Snjezana, 
Looking at the code, it seems that calling setVisible(true) and setVisible(false) will cause unnecessary SWT.Show and SWT.Hide events to be sent every time computeSize() is called. There could be other side-effects too of calling setVisible() in computeSize(). Can you please verify?
Comment 10 Snjezana Peco CLA 2015-12-07 09:44:50 EST
(In reply to Lakshmi Shanmugam from comment #9)
> Hi Snjezana, 
> Looking at the code, it seems that calling setVisible(true) and
> setVisible(false) will cause unnecessary SWT.Show and SWT.Hide events to be
> sent every time computeSize() is called. There could be other side-effects
> too of calling setVisible() in computeSize(). Can you please verify?

SWT.Show and SWT.Hide events will be called for GTK3 (sometimes for GTK2) when a control is invisible.
Comment 11 Alexander Kurtakov CLA 2015-12-07 09:49:58 EST
I haven't looked into details but using gtk_widget_show/hide should be better option than doing the full SWT cycle setVisible.
Comment 12 Arun Thondapu CLA 2015-12-07 09:55:41 EST
(In reply to Alexander Kurtakov from comment #11)
> I haven't looked into details but using gtk_widget_show/hide should be
> better option than doing the full SWT cycle setVisible.

+1. We should try to use gtk_widget_show/hide () instead of setVisible () to achieve the same effect.
Comment 13 Lakshmi P Shanmugam CLA 2015-12-08 01:30:29 EST
(In reply to Snjezana Peco from comment #10)
> (In reply to Lakshmi Shanmugam from comment #9)
> > Hi Snjezana, 
> > Looking at the code, it seems that calling setVisible(true) and
> > setVisible(false) will cause unnecessary SWT.Show and SWT.Hide events to be
> > sent every time computeSize() is called. There could be other side-effects
> > too of calling setVisible() in computeSize(). Can you please verify?
> 
> SWT.Show and SWT.Hide events will be called for GTK3 (sometimes for GTK2)
> when a control is invisible.

Thanks for verifying, Sravan. I'm not sure, but there could be other side-effects too since setVisible() does other things.

(In reply to Arun Thondapu from comment #12)
> (In reply to Alexander Kurtakov from comment #11)
> > I haven't looked into details but using gtk_widget_show/hide should be
> > better option than doing the full SWT cycle setVisible.
> 
> +1. We should try to use gtk_widget_show/hide () instead of setVisible () to
> achieve the same effect.

But, we can't use it for Custom Controls as they have common code for all platforms.

IMHO it's better to revert the patch for M4 and find a fix that works for both native and custom controls for M5.
Comment 14 Lakshmi P Shanmugam CLA 2015-12-08 01:35:35 EST
> Thanks for verifying, Sravan. 
Sorry, I meant to say - Thanks for verifying, Snjezana.
Comment 15 Arun Thondapu CLA 2015-12-08 08:08:29 EST
(In reply to Lakshmi Shanmugam from comment #13)
> > +1. We should try to use gtk_widget_show/hide () instead of setVisible () to
> > achieve the same effect.
> 
> But, we can't use it for Custom Controls as they have common code for all
> platforms.

I don't think this change is even necessary for the custom controls, it should be enough to make the change in the native controls alone AFAICS, because the computeSize() methods in the custom controls anyway use the computeSize() methods from the native controls internally...

> IMHO it's better to revert the patch for M4 and find a fix that works for
> both native and custom controls for M5.

It would have been good to have this bug fixed in M4 as it affects UI scenarios like the one mentioned in bug 481851, but I agree that we should find the optimal solution to avoid the side-effects of using setVisible() here.

Reverted the patch via http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=166a902e3280d3067b5a24bba11e2aac7e51a264 and moved to M5.
Comment 16 Eclipse Genie CLA 2015-12-11 10:36:54 EST
New Gerrit change created: https://git.eclipse.org/r/62495
Comment 17 Snjezana Peco CLA 2015-12-11 10:38:38 EST
https://git.eclipse.org/r/62495 uses gtk_widget_show/gtk_widget_hide to fix the issue.
The patch fixes the issue described in bug 481851 and https://issues.jboss.org/browse/JBIDE-21072.
Calling gtk_widget_show/gtk_widget_hide for Shell locks Eclipse.

As to the CCombo, CLabel, CoolBar and CTable class, I haven't changed them because there aren't any known issues related to these classes. 
If we face an issue related to them, we will be able to fix it using the setVisible method.
Comment 18 Arun Thondapu CLA 2015-12-11 14:54:07 EST
(In reply to Arun Thondapu from comment #15)
> It would have been good to have this bug fixed in M4 as it affects UI
> scenarios like the one mentioned in bug 481851, but I agree that we should
> find the optimal solution to avoid the side-effects of using setVisible()
> here.

Bug 483848 is one example of an undesirable side-effect caused by toggling visibility using setVisible().

I'm not sure if the patch using gtk_widget_show/gtk_widget_hide would exhibit this or other similar problems, needs to be tested to confirm...
Comment 19 Snjezana Peco CLA 2015-12-11 16:09:01 EST
(In reply to Arun Thondapu from comment #18)
> 
> Bug 483848 is one example of an undesirable side-effect caused by toggling
> visibility using setVisible().
> 
> I'm not sure if the patch using gtk_widget_show/gtk_widget_hide would
> exhibit this or other similar problems, needs to be tested to confirm...

In my opinion, the issue described in bug 483848 isn't related either to this bug or to any patches I have created within it.
I can reproduce it on Mars.1, Neon M3, the current SWT master with or without these patches using GTK >= 3.14.
It is easier to reproduce it on a slower machine. Try to start several Eclipse instances.
Bug 483848 isn't fixed, but it is a duplicate of bug 473369.
I think Alexander is right. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=473369#c1
Comment 20 Sravan Kumar Lakkimsetti CLA 2015-12-24 05:04:52 EST
With the latest code also the ui test testShowView(org.eclipse.ui.tests.dialogs.UIDialogsAuto) fails.

This test actually test the get_allocation using hidden buttons.
Comment 21 Sravan Kumar Lakkimsetti CLA 2016-01-22 05:12:35 EST
moving to M6 as review is not complete
Comment 22 Sravan Kumar Lakkimsetti CLA 2016-02-08 04:12:27 EST
Is it possible to have a look at the problem for M6. There are some issues with the attached gerrit Patch
Comment 23 Arun Thondapu CLA 2016-03-10 14:28:43 EST
Moving to M7 now as it is still not clear whether the patch is fixing the real problem or not...
Comment 24 Sravan Kumar Lakkimsetti CLA 2016-04-25 07:17:07 EDT
the patch still does not fix the main issue so moving out of 4.6. since it only test failure I am reducing the severity
Comment 25 Leo Ufimtsev CLA 2016-06-07 11:06:54 EDT
I haven't read into this bug too deeply, but I've worked on Visibility issues in:
Bug 487757 - ScrolledComposite is empty if it is hidden and then made visible via setVisible(true|false) 

I added a check that shows a widget in setBounds() if it's suppose to be shown on SWT side but hasn't been shown on GTK side.
It might be a bit relevant to this bug.
Comment 26 Arun Thondapu CLA 2017-05-25 15:06:01 EDT
Moving to 4.8.
Comment 27 Leo Ufimtsev CLA 2017-06-09 17:48:14 EDT
Created attachment 268852 [details]
Some jUnits to demonstrate issue

I've been investigating this business.

I've made some observations:
- The root of the problem seems to be gtk caching that was introduced in 3.8
- On 3.6, the attached jUnits pass. On 3.8, some fail.

Things to note:
- It doesn't seem that visibility alone impacts getBounds(), but rather:
  * setBounds() on an invisible widget seems to now only 'mark' the widget for resizing
  * actual resizing seems to be done in idle time
  * only once actual resizing is done in idle time by gtk, does gtk report correct widget sizes
    for get_allocation/getBounds().

Evidence:
- getBounds() will return correct coordinates for invisible widget if setBounds() was called *before* setVisible(false). (see test1)
- getbounds() will return correct coordinates for invisible widget if setBounds() was called after setVisible() AND if you open shell & call readAndDispatch() multiple times in between (presumably allowing size-cache to be rebuild in indle cycles). (see hackaround).


Possible solutions:
1) Figure out how force gtk to compute sizes, such that we could force compute sizes before returning getBounds()/getAllocate.

2) On SWT side, cache sizes for widgets by setBounds() until gtk computes actual sizes. I.e, if gtk gives us 0,0 but we have a different cached size, then return cached sizes until gtk has updated it's sizes internally.


I will investigate if 1) is technically possible by consulting with gtk devel team. If not, I'll investigate a solution for option 2.
Comment 28 Eclipse Genie CLA 2017-06-23 16:30:01 EDT
New Gerrit change created: https://git.eclipse.org/r/99981
Comment 30 Eclipse Genie CLA 2017-06-23 16:40:57 EDT
New Gerrit change created: https://git.eclipse.org/r/99982
Comment 32 Leo Ufimtsev CLA 2017-06-26 10:25:18 EDT
Patch that fixes the issue was merged. Tomorrow's builds should contain the fix.

I need to backport this patch if it proves to work well.
Comment 33 Leo Ufimtsev CLA 2017-06-26 12:30:29 EDT
Bugfix verified. See:
Bug 497705 – Unhandled event loop > StackOverflow in Perspective

Awaiting Oxygen release & opening of backport branch for backport.
Comment 34 Eclipse Genie CLA 2017-07-20 12:23:25 EDT
New Gerrit change created: https://git.eclipse.org/r/101659
Comment 36 Leo Ufimtsev CLA 2017-07-20 12:29:55 EDT
Fix backported to 4.7.1