Bug 46061 - [KeyBindings] Key bindings mix-up in new top-level Shell started from workbench
Summary: [KeyBindings] Key bindings mix-up in new top-level Shell started from workbench
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows All
: P1 major (vote)
Target Milestone: 3.0 M6   Edit
Assignee: Douglas Pollock CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-11-04 15:42 EST by adrian CLA
Modified: 2003-12-22 01:15 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description adrian CLA 2003-11-04 15:42:50 EST
I start a new top-level Shell from inside an edit view in the workbench:

    getSite().getShell().getDisplay().asyncExec(new Runnable(){
     public void run() {
      try {
       Class cl = Class.forName("com.MyShell");
       Constructor myConstructor = cl.getConstructor(new Class[]
        {String.class});
       myConstructor.newInstance(new Object[] {parameters});
       }
      catch (Throwable t) {}
     }});

Unlike in Eclipse R2.1.n, key combinations in this Shell that correspond to key
bindings in whatever view is active in the workbench activate the *workbench*
action in that view, rather than coming to this Shell?!?!

[This does not happen in secondary Shells, but I can't use a secondary Shell
because it's always drawn on top of the workbench...]
Comment 1 Douglas Pollock CLA 2003-11-14 12:22:19 EST
Out of curiousity: why exactly do you want to do this?

We have run into a similar problem with the CyclePartAction, which opens a shell
that wishes to trap incoming key strokes.  We created internal API to deal with
the problem.  Should we make this external/public?

In the interim, you can access this functionality by getting a reference to the
Workbench.  Use something like:

    Workbench wb = (Workbench) getSite().getWorkbenchWindow().getWorkbench();

Then you can disable and enabled the global key bindings using the following
methods:

    wb.disableKeyFilter();
    wb.enabledKeyFilter();

If you wish to listen for these top-level events yourself, then use something like:

    Display display = getSite().getShell().getDisplay();
    display.addFilter(SWT.KeyDown, myFilter);

If you don't want the key event to propagate after reaching myFilter, remember
to set event.doit = false.
Comment 2 adrian CLA 2003-11-16 19:46:46 EST
I open edit widget(s) in top-level Shells outside the workbench IDE.

The key-binding changes must be pretty serious to cause a need for such patches
for things that worked naturally in Eclipse R2.1.

This works fine in secondary Shells (such as dialogs) - I would have expected
the same behaviour with top-level Shells:  i.e., that key-bindings from an IDE
view wouldn't survive a focus change to another Shell!?...
Comment 3 Douglas Pollock CLA 2003-11-18 11:16:15 EST
They won't be excluded from dialogs for much longer.  The change here has been
to support key bindings appearing in dialogs.  There is currently code checking
for a parent shell.  If there is a parent shell, then the key bindings are
suppressed.

We are listening for key events at the Display.

What is the exact nature of the shells you are opening?  How are they "outside
the IDE"?  I need a lot more information before I can decide what the best thing
to do might be.
Comment 4 adrian CLA 2003-11-18 14:40:35 EST
> What is the exact nature of the shells you are opening?

It's just like a dialog, but it's a top-level Shell (constructor with Display as
argument) rather than a secondary Shell (the Shell-argument constructor).  See
original bug append.

> They won't be excluded from dialogs for much longer.

I think one should set an explicit key-binding if so desired, otherwise any such
Shell (dialog or not) should receive all the keys (without further workarounds).
 Also, dialogs (any Shell-hosted Composite) may have their own mnemonics, etc. -
  thse should take precedence over any key bindings. 

> How are they "outside the IDE"?

Sorry for my lack of clarity - I just meant a Shell which is not a view inside
the workbench...
Comment 5 Douglas Pollock CLA 2003-11-18 14:54:56 EST
You're still not answering my true question: what are you doing?  For 
example: "platform-ui opens a Shell to allow the users to cycle between the 
list of open editors.  This Shell has special key definitions particular to it 
that require overriding the global key bindings."  Right now, all I know is 
that you're opening a top-level Shell, but I don't know *why*.

For key bindings to "just work" in dialogs we need to take a different 
approach.  We can't force people to opt-in.  See Bug 31731 to get a feel for 
what we're trying to solve.

I also have another question (which really ties into the first 
question, "why").  If the user had specified an Emacs key binding, would you 
expect that Emacs-style cut/copy/paste/undo/etc be available in your shell?  
For example, "Alt+W" or "Esc W" for "Copy".
Comment 6 adrian CLA 2003-11-19 09:08:54 EST
I'm opening one or more (LPEX) edit widgets (similar to StyleText widgets housed
by a Shell)used for various specialized browse, reference, etc. functions on
local files in the file system.

