Repository: spyder-ide/spyder

Issue:
Saving layout doesn't store the right sizes.
## Problem Description
When saving a custom layout in spyder and trying to restore it, it shows different sizes for the panes.


### What steps reproduce the problem?

1. Save a layout

<img width="1440" alt="Screenshot 2020-09-29 at 2 58 54 PM" src="https://user-images.githubusercontent.com/18587879/94609379-4efb2880-0264-11eb-80aa-2c45b33e6408.png">

2. Close spyder
3. Load saved layout from the Window layouts list.

### What is the expected output? What do you see instead?

The layout that it loads is different from the one I saved.

Also:

I saved a layout called "Layout" without changing anything after loading the "Default Spyder Layout". Taking a look at the transient.ini file where the layouts are stored. I see that the parameters of these two are different when they should be the same. 

<img width="908" alt="Screenshot 2020-09-29 at 3 03 15 PM" src="https://user-images.githubusercontent.com/18587879/94609869-055f0d80-0265-11eb-97a8-38da9452b750.png">



### Paste Traceback/Error Below (if applicable)
<!--- Copy from error dialog or View > Panes > Internal Console --->

```python-traceback

PASTE TRACEBACK HERE

```

## Versions
<!--- You can get this information from Help > About Spyder...
or (if Spyder won't launch) the "conda list" command
from the Anaconda Prompt/Terminal/command line. --->

* Spyder version: 
* Python version: 
* Qt version: 
* PyQt version: 
* Operating System name/version: 

### Dependencies
<!--- Please go to the menu entry Help > Dependencies,
press the Copy to clipboard button and paste below --->

```
PASTE DEPENDENCIES HERE
```



Discussion:

Resolving patch:
diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py
--- a/spyder/app/mainwindow.py
+++ b/spyder/app/mainwindow.py
@@ -1549,18 +1549,24 @@ def report_missing_dependencies(self):
                   ) % missing_deps, QMessageBox.Ok)
 
     def load_window_settings(self, prefix, default=False, section='main'):
-        """Load window layout settings from userconfig-based configuration
-        with *prefix*, under *section*
-        default: if True, do not restore inner layout"""
+        """
+        Load window layout settings from userconfig-based configuration
+        with `prefix`, under `section`.
+
+        Parameters
+        ----------
+        default: bool
+            If True, do not restore inner layout.
+        """
         get_func = CONF.get_default if default else CONF.get
-        window_size = get_func(section, prefix+'size')
-        prefs_dialog_size = get_func(section, prefix+'prefs_dialog_size')
+        window_size = get_func(section, prefix + 'size')
+        prefs_dialog_size = get_func(section, prefix + 'prefs_dialog_size')
         if default:
             hexstate = None
         else:
-            hexstate = get_func(section, prefix+'state', None)
+            hexstate = get_func(section, prefix + 'state', None)
 
-        pos = get_func(section, prefix+'position')
+        pos = get_func(section, prefix + 'position')
 
         # It's necessary to verify if the window/position value is valid
         # with the current screen. See spyder-ide/spyder#3748.
@@ -1570,16 +1576,19 @@ def load_window_settings(self, prefix, default=False, section='main'):
         current_width = screen_shape.width()
         current_height = screen_shape.height()
         if current_width < width or current_height < height:
-            pos = CONF.get_default(section, prefix+'position')
+            pos = CONF.get_default(section, prefix + 'position')
 
-        is_maximized =  get_func(section, prefix+'is_maximized')
-        is_fullscreen = get_func(section, prefix+'is_fullscreen')
-        return hexstate, window_size, prefs_dialog_size, pos, is_maximized, \
-               is_fullscreen
+        is_maximized = get_func(section, prefix + 'is_maximized')
+        is_fullscreen = get_func(section, prefix + 'is_fullscreen')
+        return (hexstate, window_size, prefs_dialog_size, pos, is_maximized,
+                is_fullscreen)
 
     def get_window_settings(self):
