missing SWT.Activate events
Brought to you by:
max_stepanov
We's using a slightly modified version of the composer, but in our version we noticed that we won't get any SWT.Activate events from the composer. This is due to
GeckoEditor.forceFocus() being overwritten without calling super.
This is how we fixed it:
public boolean forceFocus() {
if ( isVisible() ) {
Activate();
return super.forceFocus();
}
return false;
}
Logged In: YES
user_id=1342865
Originator: NO
Hi Carsten,
What Eclipse/SWT version and OS you has been testing on ?
Thanks,
Max
Logged In: YES
user_id=194457
Originator: YES
I'm using Eclipse 3.3.2 on Linux. What I posted above was not sufficient though, I was missing FocusOut events :-}
My current version that seems to provide all events in the same order like all other SWT controls looks like this (posting only the changed methods):
public boolean forceFocus() {
if (isFocusControl()) {
return true;
}
if (!isVisible() || !isEnabled()) {
return false;
}
Activate();
return super.forceFocus();
}
void Activate() {
boolean needsActivation = !active;
boolean notify = ( GeckoEditor.this != getDisplay().getFocusControl() && !active );
active = true;
if (needsActivation) {
nsIWebBrowserFocus webBrowserFocus = webBrowserHelper.getWebBrowserFocus();
int rc = webBrowserFocus.Activate();
if (rc != XPCOM.NS_OK)
doError(rc);
webBrowserFocus.Release();
}
// commented out -- we get double FocusIn events
// if ( notify ) {
// Event event = new Event();
// try {
// notifyListeners(SWT.FocusIn, event);
// } catch ( Exception ignore ) {
// ignore.printStackTrace();
// }
// }
}
When passing the focus from one control to another, the following events should appear:
c1 : FocusOut
c2 : FocusIn
c1 : Deactivate
c2 : Activate
I'll test my current version on Windows tomorrow.
Logged In: YES
user_id=194457
Originator: YES
Well, of course it didn't work so well on win32. Actually, with my current version, it seems to work better on linux/gtk than on win32.
Here's my current set of changes:
private Listener win32FocusOutFilter = new Listener() {
public void handleEvent(Event event) {
event.display.removeFilter(SWT.FocusIn, this);
GeckoEditor.this.notifyListeners(SWT.FocusOut, null);
}
};
:: this method is called by the "listener" handleEvent() method on FocusIn-event
:: (didn't add the code here)
private void handleFocusIn(Event anEvent) {
// On win32, we don't get any focus out events, so as a workaround,
// we register a focus in event filter and send out a focus out event
// ourselves when another widget receives the focus.
if (Platform.OS_WIN32.equals(SWT.getPlatform())) {
anEvent.display.addFilter(SWT.FocusIn, win32FocusOutFilter);
}
}
int /*long*/ SetFocus() {
nsIBaseWindow baseWindow = webBrowserHelper.getBaseWindow();
int rc = baseWindow.SetFocus();
if (rc != XPCOM.NS_OK)
doError(rc);
baseWindow.Release();
return XPCOM.NS_OK;
}
void Activate() {
boolean needsActivation = !active;
boolean notify = ( GeckoEditor.this != getDisplay().getFocusControl() && !active );
active = true;
if (needsActivation) {
nsIWebBrowserFocus webBrowserFocus = webBrowserHelper.getWebBrowserFocus();
int rc = webBrowserFocus.Activate();
if (rc != XPCOM.NS_OK)
doError(rc);
webBrowserFocus.Release();
}
}
public boolean forceFocus() {
if (!Platform.WS_GTK.equals(SWT.getPlatform())) {
return super.forceFocus();
}
// on gtk, we must call Activate() *before* calling super.getFocus()
if (!isVisible() || !isEnabled()) {
return false;
}
Activate();
return super.forceFocus();
}
With these changes, the events come in perfectly on Linux/gtk, and almost perfectly under win32 (IIRC there is one spurious FocusOutEvent when passing the focus from another control to the GeckoEditor control). That extra event shouldn't hurt much, so I'm happy for now.