While in general having the same key bindings as the parent (LPEX) EditorPart
view that opened these Shells is acceptable, there are problems - not all the
actions make sense when invoked in these individual widgets vs. when a
full-blown workbench editor view is active, and not all actions have in these
Shells the code (implementation) support that the EditorPart has.

It may be fine for Select all and clipboard operations (talking about Bug 31731
that you refer to), but certainly not for all the bindings.

I don't think such bindings should be enforced - they should be at best
inherited only when desired (a Shell constructor style SWT.INHERIT_BINDINGS?!),
or better, one should explicitly set the key-bindings scope desired that makes
sense for that Shell/dialog (and, presumably, for all the other Shells/dialogs
instantiated by the same plug-in).  Otherwise, pass all the keys on, like one
would expect a window to behave in any other programming environment!?
Comment 7 Douglas Pollock CLA 2003-12-03 16:13:29 EST
Could you provide feedback on this?

I propose grouping shells into three groups: dialogs, managed shells and
unmanaged shells.  Any shell that has a parent shell is a dialog.  Managed
shells are shells that have no parent, but that have registered with the global
key binding service.  Unmanaged shells are all the rest (i.e., shells with no
parents that have not registered).

Unmanaged shells would have no global key binding service; when they have focus,
the key bindings service is disabled.  Dialogs would receive a subset of the key
binding service; they would only allow key bindings that have been flagged as
"allowedInDialogs".  Managed shells would have the option of choosing either
full service, or dialog service.  WorkbenchWindows, for example, would choose
full service.

Your windows could be either completely unmanaged, or they could choose to have
dialog service.

Does this meet your needs?  Does this cause problems with anything else that you
are aware of?
Comment 8 adrian CLA 2003-12-03 20:08:00 EST
1.- The proposal seems very reasonable to me.

2.- On a related topic, how do the mnemonics of labels, fields, etc. whose
parent Composite is housed in each of these Shells, behave in this scheme - in
terms of priority over the key bindings?

Even managed Shells *may* want to give mnemonics priority (e.g., Alt+L to move
keyboard focus to a Text field labeled "Fie&ld").  This is particularly
important in view of the fact that such mnemonics cannot be known ahead of time,
as they differ between national languages (say "&Champ" in French here :-)).  I
know that Alt+<key> bindings are not recommended, but they are a reality to be
taken into consideration.
Comment 9 Douglas Pollock CLA 2003-12-09 15:07:25 EST
This bug is fixed in CVS, and should be available in next week's integration
build (warm-up for M6).  Sorry they didn't make it into today's integration
build (I20031209).  The API you're looking for is:
    IWorkbench.registerForKeyBindings(shell,boolean)
    IWorkbench.deregisterFromKeyBindings(shell)

The implementation is as discussed.

I am not inclined to give mnemonics priority for a few reasons.  First off, I
don't believe SWT provides an easy way to check whether a mnemonic is currently
in use (nor do I think any native widget toolkits); this means that you'd have
to walk the widget hierarchy looking for mnemonics -- which I think would be
inefficient.  Secondly, mnemonics are not required for accessibility.  Third,
people are strongly encouraged not to bind these keys -- mainly for the reasons
you mention.  ;)  And, lastly, this is not the behaviour in everyone's favourite
application: Microsoft Word.  (Not that Word is some god amongst applications,
but it is a good acid test.)  In Word, if you bind to "Alt+F" it will take
priority over the "&File" menu.
Comment 10 Douglas Pollock CLA 2003-12-17 09:35:44 EST
Adrian: I've verified this with a naive test case on I200312162000.  If you have
a chance, could you verify that your specific test case works as well?  Thanks....
Comment 11 adrian CLA 2003-12-22 01:15:57 EST
> could you verify that your specific test case works as well?

The code in question works again (like in Eclipse R2.1.n).  Thank you.  Didn't
test any of the other new methods for controlling key bindings.

> I don't believe SWT provides an easy way to check whether a mnemonic is
currently in use (nor do I think any native widget toolkits)

I distinctly remember various traverseMnemonic methods in SWT since Eclipse R1...