-        """Return current window settings
-        Symetric to the 'set_window_settings' setter"""
+        """
+        Return current window settings.
+
+        Symmetric to the 'set_window_settings' setter.
+        """
         window_size = (self.window_size.width(), self.window_size.height())
         is_fullscreen = self.isFullScreen()
         if is_fullscreen:
@@ -1595,8 +1604,11 @@ def get_window_settings(self):
 
     def set_window_settings(self, hexstate, window_size, prefs_dialog_size,
                             pos, is_maximized, is_fullscreen):
-        """Set window settings
-        Symetric to the 'get_window_settings' accessor"""
+        """
+        Set window settings.
+
+        Symmetric to the 'get_window_settings' accessor.
+        """
         self.setUpdatesEnabled(False)
         self.window_size = QSize(window_size[0], window_size[1]) # width,height
         self.prefs_dialog_size = QSize(prefs_dialog_size[0],
@@ -1632,26 +1644,31 @@ def set_window_settings(self, hexstate, window_size, prefs_dialog_size,
 
     def save_current_window_settings(self, prefix, section='main',
                                      none_state=False):
-        """Save current window settings with *prefix* in
-        the userconfig-based configuration, under *section*"""
-        win_size = self.window_size
+        """
+        Save current window settings with `prefix` in
+        the userconfig-based configuration, under `section`.
+        """
+        # Use current size and position when saving window settings.
+        # Fixes spyder-ide/spyder#13882
+        win_size = self.size()
+        pos = self.pos()
         prefs_size = self.prefs_dialog_size
 
-        CONF.set(section, prefix+'size', (win_size.width(), win_size.height()))
-        CONF.set(section, prefix+'prefs_dialog_size',
+        CONF.set(section, prefix + 'size',
+                 (win_size.width(), win_size.height()))
+        CONF.set(section, prefix + 'prefs_dialog_size',
                  (prefs_size.width(), prefs_size.height()))
-        CONF.set(section, prefix+'is_maximized', self.isMaximized())
-        CONF.set(section, prefix+'is_fullscreen', self.isFullScreen())
-        pos = self.window_position
-        CONF.set(section, prefix+'position', (pos.x(), pos.y()))
+        CONF.set(section, prefix + 'is_maximized', self.isMaximized())
+        CONF.set(section, prefix + 'is_fullscreen', self.isFullScreen())
+        CONF.set(section, prefix + 'position', (pos.x(), pos.y()))
         self.maximize_dockwidget(restore=True)# Restore non-maximized layout
         if none_state:
             CONF.set(section, prefix + 'state', None)
         else:
             qba = self.saveState()
             CONF.set(section, prefix + 'state', qbytearray_to_str(qba))
-        CONF.set(section, prefix+'statusbar',
-                    not self.statusBar().isHidden())
+        CONF.set(section, prefix + 'statusbar',
+                 not self.statusBar().isHidden())
 
     def tabify_plugins(self, first, second):
         """Tabify plugin dockwigdets"""
@@ -1976,11 +1993,9 @@ def toggle_next_layout(self):
         self.toggle_layout('next')
 
     def toggle_layout(self, direction='next'):
-        """ """
-        get = CONF.get
-        names = get('quick_layouts', 'names')
-        order = get('quick_layouts', 'order')
-        active = get('quick_layouts', 'active')
+        names = CONF.get('quick_layouts', 'names')
+        order = CONF.get('quick_layouts', 'order')
+        active = CONF.get('quick_layouts', 'active')
 
         if len(active) == 0:
             return
@@ -2006,11 +2021,9 @@ def toggle_layout(self, direction='next'):
         self.quick_layout_switch(layout_index[new_index])
 
     def quick_layout_set_menu(self):
-        """ """
-        get = CONF.get
-        names = get('quick_layouts', 'names')
-        order = get('quick_layouts', 'order')
-        active = get('quick_layouts', 'active')
+        names = CONF.get('quick_layouts', 'names')
+        order = CONF.get('quick_layouts', 'order')
+        active = CONF.get('quick_layouts', 'active')
 
         ql_actions = []
 
@@ -2070,11 +2083,9 @@ def reset_window_layout(self):
 
     def quick_layout_save(self):
         """Save layout dialog"""
-        get = CONF.get
-        set_ = CONF.set
-        names = get('quick_layouts', 'names')
-        order = get('quick_layouts', 'order')
-        active = get('quick_layouts', 'active')
+        names = CONF.get('quick_layouts', 'names')
+        order = CONF.get('quick_layouts', 'order')
+        active = CONF.get('quick_layouts', 'active')
 
         dlg = self.dialog_layout_save(self, names)
 
@@ -2082,11 +2093,13 @@ def quick_layout_save(self):
             name = dlg.combo_box.currentText()
 
             if name in names:
-                answer = QMessageBox.warning(self, _("Warning"),
-                                             _("Layout <b>%s</b> will be \
-                                               overwritten. Do you want to \
-                                               continue?") % name,
-                                             QMessageBox.Yes | QMessageBox.No)
+                answer = QMessageBox.warning(
+                    self,
+                    _("Warning"),
+                    _("<b>%s</b> will be overwritten. Do you want to "
+                      "continue?") % name,
+                    QMessageBox.Yes | QMessageBox.No
+                )
                 index = order.index(name)
             else:
                 answer = True
@@ -2106,27 +2119,23 @@ def quick_layout_save(self):
             if answer:
                 self.save_current_window_settings('layout_{}/'.format(index),
                                                   section='quick_layouts')
-                set_('quick_layouts', 'names', names)
-                set_('quick_layouts', 'order', order)
-                set_('quick_layouts', 'active', active)
+                CONF.set('quick_layouts', 'names', names)
+                CONF.set('quick_layouts', 'order', order)
+                CONF.set('quick_layouts', 'active', active)
                 self.quick_layout_set_menu()
 
     def quick_layout_settings(self):
         """Layout settings dialog"""
-        get = CONF.get
-        set_ = CONF.set
-
         section = 'quick_layouts'
-
-        names = get(section, 'names')
-        order = get(section, 'order')
-        active = get(section, 'active')
+        names = CONF.get(section, 'names')
+        order = CONF.get(section, 'order')
+        active = CONF.get(section, 'active')
 
         dlg = self.dialog_layout_settings(self, names, order, active)
         if dlg.exec_():
-            set_(section, 'names', dlg.names)
-            set_(section, 'order', dlg.order)
-            set_(section, 'active', dlg.active)
+            CONF.set(section, 'names', dlg.names)
+            CONF.set(section, 'order', dlg.order)
+            CONF.set(section, 'active', dlg.active)
             self.quick_layout_set_menu()
 
     def quick_layout_switch(self, index):
@@ -2139,7 +2148,7 @@ def quick_layout_switch(self, index):
             (hexstate, window_size, prefs_dialog_size, pos, is_maximized,
              is_fullscreen) = settings
 
-            # The defaults layouts will always be regenerated unless there was
+            # The default layouts will always be regenerated unless there was
             # an overwrite, either by rewriting with same name, or by deleting
             # and then creating a new one
             if hexstate is None:
@@ -2160,9 +2169,6 @@ def quick_layout_switch(self, index):
                                  _("Quick switch layout #%s has not yet "
                                    "been defined.") % str(index))
             return
-            # TODO: is there any real use in calling the previous layout
-            # setting?
-            # self.previous_layout_settings = self.get_window_settings()
         self.set_window_settings(*settings)
         self.current_quick_layout = index
 
diff --git a/spyder/app/tour.py b/spyder/app/tour.py
--- a/spyder/app/tour.py
+++ b/spyder/app/tour.py
@@ -1265,6 +1265,7 @@ def _handle_fullscreen(self):
                     self.spy_window.windowState()
                     & (~ Qt.WindowFullScreen))
         return False
+
     def start_tour(self):
         """ """
         self.spy_window.setUpdatesEnabled(False)


Test patch: