Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 279103

Summary: [Cocoa] SelectionChanged events behaviour broken
Product: [Eclipse Project] Platform Reporter: <h1055071>
Component: SWTAssignee: Silenio Quarti <Silenio_Quarti>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: cocoakevin, daniel_megert, kim.moir, klaasole, markus.kell.r, Mike_Wilson, oliver.oo.schaefer, snorthov, st.mailinglists, swt-mactest
Version: 3.5   
Target Milestone: 3.6 M4   
Hardware: Macintosh   
OS: Mac OS X   
Whiteboard:
Bug Depends on: 289483    
Bug Blocks: 289488    
Attachments:
Description Flags
fix none

Description CLA 2009-06-04 10:00:46 EDT
Build ID: I20090528-2000

Steps To Reproduce:

1. Using a SWT TableViewer or a TreeViewer. Add a ISelectionChangedListener to listen for changed selections.

2. Click on a tree/table node in the tree/table, a selection event is fired.

3. Click back onto the same node as in step 2 but this time no selection event is fired.


More information:

In Carbon version and the other OS's and in 3.4 a selection event is fired when selecting the same node in succession. Not so on the Cocoa port.

My application relies on the behaviour of firing selection events on each selection. As it is implemented here I cannot release a Cocoa 3.5 version.

I have found this behaviour on SWT Trees and Tables. It may also be the case on other Controls.
Comment 1 Steve Northover CLA 2009-06-04 10:21:24 EDT
Not for 3.5

This is kind of bad but not a catastrophe.  I will mark it as 3.5.1, but if the code is too dangerous, it should be defered for another x.x.x release or 3.6.
Comment 2 CLA 2009-06-04 10:38:05 EDT
For all my RCP apps this is bad news. A typical use case is this:

1. A UI with a tree and a table on the same view.

2. An "Inspector" or properties View that shows the properties of the object selected in the tree and/or the table.

3. Select a node on the tree. A selection event is fired and passed on to the "Inspector" view and that is re-populated.

4. Select a node on the table. A selection event is fired and passed on to the "Inspector" view and that is re-populated.

5. Now re-select the same node back on the tree. Obviously I want a selection event to be fired again so I can update the Inspector view. But this won't happen in Cocoa. :-(


My options for updating my application are:

1. Don't release a 3.5 version.
2. Release a 3.5 version but don't release a Cocoa version (use Carbon)
3. Go through all my code and add mouse or focus listeners to trees and tables where IF (PLATFORM == COCOA) AND (LASTSELECTED == SELECTED) fire my own event as a kludge

What would you do?
Comment 3 Steve Northover CLA 2009-06-04 10:46:10 EDT
I'm sorry but there is no way we would attempt to fix this bug right now for Eclipse 3.5 and blow the release.  Silenio and I will come up with a workaround or patch for you.  Stand by ...
Comment 4 CLA 2009-06-04 10:56:28 EDT
Steve,

I completely understand your position. Thanks for the fast response.

Comment 5 CLA 2009-06-08 04:05:53 EDT
There's also something different about the order of Viewer events fired to listeners.

1. I create and show a PopupDialog window with a TableViewer in it
2. I add a MouseUp listener to the TableViewer
3. I add a ISelectionChangedListener to the TableViewer
4. The User clicks on a Table selection - a selection event is fired
5. The MouseUp listener event closes the PopupDialog window

This all works fine on 3.4 win32, lnx and mac carbon because the order of events is:

Selection
MouseUp (close PopupDialog window)


However, on the Cocoa version, the selection event is not fired at all in stage 4. The order of events is:

MouseUp (close PopupDialog window)
Selection (actually not fired since window is closed)

Conclusion - Mouse and Listener Viewer events are fired in different order in Cocoa.



Comment 6 Silenio Quarti CLA 2009-08-06 15:53:04 EDT
Created attachment 143712 [details]
fix
Comment 7 Silenio Quarti CLA 2009-08-06 16:00:39 EDT
Fixed > 20090806 (HEAD and 3.5.1)
Comment 8 CLA 2009-08-06 16:36:08 EDT
Thank-you so much for the fix!  You guys are brilliant!

Phil
Comment 9 Markus Keller CLA 2009-09-15 14:18:27 EDT
This fix caused bug 289488.
Comment 10 Silenio Quarti CLA 2009-09-16 11:27:57 EDT
This fix will be removed from 3.5.1 and also 3.6 M2. 

We will try to address it again on 3.5.2.
Comment 11 CLA 2009-10-30 11:24:02 EDT
Just a polite enquiry...I wonder if this will be fixed for 3.5.2 and/or a 3.6 M build?

Best Regards,

Phil Beauvoir
Comment 12 Silenio Quarti CLA 2009-11-03 16:51:22 EST
Yes, I want to fix this in 3.5.2 and 3.6. I will probably get it done before 3.6 M4.
Comment 13 Markus Keller CLA 2009-11-04 19:47:28 EST
See also bug 289483.
Comment 14 Silenio Quarti CLA 2009-11-17 13:33:39 EST
Fixed > 20091117.

