Bug 212446 - Focus not set inside CTabFolder before shell is opened
Summary: Focus not set inside CTabFolder before shell is opened
Status: CLOSED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4   Edit
Hardware: PC Windows 2000
: P3 normal with 2 votes (vote)
Target Milestone: ---   Edit
Assignee: Praveen CLA
QA Contact: Bogdan Gheorghe CLA
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2007-12-10 14:14 EST by Felis Cattus CLA
Modified: 2021-09-20 12:18 EDT (History)
5 users (show)

See Also:


Attachments
CTabItem sets the Composite visibility to False during setControl method (1013 bytes, patch)
2008-11-26 07:16 EST, Praveen CLA
no flags Details | Diff
Patch v02 (1.12 KB, patch)
2009-10-27 12:14 EDT, Praveen CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Felis Cattus CLA 2007-12-10 14:14:36 EST
Build ID: I20071101-2000

If focus is set to a component, inside a CTabItem, before the shell is first opened (to try to determine the component that is first focused when the shell opens), the focus request has no effect. Or it seems that after the focus event on the requested component, there is a subsequent focus event on CTabItem.

This happens only inside CTabItem, and not inside TabItem. The difference can be seen if in the attached snippet, CTabFolder and CTabItem are changed to TabFolder and TabItem.

With TabFolder, the focus/cursor is in text2, when the shell is first opened, and the user can start typing immediately.

With CTabFolder, the user must first click in the text field, before he can start typing.


More information:

  public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setLayout(new GridLayout());
    shell.setText("Main window");

    CTabFolder tabs = new CTabFolder(shell, SWT.NONE);
    tabs.setLayoutData(new GridData(GridData.FILL_BOTH));
    CTabItem tab = new CTabItem(tabs, SWT.NONE);
    tab.setText("Test Tab");

    Composite center = new Composite(tabs, SWT.NONE);
    tab.setControl(center);
    center.setLayout(new GridLayout());

    Text text1 = new Text(center, SWT.BORDER);
    text1.setLayoutData(new GridData(GridData.FILL_BOTH));

    Text text2 = new Text(center, SWT.BORDER);
    text2.setLayoutData(new GridData(GridData.FILL_BOTH));

    ////// DOESN'T WORK
    text2.setFocus();

    shell.setSize(1000, 600);
    shell.open();

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

    display.dispose();
  }
Comment 1 Bogdan Gheorghe CLA 2008-11-24 20:16:30 EST
Praveen to reproduce and analyze.
Comment 2 Praveen CLA 2008-11-26 07:16:47 EST
Created attachment 118774 [details]
CTabItem sets the Composite visibility to False during setControl method

During the call to <CTabItem>.setControl(<Composite>), CTabItem receive that it's parent(CTabFolder) doesn't consider it as a selected item and thus, it sets the Composite visiblity to False.
Thus, when shell tries to set the Focus of Text control during Shell.Open(), it encounters that the Text's control parent Compsite is NOT visible and thus, shell ignores to set focus on Text.
Comment 3 Grant Gayed CLA 2009-07-08 14:59:19 EDT
reassigning since there's a patch attached
Comment 4 Bogdan Gheorghe CLA 2009-10-21 13:09:28 EDT
Fixed in HEAD > 20091021
Comment 5 Remy Suen CLA 2009-10-24 22:40:50 EDT
Any active CTabItems that declare SWT.CLOSE seems to have been broken by this fix when the widget is first constructed. Snippet82 can be used as a testbed.
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet82.java?view=co

