general: only remember window size

Currently, Nautilus is able to save the last window position when it’s
closed. That is broken in certain cases (#197 and multi-monitor setups
in general) and therefore window placement is best left to the window
manager.
This commit is contained in:
Ernestas Kulik 2018-01-10 17:02:16 +02:00
parent 00aeafd304
commit f0df1fc510
12 changed files with 25 additions and 366 deletions

View file

@ -264,11 +264,10 @@
</schema>
<schema path="/org/gnome/nautilus/window-state/" id="org.gnome.nautilus.window-state" gettext-domain="nautilus">
<key type="s" name="geometry">
<default>''</default>
<summary>The geometry string for a navigation window</summary>
<description>A string containing the saved geometry and coordinates string for navigation windows.</description>
<key type="(ii)" name="initial-size">
<default>(890, 550)</default>
<summary>Initial size of the window</summary>
<description>A tuple containing the initial width and height of the application window.</description>
</key>
<key type="b" name="maximized">
<default>false</default>

View file

@ -1,81 +0,0 @@
/* eel-gdk-extensions.c: Graphics routines to augment what's in gdk.
*
* Copyright (C) 1999, 2000 Eazel, Inc.
*
* The Gnome Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* The Gnome Library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with the Gnome Library; see the file COPYING.LIB. If not,
* see <http://www.gnu.org/licenses/>.
*
* Authors: Darin Adler <darin@eazel.com>,
* Pavel Cisler <pavel@eazel.com>,
* Ramiro Estrugo <ramiro@eazel.com>
*/
#include <config.h>
#include "eel-gdk-extensions.h"
#include "eel-glib-extensions.h"
#include "eel-string.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <stdlib.h>
#include <pango/pango.h>
EelGdkGeometryFlags
eel_gdk_parse_geometry (const char *string,
int *x_return,
int *y_return,
guint *width_return,
guint *height_return)
{
int x11_flags;
EelGdkGeometryFlags gdk_flags;
g_return_val_if_fail (string != NULL, EEL_GDK_NO_VALUE);
g_return_val_if_fail (x_return != NULL, EEL_GDK_NO_VALUE);
g_return_val_if_fail (y_return != NULL, EEL_GDK_NO_VALUE);
g_return_val_if_fail (width_return != NULL, EEL_GDK_NO_VALUE);
g_return_val_if_fail (height_return != NULL, EEL_GDK_NO_VALUE);
x11_flags = XParseGeometry (string, x_return, y_return,
width_return, height_return);
gdk_flags = EEL_GDK_NO_VALUE;
if (x11_flags & XValue)
{
gdk_flags |= EEL_GDK_X_VALUE;
}
if (x11_flags & YValue)
{
gdk_flags |= EEL_GDK_Y_VALUE;
}
if (x11_flags & WidthValue)
{
gdk_flags |= EEL_GDK_WIDTH_VALUE;
}
if (x11_flags & HeightValue)
{
gdk_flags |= EEL_GDK_HEIGHT_VALUE;
}
if (x11_flags & XNegative)
{
gdk_flags |= EEL_GDK_X_NEGATIVE;
}
if (x11_flags & YNegative)
{
gdk_flags |= EEL_GDK_Y_NEGATIVE;
}
return gdk_flags;
}

View file

@ -1,48 +0,0 @@
/* eel-gdk-extensions.h: Graphics routines to augment what's in gdk.
Copyright (C) 1999, 2000 Eazel, Inc.
The Gnome Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The Gnome Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the Gnome Library; see the file COPYING.LIB. If not,
see <http://www.gnu.org/licenses/>.
Authors: Darin Adler <darin@eazel.com>,
Ramiro Estrugo <ramiro@eazel.com>
*/
#ifndef EEL_GDK_EXTENSIONS_H
#define EEL_GDK_EXTENSIONS_H
#include <gdk/gdk.h>
/* Bits returned by eel_gdk_parse_geometry */
typedef enum {
EEL_GDK_NO_VALUE = 0x00,
EEL_GDK_X_VALUE = 0x01,
EEL_GDK_Y_VALUE = 0x02,
EEL_GDK_WIDTH_VALUE = 0x04,
EEL_GDK_HEIGHT_VALUE = 0x08,
EEL_GDK_ALL_VALUES = 0x0f,
EEL_GDK_X_NEGATIVE = 0x10,
EEL_GDK_Y_NEGATIVE = 0x20
} EelGdkGeometryFlags;
/* Wrapper for XParseGeometry */
EelGdkGeometryFlags eel_gdk_parse_geometry (const char *string,
int *x_return,
int *y_return,
guint *width_return,
guint *height_return);
#endif /* EEL_GDK_EXTENSIONS_H */

