exporting patch:
# HG changeset patch
# User Daniel J Sebald <daniel.sebald@ieee.org>
# Date 1522528159 18000
#      Sat Mar 31 15:29:19 2018 -0500
# Branch stable
# Node ID 8427e797dc1bf2f4300ac35eb5a64c14cb50f1fc
# Parent  25d4e3dda70ec18b825c3ae2966353655606705b
Use default title bar to preserve GUI float decorations (bug #53276)

* documentation-dock-widget.cc (constructor): Use setWindowTitle() for default
  title bar instead of set_title().
* files-dock-widget.cc (constructor): Ditto.
* history-dock-widget.cc (history_dock_widget::construct): Ditto.
* file-editor.cc (file_editor::construct): Ditto.
* terminal-dock-widget.cc (constructor): Ditto.
* workspace-view.cc (constructor): Ditto.

* main-window.cc (main_window::read_settings): Move settings_changed() ahead of
  layout function set_window_layout().
  (main_window::set_window_layout): Remove reparent step make_widget(false).

* octave-dock-widget.cc (label_dock_widget::label_dock_widget): Initialize
  m_default_float_button and m_default_close_button to nullptr then check for
  the existence of these buttons in the default title bar.  Do not call
  setTitleBarWidget(m_title_widget).
  (label_dock_widget::set_title): Use m_title_widget for pointer instead of
  titleBarWidget().  Call setTitleBarWidget(m_title_widget) to activate use of
  custom title bar.
  (qdockwidget_css): Added.  New local routine that constructs the cascading
  style sheet for the QDockWidget used in several places.
  (octave_dock_widget::octave_dock_widget): Initialize m_recent_float_geom,
  m_recent_dock_area and m_recent_dock_geom.  Remove m_floating.  Connect the
  topLevelChanged() signal to the toplevel_change() slot.  Do not restrict
  features floatable and closeable.  If the m_default_float_button was found,
  disconnect its default slots and connect it instead to slot make_window().
  Enable queuing of make_window() via the queue_make_window() signal.
  Enable queuing of make_widget() via the queue_make_widget() signal.
  Connect the m_dock_action triggered() signal to make_window() slot rather
  than change_floating().  Set the style sheet (icons and tooltips) for the
  dockable widget and disable the main widget's tooltip.  Set all dock widget
  features.
  (octave_dock_widget::make_window): Change the input to be bool (unused) so
  that the function can be used as a slot.  Disconnect the signal which
  accounts for drag-and-drop route here.  Set floating off prior to making it
  a toplevel window.  Do not do a second reparent with a custom title bar.  Get
  geometry from m_recent_float_geom rather than settings.  Drop use of
  m_floating.  Make the (un)dock icon adjustment more elaborate by using
  style sheets via the set_style() function.  Disconnect the existing behavior
  and connect the "make widget" behavior into the appropriate button/action.
  Call raise(), show() and activateWindow() to bring the new window to the
  front of the GUI desktop.
  (octave_dock_widget::make_widget): Drop the dock/not-dock logic.  When
  adding widget back to parent window set the area to m_recent_dock_area.
  Make the (un)dock icon adjustment more elaborate by using style sheets via
  set_style() function.  Disconnect the existing behavior and connect the
  "make window" behavior into the appropriate button/action.
  (octave_dock_widget::default_dock): Added.  Simply call base setFloating()
  with argument "false".
  (octave_dock_widget::make_window_on_one_focus_change): Added.  When attached
  to active_dock_changed() signal, this slot will check if the window needs to
  be converted to a full-decoration top-level window and queue make_window() if
  necessary.
  (octave_dock_widget::event): Reimplement the virtual low-level function to
  check if a conversion from widget to window to place as a result of a
  double-click, and if so disconnect the one-time drag-and-drop connection and
  emit a queued make_window().
  (octave_dock_widget::handle_settings): Get the geometry and docked layout
  information, stored in m_recent_float_geom, m_recent_dock_area and
  m_recent_dock_geom.
  (octave_dock_widget::save_settings): Get saved geometry info from
  m_recent_float_geom, m_recent_dock_area and m_recent_dock_geom.  Use
  isFloating() rather than m_floating for "Floating" state.
  (octave_dock_widget::change_floating): Removed.
  (octave_dock_widget::store_geometry): Added.  Reuasable routine to save
  geometry and dock info in the appropriate variables based on isFloating()
  state.
  (octave_dock_widget::moveEvent): Added.  Reimplemented virtual routine to
  store the geometry whenever the widget is moved.
  (octave_dock_widget::resizeEvent): Added.  Reimplemented virtual routine to
  store the geometry whenever the widget is resized.
  (octave_dock_widget::toplevel_change): Added.  Puts a fallback behavior in
  place in case the transition to a toplevel window fails on some OS.  Also,
  handles drag float and double-click float by connecting active_dock_changed()
  to make_window_on_one_focus_change() if toplevel input is true.  If toplevel
  input is false, disconnect make_window_on_one_focus_change() from
  active_dock_changed().  If need to reparent, emit queue_make_widget() to
  avoid button-click/double-click corruption.
  (octave_dock_widget::set_style): Use isFloating() instead of m_floating.
  Condition the style changes to custom title bar widgets on titleBarWidget()
  and use CSS style sheets to match the default title bar color scheme to that
  of the custom title bar.

* octave-dock-widget.h (label_dock_widget::set_title): Add note about selecting
  use of default or custom title bar via this routine.  Add pointers
  m_default_float_button and m_default_close_button.
  (octave_dock_widget::make_window): Change to a public slot with an unused
  bool input variable.
  (octave_dock_widget::make_widget): Change to a public slot.
  (octave_dock_widget::queue_make_window): Added.  New signal to queue
  make_window() and avoid crash when calling make_widget() directly.
  (octave_dock_widget::queue_make_widget): Added.  New signal to queue
  make_widget() and avoid mouse click corruption when calling make_widget()
  directly.
  (octave_dock_widget::event): Added.  Remplement low-level event() routine,
  check for double-click float.
  (octave_dock_widget::moveEvent): Added.  Declartion of re-implemented virtual
  routine.
  (octave_dock_widget::resizeEvent): Ditto.
  (octave_dock_widget::default_dock): Added.  A simple routine that calls the
  default setFloating(false).
  (octave_dock_widget::make_window_on_one_focus_change): Added.  New slot for
  implementing a single delayed make_window() if needed.
  (octave_dock_widget::change_floating): Removed.
  (octave_dock_widget::toplevel_change): Added.  React to topLevelChanged()
  signal and install the default button action in case toplevel transition
  fails.  Check if (re)parent action needed.

* variable-editor.cc (variable_dock_widget::variable_dock_widget): Use pointer
  m_title_widget instead of titleBarWidget() and construct the layout
  unconditionally.
  (variable_dock_widget::handle_focus_change): Condition the label adjustment
  on the presence of custom titleBarWidget().
  (variable_editor::variable_editor): Use setWindowTitle() for default
  title bar instead of set_title().
  (variable_editor::edit_variable): Condition the connection between the
  model's update_lable_signal() and label's setText() slot on the presence
  of custom titleBarWidget().

diff --git a/libgui/src/documentation-dock-widget.cc b/libgui/src/documentation-dock-widget.cc
--- a/libgui/src/documentation-dock-widget.cc
+++ b/libgui/src/documentation-dock-widget.cc
@@ -36,7 +36,7 @@ namespace octave
   {
     setObjectName ("DocumentationDockWidget");
     setWindowIcon (QIcon (":/actions/icons/logo.png"));
-    set_title (tr ("Documentation"));
+    setWindowTitle (tr ("Documentation"));
     setStatusTip (tr ("See the documentation for help."));
 
     m_webinfo = new octave::webinfo (this);
diff --git a/libgui/src/files-dock-widget.cc b/libgui/src/files-dock-widget.cc
--- a/libgui/src/files-dock-widget.cc
+++ b/libgui/src/files-dock-widget.cc
@@ -70,7 +70,7 @@ namespace octave
   {
     setObjectName ("FilesDockWidget");
     setWindowIcon (QIcon (":/actions/icons/logo.png"));
-    set_title (tr ("File Browser"));
+    setWindowTitle (tr ("File Browser"));
     setToolTip (tr ("Browse your files"));
 
     m_sig_mapper = nullptr;
diff --git a/libgui/src/history-dock-widget.cc b/libgui/src/history-dock-widget.cc
--- a/libgui/src/history-dock-widget.cc
+++ b/libgui/src/history-dock-widget.cc
@@ -297,7 +297,7 @@ namespace octave
     m_filter_checkbox = new QCheckBox ();
 
     setWindowIcon (QIcon (":/actions/icons/logo.png"));
-    set_title (tr ("Command History"));
+    setWindowTitle (tr ("Command History"));
     setWidget (new QWidget ());
 
     m_filter_widget = new QWidget (this);
diff --git a/libgui/src/m-editor/file-editor.cc b/libgui/src/m-editor/file-editor.cc
--- a/libgui/src/m-editor/file-editor.cc
+++ b/libgui/src/m-editor/file-editor.cc
@@ -2030,7 +2030,7 @@ namespace octave
 
     resize (500, 400);
     setWindowIcon (QIcon (":/actions/icons/logo.png"));
-    set_title (tr ("Editor"));
+    setWindowTitle (tr ("Editor"));
 
     check_actions ();
   }
diff --git a/libgui/src/main-window.cc b/libgui/src/main-window.cc
--- a/libgui/src/main-window.cc
+++ b/libgui/src/main-window.cc
@@ -1208,6 +1208,8 @@ namespace octave
         return;
       }
 
+    emit settings_changed (settings);
+
     set_window_layout (settings);
 
     // restore the list of the last directories
@@ -1217,7 +1219,6 @@ namespace octave
       {
         m_current_directory_combo_box->addItem (curr_dirs.at (i));
       }
-    emit settings_changed (settings);
   }
 
   void main_window::init_terminal_size (void)
