Forces all dialogs except for the clipboard to be modal.  Fixes cases where dialogs are not brought to the front while in fullscreen mode.  Corrects a few corner cases where viewer did not exit properly.

git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4988 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/java/com/tigervnc/vncviewer/CConn.java b/java/com/tigervnc/vncviewer/CConn.java
index 7ad2b02..9adb967 100644
--- a/java/com/tigervnc/vncviewer/CConn.java
+++ b/java/com/tigervnc/vncviewer/CConn.java
@@ -122,14 +122,13 @@
         serverPort = Hostname.getPort(vncServerName);
       } else {
         ServerDialog dlg = new ServerDialog(options, vncServerName, this);
-        if (!dlg.showDialog() || dlg.server.getSelectedItem().equals("")) {
-          vlog.info("No server name specified!");
+        boolean ret = dlg.showDialog();
+        if (!ret) {
           close();
           return;
         }
-        vncServerName = (String)dlg.server.getSelectedItem();
-        serverHost = Hostname.getHost(vncServerName);
-        serverPort = Hostname.getPort(vncServerName);
+        serverHost = viewer.vncServerName.getValueStr();
+        serverPort = viewer.vncServerPort.getValue();
       }
 
       try {
@@ -727,15 +726,24 @@
       pkgDate = attributes.getValue("Package-Date");
       pkgTime = attributes.getValue("Package-Time");
     } catch (IOException e) { }
+
+    Window fullScreenWindow = Viewport.getFullScreenWindow();
+    if (fullScreenWindow != null)
+      Viewport.setFullScreenWindow(null);
     JOptionPane.showMessageDialog((viewport != null ? viewport : null),
       String.format(VncViewer.aboutText, VncViewer.version, VncViewer.build,
                     VncViewer.buildDate, VncViewer.buildTime), 
       "About TigerVNC Viewer for Java",
       JOptionPane.INFORMATION_MESSAGE,
       logo);
+    if (fullScreenWindow != null)
+      Viewport.setFullScreenWindow(fullScreenWindow);
   }
 
   void showInfo() {
+    Window fullScreenWindow = Viewport.getFullScreenWindow();
+    if (fullScreenWindow != null)
+      Viewport.setFullScreenWindow(null);
     JOptionPane.showMessageDialog(viewport,
       "Desktop name: "+cp.name()+"\n"
       +"Host: "+sock.getPeerName()+":"+sock.getPeerPort()+"\n"
@@ -750,6 +758,8 @@
        +" ["+csecurity.description()+"]",
       "VNC connection info",
       JOptionPane.PLAIN_MESSAGE);
+    if (fullScreenWindow != null)
+      Viewport.setFullScreenWindow(fullScreenWindow);
   }
 
   public void refresh() {
diff --git a/java/com/tigervnc/vncviewer/ClipboardDialog.java b/java/com/tigervnc/vncviewer/ClipboardDialog.java
index 69fc711..41f92b1 100644
--- a/java/com/tigervnc/vncviewer/ClipboardDialog.java
+++ b/java/com/tigervnc/vncviewer/ClipboardDialog.java
@@ -97,12 +97,10 @@
       current = "";
       textArea.setText(current);
     } else if (s instanceof JButton && (JButton)s == sendButton) {
-      ok = true;
       current = textArea.getText();
       cc.writeClientCutText(current, current.length());
       endDialog();
     } else if (s instanceof JButton && (JButton)s == cancelButton) {
-      ok = false;
       endDialog();
     }
   }
diff --git a/java/com/tigervnc/vncviewer/Dialog.java b/java/com/tigervnc/vncviewer/Dialog.java
index 274cdff..5e6790f 100644
--- a/java/com/tigervnc/vncviewer/Dialog.java
+++ b/java/com/tigervnc/vncviewer/Dialog.java
@@ -29,22 +29,20 @@
 package com.tigervnc.vncviewer;
 
 import java.awt.*;
+import java.awt.Dialog.*;
 import javax.swing.*;
 