This fix depends on bug#289483 as well. Right now it is only fixed in the 3.6 branch. It needs more testing to decide if the fix goes into 3.5.2.

Markus, I tried bug#289488 and it is still working fine. Please give it a try.
Comment 15 Silenio Quarti CLA 2009-11-17 16:29:57 EST
*** Bug 289873 has been marked as a duplicate of this bug. ***
Comment 16 Stefan Thurnherr CLA 2009-11-18 03:40:20 EST
As described in my comment#1 in bug#289873 ('closed as duplicate' above), I observe in my RCP application the same behaviour for Windows XP. 

Are you sure what you're talking about in this bug is a Cocoa-only problem? If yes, I'll submit a separate bug.
Comment 17 Markus Keller CLA 2009-11-18 04:03:22 EST
> Markus, I tried bug#289488 and it is still working fine. Please give it a try.

The scenario in the SDK works fine for me, but the snippet from bug 289488 comment 2 does not completely hide the shell but leaves a gray rectangle and prints this to stderr:

2009-11-18 09:59:43.328 java[6507:903] *** Assertion failure in -[SWTTableView lockFocus], /SourceCache/AppKit/AppKit-1038.25/AppKit.subproj/NSView.m:5237
Comment 18 Silenio Quarti CLA 2009-11-18 09:13:19 EST
(In reply to comment #16)
> As described in my comment#1 in bug#289873 ('closed as duplicate' above), I
> observe in my RCP application the same behaviour for Windows XP. 
> 
> Are you sure what you're talking about in this bug is a Cocoa-only problem? If
> yes, I'll submit a separate bug.

The problem described in comment#0 of bug#289873 is a duplicate of this bug. Now that I read your problem again, it seems you have a different one. Please open a separate bug.
Comment 19 Silenio Quarti CLA 2009-11-18 09:16:39 EST
(In reply to comment #17)
> > Markus, I tried bug#289488 and it is still working fine. Please give it a try.
> 
> The scenario in the SDK works fine for me, but the snippet from bug 289488
> comment 2 does not completely hide the shell but leaves a gray rectangle and
> prints this to stderr:
> 
> 2009-11-18 09:59:43.328 java[6507:903] *** Assertion failure in -[SWTTableView
> lockFocus], /SourceCache/AppKit/AppKit-1038.25/AppKit.subproj/NSView.m:5237

I knew about the printfs to the console, but I have not seen the gray window. How do you get them? Same steps?

The printfs do not seem to affect eclipse. So it is a low priority for me.
Comment 20 Silenio Quarti CLA 2009-11-18 09:43:25 EST
The printfs happen because the shell is hidden while the mouse button is down. The problem does not happen, if the testcase is changed to hide it only on mouseUp. I do not understand why it is hidden on widgetSelected. It actually makes scrolling the table using the arrow keys impossible. The shell gets hidden after the first arrow down.

It seems the testcase is try to emulated a popup menu using a table (why not just a popup menu?). I think to get similar behavior of a menu, it should hide the shell on mouseUp if a item was selected and on widgetDefaultSelected(). I will attach the testcase modified.
Comment 21 Silenio Quarti CLA 2009-11-18 09:51:32 EST
Here is the testcase modified. Another reason why hiding on widgetSelected is bad: the user cannot drag scroll through the list (press and hold the mouse button on a item and scroll down). This is not something all platforms allow, but cocoa does.

public static void main(String[] args) {
    	try {
        Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new GridLayout(1, false));
        Button button= new Button(shell, SWT.PUSH);
        button.setText("Open Table");
        button.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
            	System.out.println("BUTTON SELECTED");
                final Shell tableShell= new Shell(shell, SWT.NO_TRIM);
                tableShell.setLayout(new GridLayout(1, false));

                final Table table = new Table(tableShell, SWT.FULL_SELECTION | SWT.SINGLE);
                table.setLayoutData(new GridData(GridData.FILL_BOTH));
                
                for (int i = 0; i < 5; i++) {
                    TableItem ti = new TableItem(table, SWT.NONE);
                    ti.setText("Item " + i);
                }
                table.setSelection(1); // bug does not occur with 0

               final  boolean[] selected = new boolean[1];
                table.addMouseListener(new MouseAdapter() {
                    public void mouseDown(MouseEvent e) {
                        System.out.println("mouseDown()");
                        selected[0] = false;
                    }
                    public void mouseUp(MouseEvent e) {
                        System.out.println("mouseUp()");
                        tableShell.setVisible(false);
                    }
                });
                table.addSelectionListener(new SelectionAdapter() {
                    public void widgetSelected(SelectionEvent e) {
                        System.out.println("widgetSelected()=" + e.item);
                        selected [0] = true;
//                      tableShell.setVisible(false);
                    }
                    public void widgetDefaultSelected(SelectionEvent e) {
                        System.out.println("widgetDefaultSelected()=" + e.item);
                      tableShell.setVisible(false);
                    }
                });
                tableShell.pack();
                tableShell.open();
            }
        });

        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    	} catch (Throwable e) {
    		e.printStackTrace();
    	}
    }
