1 /*******************************************************************************
\r
2 * Copyright (c) 2007 SAS Institute.
\r
3 * All rights reserved. This program and the accompanying materials
\r
4 * are made available under the terms of the Eclipse Public License v1.0
\r
5 * which accompanies this distribution, and is available at
\r
6 * http://www.eclipse.org/legal/epl-v10.html
\r
9 * SAS Institute - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.utils.ui.awt;
\r
13 import org.eclipse.swt.SWT;
\r
14 import org.eclipse.swt.events.FocusAdapter;
\r
15 import org.eclipse.swt.events.FocusEvent;
\r
16 import org.eclipse.swt.widgets.Dialog;
\r
17 import org.eclipse.swt.widgets.Display;
\r
18 import org.eclipse.swt.widgets.Shell;
\r
22 class SwtInputBlocker extends Dialog {
\r
23 static private SwtInputBlocker instance = null;
\r
24 static private int blockCount = 0;
\r
25 private Shell shell;
\r
27 private SwtInputBlocker(Shell parent) {
\r
28 super(parent, SWT.NONE);
\r
31 private Object open() {
\r
32 assert Display.getCurrent() != null; // On SWT event thread
\r
34 final Shell parent = getParent();
\r
35 shell = new Shell(parent, SWT.APPLICATION_MODAL);
\r
36 shell.setSize(0, 0);
\r
37 shell.addFocusListener(new FocusAdapter() {
\r
38 public void focusGained(FocusEvent e) {
\r
39 // On some platforms (e.g. Linux/GTK), the 0x0 shell still appears as a dot
\r
40 // on the screen, so make it invisible by moving it below other windows. This
\r
41 // is unnecessary under Windows and causes a flash, so only make the call when necessary.
\r
42 if (Platform.isGtk()) {
\r
43 shell.moveBelow(null);
\r
45 AwtEnvironment.getInstance(shell.getDisplay()).requestAwtDialogFocus();
\r
50 Display display = parent.getDisplay();
\r
51 while (!shell.isDisposed()) {
\r
52 if (!display.readAndDispatch()) {
\r
59 private void close() {
\r
60 assert shell != null;
\r
65 static void unblock() {
\r
66 assert blockCount >= 0;
\r
67 assert Display.getCurrent() != null; // On SWT event thread
\r
70 // System.out.println("Deleting SWT blocker");
\r
71 if (blockCount == 0) {
\r
74 if ((blockCount == 1) && (instance != null)) {
\r
81 static void block() {
\r
82 assert blockCount >= 0;
\r
84 // System.out.println("Creating SWT blocker");
\r
85 final Display display = Display.getCurrent();
\r
86 assert display != null; // On SWT event thread
\r
89 if (blockCount == 1) {
\r
90 assert instance == null; // should be no existing blocker
\r
92 // get a shell to parent the blocking dialog
\r
93 Shell shell = AwtEnvironment.getInstance(display).getShell();
\r
95 // If there is a shell to block, block input now. If there are no shells,
\r
96 // then there is no input to block. In the case of no shells, we are not
\r
97 // protecting against a shell that might get created later. This is a rare
\r
98 // enough case to skip, at least for now. In the future, a listener could be
\r
99 // added to cover it.
\r
100 // TODO: if (shell==null) add listener to block shells created later?
\r
102 // Block is implemented with a hidden modal dialog. Using setEnabled(false) is another option, but
\r
103 // on some platforms that will grey the disabled controls.
\r
104 if (shell != null) {
\r
105 instance = new SwtInputBlocker(shell);
\r