Before the patch, the first item will have the 'X' marker drawn on it. With the patch applied, the item will not have the 'X' marker. Hovering over it will cause it to be drawn though.
Comment 6 Praveen CLA 2009-10-26 07:19:50 EDT
(In reply to comment #5)
> Before the patch, the first item will have the 'X' marker drawn on it. With the
> patch applied, the item will not have the 'X' marker. Hovering over it will
> cause it to be drawn though.
I agree. Due to the added code changes, after the CTabFolder recieved focus, setSelection() is never called as selectedIndex is never -1. Thus, the required code for setting the closeImage is not set.
The correct fix might be to call setSelection(0) in createItem() when the items.length is 1, which could set the state for focussing the tabfolder properly. I am currently testing the impact/effect of implementing this.
Comment 7 Remy Suen CLA 2009-10-26 09:22:10 EDT
(In reply to comment #6)
> I am currently testing the impact/effect of implementing this.

Praveen, do you know if a unit test can be extracted out to verify that the activation/selection problem does not come back? The UI tests failed per bug 293248 as you know so I was wondering if it was possible to test for this on the SWT/CTabFolder side?
Comment 8 Bogdan Gheorghe CLA 2009-10-26 10:35:37 EDT
As it is M3 week, I took the patch out. Praveen to investigate and come up with an alternative solution.
Comment 9 Praveen CLA 2009-10-27 12:14:57 EDT
Created attachment 150649 [details]
Patch v02

When a 1st item is created, it is required to intialize selectedIndex. That is achieved through invoking setSelection(), which sets all the required params for displaying the tab-item.

The test case snippet provided below tests the sequence of events generated while creating a tab-item:

	  public static void main(String[] args) {
		    Display display = new Display();
		    Shell shell = new Shell(display);
		    shell.setLayout(new GridLayout());
		    shell.setText("Main window");
		    CTabFolder tabs = new CTabFolder(shell, SWT.SINGLE);
		    tabs.setTabHeight(30);
		    tabs.setLayoutData(new GridData(GridData.FILL_BOTH));
		    
		    tabs.addSelectionListener(new SelectionListener() {
				
				@Override
				public void widgetSelected(SelectionEvent e) {
					System.out.println("Widget selected");
				}
				
				@Override
				public void widgetDefaultSelected(SelectionEvent e) {
					System.out.println("Widget Default selected");
				}
			});
		    tabs.addFocusListener(new FocusListener() {
				@Override
				public void focusLost(FocusEvent e) {
					System.out.println("Focus Lost");
				}
				
				@Override
				public void focusGained(FocusEvent e) {
					System.out.println("Focus Gained");
				}
			});
		    tabs.addListener(SWT.Activate, new Listener() {
				@Override
				public void handleEvent(Event event) {
					System.out.println("Activated");
				}
			});
		    
		    CTabItem tab = new CTabItem(tabs, SWT.CLOSE);
		    tab.setText("Test Tab");

		    Composite center = new Composite(tabs, SWT.NONE);
		    tab.setControl(center);
		    center.setLayout(new GridLayout());

		    Text text1 = new Text(center, SWT.BORDER);
		    text1.setLayoutData(new GridData(GridData.FILL_BOTH));

		    Text text2 = new Text(center, SWT.BORDER);
		    text2.setLayoutData(new GridData(GridData.FILL_BOTH));

		    CTabItem tab1 = new CTabItem(tabs, SWT.CLOSE);
		    tab1.setText("Other Tab");
		    Composite comp2 = new Composite(tabs, SWT.NONE);
		    comp2.setLayout(new GridLayout());
		    tab1.setControl(comp2);
		    Text txt = new Text(comp2, SWT.BORDER);
		    txt.setLayoutData(new GridData(GridData.FILL_BOTH));

		    text1.setFocus();
		    shell.setSize(1000, 600);
		    shell.open();
		    
		    while (!shell.isDisposed()) {
		      if (!display.readAndDispatch()) {
		        display.sleep();
		      }
		    }

		    display.dispose();
		  }

Bogdan, please review the patch. Thanks.
Comment 10 Bogdan Gheorghe CLA 2009-11-02 13:17:21 EST
Your patch replaces:

if (!updateTabHeight(false)) updateItems();
redraw();

with

setSelection(index, true);

Calling setSelection() gets you a call to redraw for free. But I'm concerned about losing the calls to updateTabHeight() and updateItems(). Both of those code paths are no longer taken once you apply the patch and it is not clear to me that they are no longer required.
Comment 11 Praveen CLA 2009-11-03 01:28:54 EST
(In reply to comment #10)
> Calling setSelection() gets you a call to redraw for free. But I'm concerned
> about losing the calls to updateTabHeight() and updateItems(). Both of those
> code paths are no longer taken once you apply the patch and it is not clear to
> me that they are no longer required.

Here are the reasons for replacing those statements with setSelection -

1) setSelection() invokes showItem(), which takes the responsibility of calling updateItem(index).
So, I think that updateItems() would be redundant if is used along with setSelection() call.

2) The value of tabHeight is initialized (in updateTabHeight) by CTabFolder constructor through init() method. So, any other invokation of updateTabHeight() actually updates the tab height only if the height/font is changed, or text/image is set on Item (and when the APIs are called for changing these parameters, tabHeight is updated accordingly). Otherwise, it just returns without updating anything. So, I feel it is just redundant to make another invokation of this call at that place as there would be no changes/updates to the tab height.

Considering these factors, I felt that it is valid to replace those statements with setSelection() call.
Comment 12 Eclipse Webmaster CLA 2019-09-06 16:17:52 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.
Comment 13 Eclipse Genie CLA 2021-09-20 12:18:16 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.