View file

@ -77,198 +77,6 @@ eel_gtk_window_get_geometry_string (GtkWindow *window)
return str;
}
static void
sanity_check_window_position (int *left,
int *top)
{
GdkRectangle geometry;
g_assert (left != NULL);
g_assert (top != NULL);
gdk_monitor_get_geometry (gdk_display_get_monitor (gdk_display_get_default (), 0), &geometry);
/* Make sure the top of the window is on screen, for
* draggability (might not be necessary with all window managers,
* but seems reasonable anyway). Make sure the top of the window
* isn't off the bottom of the screen, or so close to the bottom
* that it might be obscured by the panel.
*/
*top = CLAMP (*top, 0, geometry.height - MINIMUM_ON_SCREEN_HEIGHT);
/* FIXME bugzilla.eazel.com 669:
* If window has negative left coordinate, set_uposition sends it
* somewhere else entirely. Not sure what level contains this bug (XWindows?).
* Hacked around by pinning the left edge to zero, which just means you
* can't set a window to be partly off the left of the screen using
* this routine.
*/
/* Make sure the left edge of the window isn't off the right edge of
* the screen, or so close to the right edge that it might be
* obscured by the panel.
*/
*left = CLAMP (*left, 0, geometry.width - MINIMUM_ON_SCREEN_WIDTH);
}
static void
sanity_check_window_dimensions (guint *width,
guint *height)
{
GdkRectangle geometry;
g_assert (width != NULL);
g_assert (height != NULL);
gdk_monitor_get_geometry (gdk_display_get_monitor (gdk_display_get_default (), 0), &geometry);
/* Pin the size of the window to the screen, so we don't end up in
* a state where the window is so big essential parts of it can't
* be reached (might not be necessary with all window managers,
* but seems reasonable anyway).
*/
*width = MIN (*width, geometry.width);
*height = MIN (*height, geometry.height);
}
/**
* eel_gtk_window_set_initial_geometry:
*
* Sets the position and size of a GtkWindow before the
* GtkWindow is shown. It is an error to call this on a window that
* is already on-screen. Takes into account screen size, and does
* some sanity-checking on the passed-in values.
*
* @window: A non-visible GtkWindow
* @geometry_flags: A EelGdkGeometryFlags value defining which of
* the following parameters have defined values
* @left: pixel coordinate for left of window
* @top: pixel coordinate for top of window
* @width: width of window in pixels
* @height: height of window in pixels
*/
static void
eel_gtk_window_set_initial_geometry (GtkWindow *window,
EelGdkGeometryFlags geometry_flags,
int left,
int top,
guint width,
guint height)
{
GdkScreen *screen;
GdkDisplay *display;
GdkMonitor *monitor;
GdkRectangle geometry;
int real_left, real_top;
int screen_width, screen_height;
g_return_if_fail (GTK_IS_WINDOW (window));
/* Setting the default size doesn't work when the window is already showing.
* Someday we could make this move an already-showing window, but we don't
* need that functionality yet.
*/
g_return_if_fail (!gtk_widget_get_visible (GTK_WIDGET (window)));
if ((geometry_flags & EEL_GDK_X_VALUE) && (geometry_flags & EEL_GDK_Y_VALUE))
{
real_left = left;
real_top = top;
screen = gtk_window_get_screen (window);
display = gdk_screen_get_display (screen);
monitor = gdk_display_get_monitor (display, 0);
gdk_monitor_get_geometry (monitor, &geometry);
screen_width = geometry.width;
screen_height = geometry.height;
/* This is sub-optimal. GDK doesn't allow us to set win_gravity
* to South/East types, which should be done if using negative
* positions (so that the right or bottom edge of the window
* appears at the specified position, not the left or top).
* However it does seem to be consistent with other GNOME apps.
*/
if (geometry_flags & EEL_GDK_X_NEGATIVE)
{
real_left = screen_width - real_left;
}
if (geometry_flags & EEL_GDK_Y_NEGATIVE)
{
real_top = screen_height - real_top;
}
sanity_check_window_position (&real_left, &real_top);
gtk_window_move (window, real_left, real_top);
}
if ((geometry_flags & EEL_GDK_WIDTH_VALUE) && (geometry_flags & EEL_GDK_HEIGHT_VALUE))
{
sanity_check_window_dimensions (&width, &height);
gtk_window_set_default_size (GTK_WINDOW (window), (int) width, (int) height);
}
}
/**
* eel_gtk_window_set_initial_geometry_from_string:
*
* Sets the position and size of a GtkWindow before the
* GtkWindow is shown. The geometry is passed in as a string.
* It is an error to call this on a window that
* is already on-screen. Takes into account screen size, and does
* some sanity-checking on the passed-in values.
*
* @window: A non-visible GtkWindow
* @geometry_string: A string suitable for use with eel_gdk_parse_geometry
* @minimum_width: If the width from the string is smaller than this,
* use this for the width.
* @minimum_height: If the height from the string is smaller than this,
* use this for the height.
* @ignore_position: If true position data from string will be ignored.
*/
void
eel_gtk_window_set_initial_geometry_from_string (GtkWindow *window,
const char *geometry_string,
guint minimum_width,
guint minimum_height,
gboolean ignore_position)
{
int left, top;
guint width, height;
EelGdkGeometryFlags geometry_flags;
g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (geometry_string != NULL);
/* Setting the default size doesn't work when the window is already showing.
* Someday we could make this move an already-showing window, but we don't
* need that functionality yet.
*/
g_return_if_fail (!gtk_widget_get_visible (GTK_WIDGET (window)));
geometry_flags = eel_gdk_parse_geometry (geometry_string, &left, &top, &width, &height);
/* Make sure the window isn't smaller than makes sense for this window.
* Other sanity checks are performed in set_initial_geometry.
*/
if (geometry_flags & EEL_GDK_WIDTH_VALUE)
{
width = MAX (width, minimum_width);
}
if (geometry_flags & EEL_GDK_HEIGHT_VALUE)
{
height = MAX (height, minimum_height);
}
/* Ignore saved window position if requested. */
if (ignore_position)
{
geometry_flags &= ~(EEL_GDK_X_VALUE | EEL_GDK_Y_VALUE);
}
eel_gtk_window_set_initial_geometry (window, geometry_flags, left, top, width, height);
}
GtkMenuItem *
eel_gtk_menu_append_separator (GtkMenu *menu)
{

View file

@ -28,16 +28,6 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
#include <eel/eel-gdk-extensions.h>
/* GtkWindow */
void eel_gtk_window_set_initial_geometry_from_string (GtkWindow *window,
const char *geometry_string,
guint minimum_width,
guint minimum_height,
gboolean ignore_position);
char * eel_gtk_window_get_geometry_string (GtkWindow *window);
/* GtkMenu and GtkMenuItem */
GtkMenuItem * eel_gtk_menu_append_separator (GtkMenu *menu);

View file

@ -24,7 +24,6 @@
#define EEL_H
#include <eel/eel-art-extensions.h>
#include <eel/eel-gdk-extensions.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-graphic-effects.h>
#include <eel/eel-gtk-extensions.h>

View file

@ -7,8 +7,6 @@ libeel_2_sources = [
'eel-canvas.c',
'eel-debug.h',
'eel-debug.c',
'eel-gdk-extensions.h',
'eel-gdk-extensions.c',
'eel-glib-extensions.h',
'eel-glib-extensions.c',
'eel-graphic-effects.h',

View file

@ -242,9 +242,11 @@ nautilus_application_create_window (NautilusApplication *self,
{
NautilusApplicationPrivate *priv;
NautilusWindow *window;
char *geometry_string;
gboolean maximized;
gint n_windows;
g_autoptr (GVariant) default_size = NULL;
gint default_width = 0;
gint default_height = 0;
g_return_val_if_fail (NAUTILUS_IS_APPLICATION (self), NULL);
nautilus_profile_start (NULL);
@ -263,24 +265,14 @@ nautilus_application_create_window (NautilusApplication *self,
{
gtk_window_unmaximize (GTK_WINDOW (window));
}
default_size = g_settings_get_value (nautilus_window_state,
NAUTILUS_WINDOW_STATE_INITIAL_SIZE);
geometry_string = g_settings_get_string
(nautilus_window_state, NAUTILUS_WINDOW_STATE_GEOMETRY);
if (geometry_string != NULL &&
geometry_string[0] != 0)
{
/* Ignore saved window position if another window is already showing.
* That way the two windows wont appear at the exact same
* location on the screen.
*/
eel_gtk_window_set_initial_geometry_from_string
(GTK_WINDOW (window),
geometry_string,
NAUTILUS_WINDOW_MIN_WIDTH,
NAUTILUS_WINDOW_MIN_HEIGHT,
n_windows > 0);
}
g_free (geometry_string);
g_variant_get (default_size, "(ii)", &default_width, &default_height);
gtk_window_set_default_size (GTK_WINDOW (window),
MAX (NAUTILUS_WINDOW_MIN_WIDTH, default_width),
MAX (NAUTILUS_WINDOW_MIN_HEIGHT, default_height));
DEBUG ("Creating a new navigation window");
nautilus_profile_end (NULL);

View file

@ -28,7 +28,6 @@
#include "nautilus-global-preferences.h"
#include "nautilus-canvas-private.h"
#include <eel/eel-art-extensions.h>
#include <eel/eel-gdk-extensions.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-graphic-effects.h>
#include <eel/eel-string.h>

View file

@ -65,7 +65,7 @@ typedef enum
/* Which views should be displayed for new windows */
#define NAUTILUS_WINDOW_STATE_START_WITH_SIDEBAR "start-with-sidebar"
#define NAUTILUS_WINDOW_STATE_GEOMETRY "geometry"
#define NAUTILUS_WINDOW_STATE_INITIAL_SIZE "initial-size"
#define NAUTILUS_WINDOW_STATE_MAXIMIZED "maximized"
#define NAUTILUS_WINDOW_STATE_SIDEBAR_WIDTH "sidebar-width"

View file

@ -36,7 +36,6 @@
#include <string.h>
#include <eel/eel-vfs-extensions.h>
#include <eel/eel-gdk-extensions.h>
#include <eel/eel-glib-extensions.h>
#include <eel/eel-string.h>
#include <gdk/gdk.h>

View file

@ -2505,24 +2505,28 @@ nautilus_window_finalize (GObject *object)
static void
nautilus_window_save_geometry (NautilusWindow *window)
{
char *geometry_string;
gboolean is_maximized;
g_assert (NAUTILUS_IS_WINDOW (window));
if (gtk_widget_get_window (GTK_WIDGET (window)))
{
geometry_string = eel_gtk_window_get_geometry_string (GTK_WINDOW (window));
gint width;
gint height;
GVariant *initial_size;
gtk_window_get_size (GTK_WINDOW (window), &width, &height);
initial_size = g_variant_new_parsed ("(%i, %i)", width, height);
is_maximized = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (window)))
& GDK_WINDOW_STATE_MAXIMIZED;
if (!is_maximized)
{
g_settings_set_string
(nautilus_window_state, NAUTILUS_WINDOW_STATE_GEOMETRY,
geometry_string);
g_settings_set_value (nautilus_window_state,
NAUTILUS_WINDOW_STATE_INITIAL_SIZE,
initial_size);
}
g_free (geometry_string);
g_settings_set_boolean
(nautilus_window_state, NAUTILUS_WINDOW_STATE_MAXIMIZED,