@@ -1258,9 +1259,6 @@ namespace octave
               }
             else  // not floating
               {
-                if (! widget->parent ())        // should not be floating but is
-                  widget->make_widget (false);  // no docking, just reparent
-
                 widget->make_widget ();
                 widget->setVisible (visible);   // not floating -> show
               }
diff --git a/libgui/src/octave-dock-widget.cc b/libgui/src/octave-dock-widget.cc
--- a/libgui/src/octave-dock-widget.cc
+++ b/libgui/src/octave-dock-widget.cc
@@ -39,11 +39,29 @@ along with Octave; see the file COPYING.
 namespace octave
 {
   label_dock_widget::label_dock_widget (QWidget *p)
-    : QDockWidget (p)
+    : QDockWidget (p), m_default_float_button (nullptr),
+      m_default_close_button (nullptr)
   {
     QStyle *st = style ();
     m_icon_size = 0.75*st->pixelMetric (QStyle::PM_SmallIconSize);
 
+    // keep track of the original buttons on the default title bar,
+    // the button further left is considered "float"
+    QList<QAbstractButton *> buttonlist = findChildren<QAbstractButton *> ();
+    if (buttonlist.size () == 2)
+      {
+        if (buttonlist.at (0)->x () < buttonlist.at (1)->x ())
+          {
+            m_default_float_button = buttonlist.at (0);
+            m_default_close_button = buttonlist.at (1);
+          }
+        else
+          {
+            m_default_float_button = buttonlist.at (0);
+            m_default_close_button = buttonlist.at (1);
+          }
+      }
+
     // the custom (extra) title bar of the widget
     m_title_widget = new QWidget ();
 
@@ -75,7 +93,6 @@ namespace octave
     h_layout->setContentsMargins (5,2,2,2);
 
     m_title_widget->setLayout (h_layout);
-    setTitleBarWidget (m_title_widget);
 
     // copy & paste handling
     connect (p, SIGNAL (copyClipboard_signal ()),
@@ -93,21 +110,69 @@ namespace octave
   label_dock_widget::set_title (const QString& title)
   {
     QHBoxLayout *h_layout
-      = static_cast<QHBoxLayout *> (titleBarWidget ()->layout ());
-    QLabel *label = new QLabel (title, titleBarWidget ());
+      = static_cast<QHBoxLayout *> (m_title_widget->layout ());
+    QLabel *label = new QLabel (title, m_title_widget);
     label->setStyleSheet ("background: transparent;");
     h_layout->insertWidget (0,label);
+    setTitleBarWidget (m_title_widget);
     setWindowTitle (title);
   }
 
 
+  static QString
+  qdockwidget_css (const QString& close_icon, const QString& close_tooltip,
+                   const QString& float_icon, const QString& float_tooltip,
+                   int icon_size, const QString& titlebar_tooltip,
+                   const QString& titlebar_background)
+  {
+    // Not exactly "title bar tooltip", actually any area not having a tool tip.
+    // Can capture QEvent::ToolTip in the event filter and disregard anything
+    // outside the title bar area, but the preferred option is not needing
+    // a title bar tooltip.
+    return QString ("QDockWidget::close-button, QDockWidget::float-button\n"
+                    "{\n"
+                    "  border: none;\n"
+                    "  icon-size: %1px;\n"
+                    "}\n"
+                    "\n"
+                    "QDockWidget\n"
+                    "{\n"
+                    "  border: none;\n"
+                    "  qproperty-toolTip: \"%2\";\n"
+                    "  titlebar-close-icon: url(%3);\n"
+                    "  titlebar-normal-icon: url(%4);\n"
+                    "}\n"
+                    "\n"
+                    "QAbstractButton#qt_dockwidget_closebutton\n"
+                    "{\n"
+                    "  qproperty-toolTip: \"%5\";\n"
+                    "}\n"
+                    "\n"
+                    "QAbstractButton#qt_dockwidget_floatbutton\n"
+                    "{\n"
+                    "  qproperty-toolTip: \"%6\";\n"
+                    "}\n"
+                    "\n"
+                    "QDockWidget::title {\n"
+                    "  text-align: left;\n"
+                    "  %7\n"
+                    "  padding-left: 1px;\n"
+                    "}\n"
+                    ).arg (icon_size).arg (titlebar_tooltip)
+                     .arg (close_icon).arg (float_icon)
+                     .arg (close_tooltip).arg (float_tooltip)
+                     .arg (titlebar_background);
+  }
+
   octave_dock_widget::octave_dock_widget (QWidget *p)
-    : label_dock_widget (p)
+    : label_dock_widget (p), m_recent_float_geom (),
+      m_recent_dock_area (Qt::NoDockWidgetArea), m_recent_dock_geom ()
   {
     m_parent = static_cast<QMainWindow *> (p);     // store main window
-    m_floating = false;
     m_predecessor_widget = nullptr;
 
+    connect (this, SIGNAL (topLevelChanged (bool)),
+             this, SLOT (toplevel_change (bool)));
     connect (this, SIGNAL (visibilityChanged (bool)),
              this, SLOT (handle_visibility_changed (bool)));
 
@@ -119,21 +184,42 @@ namespace octave
              this, SLOT (handle_active_dock_changed (octave_dock_widget*,
                                                      octave_dock_widget*)));
 
-    setFeatures (QDockWidget::DockWidgetMovable); // not floatable or closeable
+    if (m_default_float_button != nullptr)
+      {
+        disconnect (m_default_float_button, 0, 0, 0);
+        connect (m_default_float_button, SIGNAL (clicked (bool)),
+                 this, SLOT (make_window (bool)));
+      }
+    connect (this, SIGNAL (queue_make_window ()),
+             this, SLOT (make_window ()), Qt::QueuedConnection);
+    connect (this, SIGNAL (queue_make_widget ()),
+             this, SLOT (make_widget ()), Qt::QueuedConnection);
 
     connect (m_dock_action, SIGNAL (triggered (bool)),
-             this, SLOT (change_floating (bool)));
+             this, SLOT (make_window (bool)));
     connect (m_close_action, SIGNAL (triggered (bool)),
              this, SLOT (change_visibility (bool)));
 
     m_close_action->setToolTip (tr ("Hide widget"));
 
+    setStyleSheet (qdockwidget_css (QString (":/actions/icons/widget-close.png"),
+                                    QString ("Close widget"),
+                                    QString (":/actions/icons/widget-undock.png"),
+                                    QString ("Undock widget"),
+                                    m_icon_size,
+                                    QString (""),
+                                    QString ("")));
+    if (widget ())
+      widget ()->setToolTip (QString (""));
+
     m_icon_color = "";
     m_title_3d = 50;
 
     installEventFilter (this);
 
     setFocusPolicy (Qt::StrongFocus);
+
+    setFeatures (QDockWidget::AllDockWidgetFeatures);
   }
 
   // connect signal visibility changed to related slot (called from main-window)
@@ -147,82 +233,110 @@ namespace octave
 
   // make the widget floating
   void
-  octave_dock_widget::make_window (void)
+  octave_dock_widget::make_window (bool)
   {
-    // the widget has to be reparented (parent = 0)
+    // connection not needed anymore after reaching this point
+    disconnect (m_parent, SIGNAL (active_dock_changed (octave_dock_widget*,
+                                                       octave_dock_widget*)),
+                this, SLOT (make_window_on_one_focus_change (octave_dock_widget*,
+                                                             octave_dock_widget*)));
 
-    QSettings *settings = resource_manager::get_settings ();
-
-    // save the docking area and geometry for later redocking
-    settings->setValue ("DockWidgets/" + objectName () + "_dock_area",
-                        m_parent->dockWidgetArea (this));
-    settings->setValue ("DockWidgets/" + objectName (), saveGeometry ());
-    settings->sync ();
-
-    // remove parent and adjust the (un)dock icon
-    setTitleBarWidget (0);
-    setParent (0, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
-               Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
-    setTitleBarWidget (m_title_widget);
+    // the widget has to be reparented (parent = 0), preferably
+    // from a non-toplevel widget otherwise may not have full
+    // decorations, e.g., no taskbar icon and always in front
+    setFloating (false);
+// Remove after thorough testing 3/20/18    m_parent->removeDockWidget (this);
     setParent (0, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
                Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
 
-#if defined (Q_OS_UNIX)
-    m_title_widget->setToolTip (
-      tr ("Use <Alt> + <Left Mouse Button> for moving the window"));
-#endif
-
-    m_dock_action->setIcon (QIcon (":/actions/icons/widget-dock"
-                                   + m_icon_color + ".png"));
-    m_dock_action->setToolTip (tr ("Dock widget"));
-
     // restore the last geometry when floating
-    setGeometry (settings->value ("DockWidgets/" + objectName ()
-                                  + "_floating_geometry",
-                                  QRect (50,100,480,480)).toRect ());
-
-    m_floating = true;
+    QRect geom = m_recent_float_geom.isNull () ? QRect (50,100,480,480)
+                                               : m_recent_float_geom;
+    setGeometry (geom);
 
     set_focus_predecessor ();  // set focus previously active widget if tabbed
+
+    // adjust the (un)dock icon
+    if (titleBarWidget ())
+      {
+#if defined (Q_OS_UNIX)
+        m_title_widget->setToolTip (
+          tr ("Use <Alt> + <Left Mouse Button> for moving the window"));
+#endif
+        m_dock_action->setIcon (QIcon (":/actions/icons/widget-dock"
+                                       + m_icon_color + ".png"));
+        m_dock_action->setToolTip (tr ("Dock widget"));
+        disconnect (m_dock_action, 0, this, 0);
+        connect (m_dock_action, SIGNAL (triggered (bool)),
+                 this, SLOT (make_widget (bool)));
+      }
+    else
+      {
+        set_style (isActiveWindow ());
+        disconnect (m_default_float_button, 0, this, 0);
+        connect (m_default_float_button, SIGNAL (clicked (bool)),
+                 this, SLOT (make_widget (bool)));
+      }
+
+    raise ();
+    show ();
+    activateWindow ();
   }
 
   // dock the widget
   void
-  octave_dock_widget::make_widget (bool dock)
+  octave_dock_widget::make_widget (bool)
   {
     // Since floating widget has no parent, we have to read it
-
     QSettings *settings = resource_manager::get_settings ();
 
-    // save last floating geometry if widget really was floating
-    if (m_floating)
-      settings->setValue ("DockWidgets/" + objectName () + "_floating_geometry",
-                          geometry ());
-    settings->sync ();
-
-    if (dock)
-      {
-        settings->setValue ("MainWindow/windowState", m_parent->saveState ());
-        // Stay window, otherwise will bounce back to window by default because
-        // there is no layout information for this widget in the saved settings.
-        setParent (m_parent, Qt::Window);
-        m_parent->addDockWidget (Qt::TopDockWidgetArea, this);
-        // recover old window states, hide and re-show new added widget
-        m_parent->restoreState (settings->value ("MainWindow/windowState").toByteArray ());
-        setFloating (false);
-        focus ();
-        QApplication::setActiveWindow (this);
-        m_title_widget->setToolTip ("");
-      }
-    else  // only reparent, no docking
-      setParent (m_parent);
+    settings->setValue ("MainWindow/windowState", m_parent->saveState ());
+    // Stay window, otherwise will bounce back to window by default because
+    // there is no layout information for this widget in the saved settings.
+    setParent (m_parent, Qt::Window);
+    m_parent->addDockWidget (m_recent_dock_area, this);
+    // recover old window states, hide and re-show new added widget
+    m_parent->restoreState (settings->value ("MainWindow/windowState").toByteArray ());
+    setFloating (false);
+    focus ();
+    QApplication::setActiveWindow (this);
+    show ();
 
     // adjust the (un)dock icon
-    m_dock_action->setIcon (QIcon (":/actions/icons/widget-undock"
-                                   + m_icon_color + ".png"));
-    m_dock_action->setToolTip (tr ("Undock widget"));
+    if (titleBarWidget ())
+      {
+#if defined (Q_OS_UNIX)
+        m_title_widget->setToolTip ("");
+#endif
+        m_dock_action->setIcon (QIcon (":/actions/icons/widget-undock"
+                                       + m_icon_color + ".png"));
+        m_dock_action->setToolTip (tr ("Undock widget"));
+        disconnect (m_dock_action, 0, this, 0);
+        connect (m_dock_action, SIGNAL (triggered (bool)),
+                 this, SLOT (make_window (bool)));
+      }
+    else
+      {
+        set_style (isActiveWindow ());
+        disconnect (m_default_float_button, 0, this, 0);
+        connect (m_default_float_button, SIGNAL (clicked (bool)),
+                 this, SLOT (make_window (bool)));
+      }
+  }
 
-    m_floating = false;
+  // dock the widget
+  void
+  octave_dock_widget::default_dock (bool)
+  {
+    setFloating (false);
+  }
+
+  // dock the widget
+  void
+  octave_dock_widget::make_window_on_one_focus_change (octave_dock_widget *, octave_dock_widget *w_new)
+  {
+    if (w_new == this && isFloating () && parent () != 0)
+      emit queue_make_window ();
   }
 
   // set the widget which previously had focus when tabified
@@ -250,6 +364,27 @@ namespace octave
     return w;
   }
 
+  bool
+  octave_dock_widget::event (QEvent *event)
+  {
+    // low-level check of whether docked-widget became a window via double-click
+    if (event->type () == QEvent::MouseButtonDblClick && ! isFloating ())
+      {
+        bool retval = QDockWidget::event (event);
+        if (isFloating () && parent () != 0)
+          {
+            disconnect (m_parent, SIGNAL (active_dock_changed (octave_dock_widget*,
+                                                               octave_dock_widget*)),
+                        this, SLOT (make_window_on_one_focus_change (octave_dock_widget*,
+                                                                     octave_dock_widget*)));
+            emit queue_make_window ();
+          }
+        return retval;
+      }
+
+    return QDockWidget::event (event);
+  }
+
   void
   octave_dock_widget::handle_settings (const QSettings *settings)
   {
@@ -278,7 +413,7 @@ namespace octave
 
     if (! m_custom_style)
       {
-        bcol = QWidget::palette ().color (m_title_widget->backgroundRole());
+        bcol = QWidget::palette ().color (m_title_widget->backgroundRole ());
         bcola = bcol;
       }
 
@@ -295,6 +430,24 @@ namespace octave
     else
       m_icon_color_active = "";
 
+    m_recent_float_geom = settings->value ("DockWidgets/" + objectName ()
+                                           + "_floating_geometry",
+                                           QRect (50,100,480,480)).toRect ();
+
+#if 0
+    m_recent_dock_area = settings->value ("DockWidgets/" + objectName ()
+                                          + "_dock_area", Qt::NoDockWidgetArea).toInt ();
+#else
+    m_recent_dock_area = Qt::NoDockWidgetArea;
+#endif
+
+#if 0
+    m_recent_dock_geom = settings->value ("DockWidgets/" + objectName (),
+                                          QByteArray ()).toRect ();
+#else
+    m_recent_dock_geom = QByteArray ();
+#endif
+
     notice_settings (settings);  // call individual handler
 
     set_style (false);
@@ -329,13 +482,17 @@ namespace octave
 
     settings->beginGroup ("DockWidgets");
 
-    if (m_floating) // widget is floating (windows), save actual floating geometry
-      settings->setValue (name+"_floating_geometry", geometry ());
-    else           // not floating save docked (normal) geometry
-      settings->setValue (name, saveGeometry ());
+    // conditional needed?
+    if (! m_recent_float_geom.isNull ())
+      settings->setValue (name + "_floating_geometry", m_recent_float_geom);
 
+    if (! m_recent_dock_geom.isEmpty ())
+      {
+        settings->setValue (name + "_dock_area", m_recent_dock_area);
+        settings->setValue (name, m_recent_dock_geom);
+      }
     settings->setValue (name+"Visible", isVisible ()); // store visibility
-    settings->setValue (name+"Floating", m_floating);    // store visibility
+    settings->setValue (name+"Floating", isFloating ()); // store floating
     settings->setValue (name+"_minimized", isMinimized ()); // store minimized
 
     settings->endGroup ();
@@ -353,19 +510,37 @@ namespace octave
     return QDockWidget::eventFilter (obj,e);
   }
 
-  // slot for (un)dock action
   void
-  octave_dock_widget::change_floating (bool)
+  octave_dock_widget::store_geometry (void)
   {
-    if (m_floating)
-      make_widget ();
+    if (isFloating ())
+      {
+        if (! parent ())
+          m_recent_float_geom = geometry ();
+      }
     else
       {
-        make_window ();
-        focus ();
+        m_recent_dock_area = m_parent->dockWidgetArea (this);
+        m_recent_dock_geom = saveGeometry ();
       }
   }
 
+  void
+  octave_dock_widget::moveEvent (QMoveEvent *event)
+  {
+    store_geometry ();
+
+    QDockWidget::moveEvent (event);
+  }
+
+  void
+  octave_dock_widget::resizeEvent (QResizeEvent *event)
+  {
+    store_geometry ();
+
+    QDockWidget::resizeEvent (event);
+  }
+
   // slot for hiding the widget
   void
   octave_dock_widget::change_visibility (bool)
@@ -375,6 +550,54 @@ namespace octave
   }
 
   void
+  octave_dock_widget::toplevel_change (bool toplevel)
+  {
+    QObject *dockobj;
+    const char *docksig;
+
+    if (titleBarWidget ())
+      {
+        dockobj = m_dock_action;
+        docksig = SIGNAL (triggered (bool));
+      }
+    else
+      {
+        dockobj = m_default_float_button;
+        docksig = SIGNAL (clicked (bool));
+      }
+
+    if (toplevel)
+      {
+        // This is a fallback in case the attempt to create a floated
+        // top-level window fails and the QDockWidget remains a child
+        // of the QMainWindow.
+        connect (dockobj, docksig, this, SLOT (default_dock (bool)));
+
+        // Could be dragging window, so must wait until there is a
+        // change in focus.
+        if (parent () != 0)
+            connect (m_parent, SIGNAL (active_dock_changed (octave_dock_widget*,
+                                                            octave_dock_widget*)),
+                     this, SLOT (make_window_on_one_focus_change (octave_dock_widget*,
+                                                                  octave_dock_widget*)));
+
+      }
+    else
+      {
+        // If a drag-and-drop within the QMainWindow occurred, want to remain a widget.
+        disconnect (m_parent, SIGNAL (active_dock_changed (octave_dock_widget*,
+                                                           octave_dock_widget*)),
+                    this, SLOT (make_window_on_one_focus_change (octave_dock_widget*,
+                                                                 octave_dock_widget*)));
+
+        // Making into a widget immediately will mangle the double-click
+        // status and cause problems on followup button clicks.
+        if (parent () == 0)
+          emit queue_make_widget ();
+      }
+  }
+
+  void
   octave_dock_widget::set_style (bool active)
   {
     QString css;
@@ -383,10 +606,27 @@ namespace octave
 
     QString icon_col = m_icon_color;
 
-    if (m_floating)
-      dock_icon = "widget-dock";
+    QString close_tooltip = "Close widget";
+    QString dock_tooltip;
+    QString titlebar_tooltip;
+
+    if (isFloating ())
+      {
+        dock_icon = "widget-dock";
+        dock_tooltip = "Dock widget";
+#if defined (Q_OS_UNIX)
+        // needed anymore?
+        titlebar_tooltip = "Use <Alt> + <Left Mouse Button> for moving the window";
+#else
+        titlebar_tooltip = "";
+#endif
+      }
     else
-      dock_icon = "widget-undock";
+      {
+        dock_icon = "widget-undock";
+        dock_tooltip = "Undock widget";
+        titlebar_tooltip = "";
+      }
 
 #if defined (Q_OS_MAC)
     QString alignment = "center";
@@ -437,14 +677,27 @@ namespace octave
         css = QString ("");
       }
 
-    m_title_widget->setStyleSheet (css);
-    css_button = QString ("QToolButton {background: transparent; border: 0px;}");
-    m_dock_button->setStyleSheet (css_button);
-    m_close_button->setStyleSheet (css_button);
-    m_dock_action->setIcon (QIcon (":/actions/icons/" + dock_icon + icon_col +
-                                   ".png"));
-    m_close_action->setIcon (QIcon (":/actions/icons/widget-close" + icon_col +
-                                    ".png"));
+    QString full_dock_icon = ":/actions/icons/" + dock_icon + icon_col + ".png";
+    QString full_close_icon = ":/actions/icons/widget-close" + icon_col + ".png";
+    if (titleBarWidget ())
+      {
+        titleBarWidget ()->setStyleSheet (css);
+        css_button = QString ("QToolButton {background: transparent; border: 0px;}");
+        m_dock_button->setStyleSheet (css_button);
+        m_close_button->setStyleSheet (css_button);
+        m_dock_action->setIcon (QIcon (full_dock_icon));
+        m_close_action->setIcon (QIcon (full_close_icon));
+      }
+    else
+      {
+        setStyleSheet (qdockwidget_css (full_close_icon,
+                                        close_tooltip,
+                                        full_dock_icon,
+                                        dock_tooltip,
+                                        m_icon_size,
+                                        titlebar_tooltip,
+                                        css));
+      }
   }
 
   // set focus to previously active widget in tabbed widget stack