Comment 22 Silenio Quarti CLA 2009-11-18 09:53:40 EST
Forgot the check the selected flag in mouseUp:

    public static void main(String[] args) {
    	try {
        Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new GridLayout(1, false));
        Button button= new Button(shell, SWT.PUSH);
        button.setText("Open Table");
        button.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
            	System.out.println("BUTTON SELECTED");
                final Shell tableShell= new Shell(shell, SWT.NO_TRIM);
                tableShell.setLayout(new GridLayout(1, false));

                final Table table = new Table(tableShell, SWT.FULL_SELECTION | SWT.SINGLE);
                table.setLayoutData(new GridData(GridData.FILL_BOTH));
                
                for (int i = 0; i < 5; i++) {
                    TableItem ti = new TableItem(table, SWT.NONE);
                    ti.setText("Item " + i);
                }
                table.setSelection(1); // bug does not occur with 0

               final  boolean[] selected = new boolean[1];
                table.addMouseListener(new MouseAdapter() {
                    public void mouseDown(MouseEvent e) {
                        System.out.println("mouseDown()");
                        selected[0] = false;
                    }
                    public void mouseUp(MouseEvent e) {
                        System.out.println("mouseUp()");
                        if (selected[0]) tableShell.setVisible(false);
                    }
                });
                table.addSelectionListener(new SelectionAdapter() {
                    public void widgetSelected(SelectionEvent e) {
                        System.out.println("widgetSelected()=" + e.item);
                        selected [0] = true;
//                      tableShell.setVisible(false);
                    }
                    public void widgetDefaultSelected(SelectionEvent e) {
                        System.out.println("widgetDefaultSelected()=" + e.item);
                      tableShell.setVisible(false);
                    }
                });
                tableShell.pack();
                tableShell.open();
            }
        });

        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    	} catch (Throwable e) {
    		e.printStackTrace();
    	}
    }
Comment 23 Markus Keller CLA 2009-11-18 10:10:36 EST
I'm not on a Mac at the moment, so I can't give more precise steps to reproduce the gray window right now. I think I just ran the snippet clicked the button, and then clicked a table item. I'll open a separate bug for that with steps and a screenshot.

> The printfs happen because the shell is hidden while the mouse button is down.
> The problem does not happen, if the testcase is changed to hide it only on
> mouseUp. I do not understand why it is hidden on widgetSelected. It actually
> makes scrolling the table using the arrow keys impossible. The shell gets
> hidden after the first arrow down.

That's true, I also realized that after we talked. We need to look at that when we fix bug 78522 (make hyperlinks accessible via keyboard).

> It seems the testcase is try to emulated a popup menu using a table (why not
> just a popup menu?). I think to get similar behavior of a menu, it should hide
> the shell on mouseUp if a item was selected and on widgetDefaultSelected(). I
> will attach the testcase modified.

The problem is that we show the hyperlinks popup when the user holds Ctrl and then points to an identifier. The popup must not have focus in this case, so we can't use a menu. I'll check if we can remove the widgetSelected listener.
Comment 24 Stefan Thurnherr CLA 2009-11-18 11:08:22 EST
(In reply to comment #18)
> The problem described in comment#0 of bug#289873 is a duplicate of this bug.
> Now that I read your problem again, it seems you have a different one. Please
> open a separate bug.

Done: bug#295480
Comment 25 CLA 2010-01-24 06:54:54 EST
(In reply to comment #14)
> Fixed > 20091117.
> 
> This fix depends on bug#289483 as well. Right now it is only fixed in the 3.6
> branch. It needs more testing to decide if the fix goes into 3.5.2.
> 
> Markus, I tried bug#289488 and it is still working fine. Please give it a try.

Hi, will the fix make it into 3.5.2?
Comment 26 Markus Keller CLA 2010-01-24 20:07:53 EST
(In reply to comment #19)
> I knew about the printfs to the console, but I have not seen the gray window.
> How do you get them? Same steps?

(In reply to comment #23)
> I'll open a separate bug for that with steps and a screenshot.

Sorry, seems like I forgot that. Opened bug 300627 now (but AFAIK, this currently does not affect us in the SDK).
Comment 27 Silenio Quarti CLA 2010-01-25 10:09:32 EST
(In reply to comment #25)
> (In reply to comment #14)
> > Fixed > 20091117.
> > 
> > This fix depends on bug#289483 as well. Right now it is only fixed in the 3.6
> > branch. It needs more testing to decide if the fix goes into 3.5.2.
> > 
> > Markus, I tried bug#289488 and it is still working fine. Please give it a try.
> Hi, will the fix make it into 3.5.2?

Sorry, I missed this one and the changes are kind of scary to put in 3.5.2 at this point.
Comment 28 Scott Kovatch CLA 2010-04-06 20:24:43 EDT
*** Bug 307815 has been marked as a duplicate of this bug. ***