-//class Dialog extends JFrame implements WindowListener {
-class Dialog extends JFrame {
+class Dialog extends JDialog {
 
-  protected boolean ok, done;
-  boolean modal;
-
-  public Dialog(boolean modal_) {
-    modal = modal_;
-    //addWindowListener(this);
+  public Dialog(boolean modal) {
+    if (modal) {
+      setModalityType(ModalityType.APPLICATION_MODAL);
+    } else {
+      setModalityType(ModalityType.MODELESS);
+    }
   }
 
   public boolean showDialog(Component c) {
-    ok = false;
-    done = false;
     initDialog();
     if (c != null) {
       setLocationRelativeTo(c);
@@ -58,20 +56,14 @@
     ClassLoader cl = this.getClass().getClassLoader();
     ImageIcon icon = new ImageIcon(cl.getResource("com/tigervnc/vncviewer/tigervnc.ico"));
     setIconImage(icon.getImage());
-    //setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
-    //setFont(new Font("SansSerif", Font.PLAIN, 11));
+    fullScreenWindow = Viewport.getFullScreenWindow();
+    if (fullScreenWindow != null)
+      Viewport.setFullScreenWindow(null);
 
     setVisible(true);
     setFocusable(true);
-    if (!modal) return true;
-    synchronized(this) {
-      try {
-        while (!done)
-          wait();
-      } catch (InterruptedException e) {
-      }
-    }
-    return ok;
+    setAlwaysOnTop(true);
+    return ret;
   }
 
   public boolean showDialog() {
@@ -79,14 +71,11 @@
   }
 
   public void endDialog() {
-    done = true;
     setVisible(false);
     setFocusable(false);
-    if (modal) {
-      synchronized (this) {
-        notify();
-      }
-    }
+    setAlwaysOnTop(false);
+    if (fullScreenWindow != null)
+      Viewport.setFullScreenWindow(fullScreenWindow);
   }
 
   // initDialog() can be overridden in a derived class.  Typically it is used
@@ -94,23 +83,6 @@
   public void initDialog() {
   }
 
-  //------------------------------------------------------------------ 
-  //   implemented blank methods
-  //public void windowClosed(WindowEvent event){}
-  //public void windowDeiconified(WindowEvent event){}
-  //public void windowIconified(WindowEvent event){}
-  //public void windowActivated(WindowEvent event){}
-  //public void windowDeactivated(WindowEvent event){}
-  //public void windowOpened(WindowEvent event){}
-
-  //------------------------------------------------------------------
-
-  // method to check which window was closing
-  //public void windowClosing(WindowEvent event) {
-  //  ok = false;
-  //  endDialog();
-  //}
-
   public void addGBComponent(JComponent c, JComponent cp,
                              int gx, int gy, 
                              int gw, int gh, 
@@ -134,14 +106,7 @@
       cp.add(c, gbc);
   }
 
-  final public String getFileSeperator() {
-    String seperator = System.getProperties().get("file.separator").toString();
-    return seperator;
-  }
-
-  final public String getUserName() {
-    String userName = (String)System.getProperties().get("user.name");
-    return userName;
-  }
+  private Window fullScreenWindow;
+  protected boolean ret = true;
 
 }
diff --git a/java/com/tigervnc/vncviewer/F8Menu.java b/java/com/tigervnc/vncviewer/F8Menu.java
index 07e8974..ee7ae87 100644
--- a/java/com/tigervnc/vncviewer/F8Menu.java
+++ b/java/com/tigervnc/vncviewer/F8Menu.java
@@ -19,6 +19,7 @@
 
 package com.tigervnc.vncviewer;
 
+import java.awt.*;
 import java.awt.Cursor;
 import java.awt.event.*;
 import javax.swing.JFrame;
@@ -122,7 +123,12 @@
       fc.setDialogTitle("Save current configuration as:");
       fc.setApproveButtonText("OK");
       fc.setFileHidingEnabled(false);
+      Window fullScreenWindow = Viewport.getFullScreenWindow();
+      if (fullScreenWindow != null)
+        Viewport.setFullScreenWindow(null);
       int ret = fc.showOpenDialog(this);
+      if (fullScreenWindow != null)
+        Viewport.setFullScreenWindow(fullScreenWindow);
       if (ret == JFileChooser.APPROVE_OPTION) {
         String filename = fc.getSelectedFile().toString();
         if (filename != null)
diff --git a/java/com/tigervnc/vncviewer/OptionsDialog.java b/java/com/tigervnc/vncviewer/OptionsDialog.java
index 4975733..80d9f40 100644
--- a/java/com/tigervnc/vncviewer/OptionsDialog.java
+++ b/java/com/tigervnc/vncviewer/OptionsDialog.java
@@ -52,7 +52,7 @@
   JButton cfLoadButton, cfSaveAsButton, defSaveButton, defReloadButton, defClearButton;
 
   public OptionsDialog(OptionsDialogCallback cb_) { 
-    super(false);
+    super(true);
     cb = cb_;
     setResizable(false);
     setTitle("VNC Viewer Options");
@@ -292,7 +292,6 @@
   }
   
   private void updatePreferences() {
-    //UserPreferences.clear("global");
     if (autoSelect.isSelected()) {
       UserPreferences.set("global", "AutoSelect", true);
     } else {
@@ -472,11 +471,9 @@
   public void actionPerformed(ActionEvent e) {
     Object s = e.getSource();
     if (s instanceof JButton && (JButton)s == okButton) {
-      ok = true;
       if (cb != null) cb.getOptions();
       endDialog();
     } else if (s instanceof JButton && (JButton)s == cancelButton) {
-      ok = false;
       endDialog();
     } else if (s instanceof JButton && (JButton)s == cfLoadButton) {
       JFileChooser fc = new JFileChooser();
diff --git a/java/com/tigervnc/vncviewer/PasswdDialog.java b/java/com/tigervnc/vncviewer/PasswdDialog.java
index c12fad5..10281e0 100644
--- a/java/com/tigervnc/vncviewer/PasswdDialog.java
+++ b/java/com/tigervnc/vncviewer/PasswdDialog.java
@@ -32,7 +32,11 @@
     super(true);
     setResizable(false);
     setTitle(title);
-    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+    addWindowListener(new WindowAdapter() {
+      public void windowClosing(WindowEvent e) {
+        endDialog();
+      }
+    });
 
     JPanel p1 = new JPanel();
     userLabel = new JLabel("Username:");
@@ -73,18 +77,16 @@
     Object s = event.getSource();
     if (s instanceof JTextField && (JTextField)s == userEntry) {
        if (event.getKeyCode() == KeyEvent.VK_ENTER) {
-         ok = true;
          endDialog();
         }
     } else if (s instanceof JPasswordField && (JPasswordField)s == passwdEntry) {
         if (event.getKeyCode() == KeyEvent.VK_ENTER) {
-         ok = true;
          endDialog();
         }
     }
   }
 
-  public String getPassword(){ 
+  public String getPassword() { 
     return new String(passwdEntry.getPassword());
   }
   public String getPassphrase(){ return null; }
diff --git a/java/com/tigervnc/vncviewer/ServerDialog.java b/java/com/tigervnc/vncviewer/ServerDialog.java
index 3efc585..976dc7f 100644
--- a/java/com/tigervnc/vncviewer/ServerDialog.java
+++ b/java/com/tigervnc/vncviewer/ServerDialog.java
@@ -47,7 +47,7 @@
         if (cc.viewer.nViewers == 1) {
           cc.viewer.exit(1);
         } else {
-          ok = false;
+          ret = false;
           endDialog();
         }
       }
@@ -117,21 +117,18 @@
   }
 
   public void itemStateChanged(ItemEvent e) {
-    //Object s = e.getSource();
+    return;
   }
 
   public void actionPerformed(ActionEvent e) {
     Object s = e.getSource();
     if (s instanceof JButton && (JButton)s == okButton) {
-      ok = true;
-      String serverName = (String)server.getSelectedItem();
-      if (serverName != null) {
-        Configuration.setParam("Server", Hostname.getHost(serverName));
-        Configuration.setParam("Port", Integer.toString(Hostname.getPort(serverName)));
-      }
+      commit();
       endDialog();
     } else if (s instanceof JButton && (JButton)s == cancelButton) {
-      ok = false;
+      if (cc.viewer.nViewers == 1)
+        cc.viewer.exit(1);
+      ret = false;
       endDialog();
     } else if (s instanceof JButton && (JButton)s == optionsButton) {
       options.showDialog(this);
@@ -141,38 +138,42 @@
       if (e.getActionCommand().equals("comboBoxEdited")) {
         server.insertItemAt(editor.getItem(), 0);
         server.setSelectedIndex(0);
-        ok = true;
+        commit();
         endDialog();
       }
     }
   }
+
+  private void commit() {
+    String serverName = (String)server.getSelectedItem();
+    if (serverName == null || serverName.equals("")) {
+      vlog.error("Invalid servername specified");
+      if (cc.viewer.nViewers == 1)
+        cc.viewer.exit(1);
+      ret = false;
+      endDialog();
+    }
+    // set params
+    Configuration.setParam("Server", Hostname.getHost(serverName));
+    Configuration.setParam("Port", Integer.toString(Hostname.getPort(serverName)));
+    // Update the history list
+    String valueStr = UserPreferences.get("ServerDialog", "history");
+    String t = (valueStr == null) ? "" : valueStr;
+    StringTokenizer st = new StringTokenizer(t, ",");
+    StringBuffer sb = new StringBuffer().append((String)server.getSelectedItem());
+    while (st.hasMoreTokens()) {
+      String str = st.nextToken();
+      if (!str.equals((String)server.getSelectedItem()) && !str.equals("")) {
+        sb.append(',');
+        sb.append(str);
+      }
+    }
+    UserPreferences.set("ServerDialog", "history", sb.toString());
+    UserPreferences.save("ServerDialog");
+  }
   
   public void endDialog() {
-    if (ok) {
-      if (!server.getSelectedItem().toString().equals("")) {
-        String valueStr = UserPreferences.get("ServerDialog", "history");
-        String t = (valueStr == null) ? "" : valueStr;
-        StringTokenizer st = new StringTokenizer(t, ",");
-        StringBuffer sb = new StringBuffer().append((String)server.getSelectedItem());
-        while (st.hasMoreTokens()) {
-          String s = st.nextToken();
-          if (!s.equals((String)server.getSelectedItem()) && !s.equals("")) {
-            sb.append(',');
-            sb.append(s);
-          }
-        }
-        UserPreferences.set("ServerDialog", "history", sb.toString());
-        UserPreferences.save("ServerDialog");
-      }
-    }
-
-    done = true;
-    if (modal) {
-      synchronized (this) {
-        notify();
-      }
-    }
-    this.dispose();
+    super.endDialog();
   }
 
   CConn cc;
diff --git a/java/com/tigervnc/vncviewer/Viewport.java b/java/com/tigervnc/vncviewer/Viewport.java
index 503a653..c148416 100644
--- a/java/com/tigervnc/vncviewer/Viewport.java
+++ b/java/com/tigervnc/vncviewer/Viewport.java
@@ -24,6 +24,10 @@
 import java.awt.event.*;
 import java.awt.Dimension;
 import java.awt.Event;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Window;
 import javax.swing.*;
 
 import com.tigervnc.rdr.*;
@@ -49,7 +53,11 @@
     });
     addWindowListener(new WindowAdapter() {
       public void windowClosing(WindowEvent e) {
-        cc.close();
+        if (cc.viewer.nViewers == 1) {
+          cc.viewer.exit(1);
+        } else {
+          cc.close();
+        }
       }
     });
     addComponentListener(new ComponentAdapter() {
@@ -105,6 +113,20 @@
     setBackground(Color.BLACK);
   }
 
+  public static Window getFullScreenWindow() {
+      GraphicsEnvironment ge =
+        GraphicsEnvironment.getLocalGraphicsEnvironment();
+      GraphicsDevice gd = ge.getDefaultScreenDevice();
+      Window fullScreenWindow = gd.getFullScreenWindow();
+      return fullScreenWindow;
+  }
+
+  public static void setFullScreenWindow(Window fullScreenWindow) {
+      GraphicsEnvironment ge =
+        GraphicsEnvironment.getLocalGraphicsEnvironment();
+      GraphicsDevice gd = ge.getDefaultScreenDevice();
+      gd.setFullScreenWindow(fullScreenWindow);
+  }
 
   CConn cc;
   JScrollPane sp;