diff --git a/libgui/src/octave-dock-widget.h b/libgui/src/octave-dock-widget.h
--- a/libgui/src/octave-dock-widget.h
+++ b/libgui/src/octave-dock-widget.h
@@ -43,6 +43,8 @@ namespace octave
 
     label_dock_widget (QWidget *p = nullptr);
 
+    // set_title() uses the custom title bar while setWindowTitle() uses
+    // the default title bar (with style sheets)
     void set_title (const QString&);
 
   protected slots:
@@ -66,6 +68,9 @@ namespace octave
     QToolButton *m_close_button;
     QAction *m_dock_action;
     QAction *m_close_action;
+
+    QAbstractButton *m_default_float_button;
+    QAbstractButton *m_default_close_button;
   };
 
   class octave_dock_widget : public label_dock_widget
@@ -80,8 +85,6 @@ namespace octave
 
     virtual void connect_visibility_changed (void);
 
-    void make_window (void);
-    void make_widget (bool dock=true);
     void set_predecessor_widget (octave_dock_widget *prev_widget);
 
   signals:
@@ -91,12 +94,18 @@ namespace octave
 
     void active_changed (bool active);
 
+    void queue_make_window (void);
+
+    void queue_make_widget (void);
+
   protected:
 
     virtual void closeEvent (QCloseEvent *e);
 
     QWidget * focusWidget (void);
 
