--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007 SAS Institute.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * SAS Institute - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.utils.ui.awt;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.FocusAdapter;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.widgets.Dialog;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Shell;\r
+\r
+\r
+\r
+class SwtInputBlocker extends Dialog {\r
+ static private SwtInputBlocker instance = null;\r
+ static private int blockCount = 0;\r
+ private Shell shell;\r
+\r
+ private SwtInputBlocker(Shell parent) {\r
+ super(parent, SWT.NONE); \r
+ }\r
+ \r
+ private Object open() {\r
+ assert Display.getCurrent() != null; // On SWT event thread\r
+ \r
+ final Shell parent = getParent();\r
+ shell = new Shell(parent, SWT.APPLICATION_MODAL);\r
+ shell.setSize(0, 0);\r
+ shell.addFocusListener(new FocusAdapter() {\r
+ public void focusGained(FocusEvent e) {\r
+ // On some platforms (e.g. Linux/GTK), the 0x0 shell still appears as a dot \r
+ // on the screen, so make it invisible by moving it below other windows. This\r
+ // is unnecessary under Windows and causes a flash, so only make the call when necessary. \r
+ if (Platform.isGtk()) {\r
+ shell.moveBelow(null);\r
+ }\r
+ AwtEnvironment.getInstance(shell.getDisplay()).requestAwtDialogFocus();\r
+ }\r
+ });\r
+ shell.open();\r
+ \r
+ Display display = parent.getDisplay();\r
+ while (!shell.isDisposed()) {\r
+ if (!display.readAndDispatch()) {\r
+ display.sleep();\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ private void close() {\r
+ assert shell != null;\r
+ \r
+ shell.dispose();\r
+ }\r
+\r
+ static void unblock() {\r
+ assert blockCount >= 0;\r
+ assert Display.getCurrent() != null; // On SWT event thread\r
+\r
+ \r
+ // System.out.println("Deleting SWT blocker");\r
+ if (blockCount == 0) {\r
+ return;\r
+ }\r
+ if ((blockCount == 1) && (instance != null)) {\r
+ instance.close();\r
+ instance = null;\r
+ }\r
+ blockCount--;\r
+ }\r
+ \r
+ static void block() {\r
+ assert blockCount >= 0;\r
+ \r
+ // System.out.println("Creating SWT blocker");\r
+ final Display display = Display.getCurrent();\r
+ assert display != null; // On SWT event thread\r
+ \r
+ blockCount++;\r
+ if (blockCount == 1) {\r
+ assert instance == null; // should be no existing blocker\r
+ \r
+ // get a shell to parent the blocking dialog\r
+ Shell shell = AwtEnvironment.getInstance(display).getShell();\r
+\r
+ // If there is a shell to block, block input now. If there are no shells, \r
+ // then there is no input to block. In the case of no shells, we are not\r
+ // protecting against a shell that might get created later. This is a rare\r
+ // enough case to skip, at least for now. In the future, a listener could be \r
+ // added to cover it. \r
+ // TODO: if (shell==null) add listener to block shells created later?\r
+ //\r
+ // Block is implemented with a hidden modal dialog. Using setEnabled(false) is another option, but \r
+ // on some platforms that will grey the disabled controls.\r
+ if (shell != null) {\r
+ instance = new SwtInputBlocker(shell);\r
+ instance.open();\r
+ }\r
+ }\r
+ }\r
+\r
+}\r