+    bool event (QEvent *event);
+
   public slots:
 
     virtual void focus (void)
@@ -125,6 +134,18 @@ namespace octave
 
     void save_settings (void);
 
+    void moveEvent (QMoveEvent *event);
+
+    void resizeEvent (QResizeEvent *event);
+
+    void make_window (bool not_used = false);
+
+    void make_widget (bool not_used = false);
+
+    void default_dock (bool not_used = false);
+
+    void make_window_on_one_focus_change (octave_dock_widget *old, octave_dock_widget *now);
+
   protected slots:
 
     //! Slot to steer changing visibility from outside.
@@ -141,19 +162,19 @@ namespace octave
 
   private slots:
 
-    void change_floating (bool);
     void change_visibility (bool);
+    void toplevel_change (bool);
 
   private:
 
     void set_style (bool active);
     void set_focus_predecessor (void);
+    void store_geometry (void);
 
     //! Stores the parent, since we are reparenting to 0.
 
     QMainWindow *m_parent;
 
-    bool m_floating;
     bool m_custom_style;
     int m_title_3d;
     QColor m_bg_color;
@@ -163,6 +184,9 @@ namespace octave
     QString m_icon_color;
     QString m_icon_color_active;
     octave_dock_widget *m_predecessor_widget;
+    QRect m_recent_float_geom;
+    Qt::DockWidgetArea m_recent_dock_area;
+    QByteArray m_recent_dock_geom;
 
   };
 }
diff --git a/libgui/src/terminal-dock-widget.cc b/libgui/src/terminal-dock-widget.cc
--- a/libgui/src/terminal-dock-widget.cc
+++ b/libgui/src/terminal-dock-widget.cc
@@ -40,7 +40,7 @@ namespace octave
 
     setObjectName ("TerminalDockWidget");
     setWindowIcon (QIcon (":/actions/icons/logo.png"));
-    set_title (tr ("Command Window"));
+    setWindowTitle (tr ("Command Window"));
 
     setWidget (m_terminal);
     setFocusProxy (m_terminal);
diff --git a/libgui/src/variable-editor.cc b/libgui/src/variable-editor.cc
--- a/libgui/src/variable-editor.cc
+++ b/libgui/src/variable-editor.cc
@@ -116,28 +116,25 @@ namespace octave
     m_prev_floating = false;
     m_prev_geom = QRect (0, 0, 0, 0);
 
-    QHBoxLayout *h_layout = findChild<QHBoxLayout *> ();
-    if (h_layout != nullptr && titleBarWidget () != nullptr)
-      {
-        m_fullscreen_action = new QAction
-          (resource_manager::icon ("view-fullscreen", false), "", this);
-        m_fullscreen_action->setToolTip (tr (DOCKED_FULLSCREEN_BUTTON_TOOLTIP));
-        QToolButton *fullscreen_button = new QToolButton (titleBarWidget ());
-        fullscreen_button->setDefaultAction (m_fullscreen_action);
-        fullscreen_button->setFocusPolicy (Qt::NoFocus);
-        fullscreen_button->setIconSize (QSize (m_icon_size,m_icon_size));
-        QString css_button = QString ("QToolButton {background: transparent; border: 0px;}");
-        fullscreen_button->setStyleSheet (css_button);
+    QHBoxLayout *h_layout = m_title_widget->findChild<QHBoxLayout *> ();
+    m_fullscreen_action = new QAction
+      (resource_manager::icon ("view-fullscreen", false), "", this);
+    m_fullscreen_action->setToolTip (tr (DOCKED_FULLSCREEN_BUTTON_TOOLTIP));
+    QToolButton *fullscreen_button = new QToolButton (m_title_widget);
+    fullscreen_button->setDefaultAction (m_fullscreen_action);
+    fullscreen_button->setFocusPolicy (Qt::NoFocus);
+    fullscreen_button->setIconSize (QSize (m_icon_size,m_icon_size));
+    QString css_button = QString ("QToolButton {background: transparent; border: 0px;}");
+    fullscreen_button->setStyleSheet (css_button);
 
-        connect (m_fullscreen_action, SIGNAL (triggered ()),
-                 this, SLOT (change_fullscreen ()));
+    connect (m_fullscreen_action, SIGNAL (triggered ()),
+             this, SLOT (change_fullscreen ()));
 
-        int index = -1;
-        QToolButton *first = titleBarWidget ()->findChild<QToolButton *> ();
-        if (first != nullptr)
-          index = h_layout->indexOf (first);
-        h_layout->insertWidget (index, fullscreen_button);
-      }
+    int index = -1;
+    QToolButton *first = m_title_widget->findChild<QToolButton *> ();
+    if (first != nullptr)
+      index = h_layout->indexOf (first);
+    h_layout->insertWidget (index, fullscreen_button);
 #endif
 
     // Custom title bars cause loss of decorations, add a frame
@@ -254,20 +251,26 @@ namespace octave
     // The is a proxied test
     if (hasFocus ())
       {
-        QLabel *label = titleBarWidget ()->findChild<QLabel *> ();
-        if (label != nullptr)
+        if (titleBarWidget () != nullptr)
           {
-            label->setBackgroundRole (QPalette::Highlight);
-            label->setAutoFillBackground (true);
+            QLabel *label = titleBarWidget ()->findChild<QLabel *> ();
+            if (label != nullptr)
+              {
+                label->setBackgroundRole (QPalette::Highlight);
+                label->setAutoFillBackground (true);
+              }
           }
 
         emit variable_focused_signal (objectName ());
       }
     else if (old == focusWidget())
       {
-        QLabel *label = titleBarWidget ()->findChild<QLabel *> ();
-        if (label != NULL)
-          label->setBackgroundRole (QPalette::NoRole);
+        if (titleBarWidget () != nullptr)
+          {
+            QLabel *label = titleBarWidget ()->findChild<QLabel *> ();
+            if (label != nullptr)
+              label->setBackgroundRole (QPalette::NoRole);
+          }
       }
   }
 
@@ -999,7 +1002,7 @@ namespace octave
       m_hovered_focus_vname ("")
   {
     setObjectName ("VariableEditor");
-    set_title (tr ("Variable Editor"));
+    setWindowTitle (tr ("Variable Editor"));
     setStatusTip (tr ("Edit variables."));
     setWindowIcon (QIcon (":/actions/icons/logo.png"));
     setFocusPolicy (Qt::NoFocus);
@@ -1170,10 +1173,13 @@ namespace octave
     // to always supply a QLabl (initially empty) and then simply update its
     // contents.
     page->set_title (name);
-    QLabel *existing_ql = page->titleBarWidget ()->findChild<QLabel *> ();
-    connect (model, SIGNAL (update_label_signal (const QString&)),
-             existing_ql, SLOT (setText (const QString&)));
-    existing_ql->setMargin (2);
+    if (page->titleBarWidget () != nullptr)
+      {
+        QLabel *existing_ql = page->titleBarWidget ()->findChild<QLabel *> ();
+        connect (model, SIGNAL (update_label_signal (const QString&)),
+                 existing_ql, SLOT (setText (const QString&)));
+        existing_ql->setMargin (2);
+      }
 
     model->update_data (val);
 
diff --git a/libgui/src/workspace-view.cc b/libgui/src/workspace-view.cc
--- a/libgui/src/workspace-view.cc
+++ b/libgui/src/workspace-view.cc
@@ -52,7 +52,7 @@ namespace octave
   {
     setObjectName ("WorkspaceView");
     setWindowIcon (QIcon (":/actions/icons/logo.png"));
-    set_title (tr ("Workspace"));
+    setWindowTitle (tr ("Workspace"));
     setStatusTip (tr ("View the variables in the active workspace."));
 
     m_filter = new QComboBox (this);
