summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorEduard Braun <eduard.braun2@gmx.de>2018-01-09 20:37:43 +0000
committerEduard Braun <eduard.braun2@gmx.de>2018-01-09 21:32:06 +0000
commit87661ee65e9faccb22adeca6a37de7b065e8a702 (patch)
tree474f2e077578ae8524f1697ad37dd61c7b267863 /src/ui
parentFix profiling build (diff)
parentLimit default window size to monitor dimensions (diff)
downloadinkscape-87661ee65e9faccb22adeca6a37de7b065e8a702.tar.gz
inkscape-87661ee65e9faccb22adeca6a37de7b065e8a702.zip
Fix and improve window size/position handling/restoration
- Fix broken window size/position restoration after gtk3 deprecation fixes in fa8a2ee7e2539b145a87ac9af0d9748effa91631 - Use monitor geometry of the monitor Inkscape will be shown on instead of defaulting to the primary monitor which is often wrong - Let gtk+ / window manager handle window size/position sanitization (confirmed working on Windows and Ubuntu 16.04) and remove custom code which was prone to errors and did not always work as desired - Make default window size "Small" work again (was broken in gtk3) and add a new preference "Default" which uses the native window size (i.e. tries to make just enough room for all controls)
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/CMakeLists.txt2
-rw-r--r--src/ui/dialog/dialog.cpp28
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp20
-rw-r--r--src/ui/interface.cpp54
-rw-r--r--src/ui/monitor.cpp107
-rw-r--r--src/ui/monitor.h51
-rw-r--r--src/ui/uxmanager.cpp28
7 files changed, 192 insertions, 98 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index fecb14a91..b9933bba6 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -5,6 +5,7 @@ set(ui_SRC
dialog-events.cpp
draw-anchor.cpp
interface.cpp
+ monitor.cpp
previewholder.cpp
selected-color.cpp
shape-editor.cpp
@@ -186,6 +187,7 @@ set(ui_SRC
event-debug.h
icon-names.h
interface.h
+ monitor.h
previewable.h
previewfillable.h
previewholder.h
diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp
index 3d949a8c9..f7e9a1bed 100644
--- a/src/ui/dialog/dialog.cpp
+++ b/src/ui/dialog/dialog.cpp
@@ -20,13 +20,10 @@
#include "dialog-manager.h"
#include <gtkmm/dialog.h>
-#if GTKMM_CHECK_VERSION(3,22,0)
-# include <gdkmm/monitor.h>
-#endif
-
#include <gdk/gdkkeysyms.h>
#include "inkscape.h"
+#include "ui/monitor.h"
#include "ui/tools/tool-base.h"
#include "desktop.h"
@@ -166,26 +163,9 @@ void Dialog::read_geometry()
resize(w, h);
}
-#if GTKMM_CHECK_VERSION(3,22,0)
- auto const display = Gdk::Display::get_default();
- auto monitor = display->get_primary_monitor();
-
- // If user hasn't configured a primary monitor, nullptr is returned so try first monitor.
- if (!monitor) {
- std::cerr << "Dialog::read_geometry: no primary monitor configured!" << std::endl;
- monitor = display->get_monitor(0);
- }
-
- Gdk::Rectangle screen_geometry;
- if (monitor) {
- monitor->get_geometry(screen_geometry);
- }
- auto const screen_width = screen_geometry.get_width();
- auto const screen_height = screen_geometry.get_height();
-#else
- auto const screen_width = gdk_screen_width();
- auto const screen_height = gdk_screen_height();
-#endif
+ Gdk::Rectangle monitor_geometry = Inkscape::UI::get_monitor_geometry_primary();
+ auto const screen_width = monitor_geometry.get_width();
+ auto const screen_height = monitor_geometry.get_height();
// If there are stored values for where the dialog should be
// located, then restore the dialog to that position.
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index 0ac12d15c..7b7bd6548 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -684,9 +684,9 @@ void InkscapePreferences::initPageUI()
}
// Windows
- _win_save_geom.init ( _("Save and restore window geometry for each document"), "/options/savewindowgeometry/value", 1, true, 0);
- _win_save_geom_prefs.init ( _("Remember and use last window's geometry"), "/options/savewindowgeometry/value", 2, false, &_win_save_geom);
- _win_save_geom_off.init ( _("Don't save window geometry"), "/options/savewindowgeometry/value", 0, false, &_win_save_geom);
+ _win_save_geom.init ( _("Save and restore window geometry for each document"), "/options/savewindowgeometry/value", PREFS_WINDOW_GEOMETRY_FILE, true, 0);
+ _win_save_geom_prefs.init ( _("Remember and use last window's geometry"), "/options/savewindowgeometry/value", PREFS_WINDOW_GEOMETRY_LAST, false, &_win_save_geom);
+ _win_save_geom_off.init ( _("Don't save window geometry"), "/options/savewindowgeometry/value", PREFS_WINDOW_GEOMETRY_NONE, false, &_win_save_geom);
_win_save_dialog_pos_on.init ( _("Save and restore dialogs status"), "/options/savedialogposition/value", 1, true, 0);
_win_save_dialog_pos_off.init ( _("Don't save dialogs status"), "/options/savedialogposition/value", 0, false, &_win_save_dialog_pos_on);
@@ -707,10 +707,16 @@ void InkscapePreferences::initPageUI()
_win_ontop_agressive.init ( _("Aggressive"), "/options/transientpolicy/value", 2, false, &_win_ontop_none);
{
- Glib::ustring defaultSizeLabels[] = {C_("Window size", "Small"), C_("Window size", "Large"), C_("Window size", "Maximized")};
- int defaultSizeValues[] = {0, 1, 2};
-
- _win_default_size.init( "/options/defaultwindowsize/value", defaultSizeLabels, defaultSizeValues, G_N_ELEMENTS(defaultSizeLabels), 1 );
+ Glib::ustring defaultSizeLabels[] = {C_("Window size", "Default"),
+ C_("Window size", "Small"),
+ C_("Window size", "Large"),
+ C_("Window size", "Maximized")};
+ int defaultSizeValues[] = {PREFS_WINDOW_SIZE_NATURAL,
+ PREFS_WINDOW_SIZE_SMALL,
+ PREFS_WINDOW_SIZE_LARGE,
+ PREFS_WINDOW_SIZE_MAXIMIZED};
+
+ _win_default_size.init( "/options/defaultwindowsize/value", defaultSizeLabels, defaultSizeValues, G_N_ELEMENTS(defaultSizeLabels), PREFS_WINDOW_SIZE_NATURAL);
_page_windows.add_line( false, _("Default window size:"), _win_default_size, "",
_("Set the default window size"), false);
}
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index 826737c2c..7df3502f7 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -30,10 +30,7 @@
#include "file.h"
#include <glibmm/miscutils.h>
-#if GTKMM_CHECK_VERSION(3,22,0)
-# include <gdkmm/monitor.h>
-#endif
-
+#include "enums.h"
#include "inkscape.h"
#include "extension/db.h"
#include "extension/effect.h"
@@ -43,6 +40,7 @@
#include "document.h"
#include "ui/interface.h"
+#include "ui/monitor.h"
#include "desktop.h"
#include "selection-chemistry.h"
#include "svg-view-widget.h"
@@ -136,8 +134,6 @@ static void sp_ui_menu_item_set_name(GtkWidget *data,
Glib::ustring const &name);
static void sp_recent_open(GtkRecentChooser *, gpointer);
-static const int MIN_ONSCREEN_DISTANCE = 50;
-
void
sp_create_window(SPViewWidget *vw, bool editable)
{
@@ -165,9 +161,8 @@ sp_create_window(SPViewWidget *vw, bool editable)
win->signal_focus_in_event().connect(sigc::mem_fun(*desktop_widget, &SPDesktopWidget::onFocusInEvent));
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- gint prefs_geometry =
- (2==prefs->getInt("/options/savewindowgeometry/value", 0));
- if (prefs_geometry) {
+ int window_geometry = prefs->getInt("/options/savewindowgeometry/value", PREFS_WINDOW_GEOMETRY_NONE);
+ if (window_geometry == PREFS_WINDOW_GEOMETRY_LAST) {
gint pw = prefs->getInt("/desktop/geometry/width", -1);
gint ph = prefs->getInt("/desktop/geometry/height", -1);
gint px = prefs->getInt("/desktop/geometry/x", -1);
@@ -175,39 +170,11 @@ sp_create_window(SPViewWidget *vw, bool editable)
gint full = prefs->getBool("/desktop/geometry/fullscreen");
gint maxed = prefs->getBool("/desktop/geometry/maximized");
if (pw>0 && ph>0) {
-#if GTKMM_CHECK_VERSION(3,22,0)
- auto const display = Gdk::Display::get_default();
- auto const monitor = display->get_primary_monitor();
-
- // A Gdk::Rectangle in "application pixel" units
- Gdk::Rectangle screen_geometry;
- monitor->get_geometry(screen_geometry);
- auto const screen_width = screen_geometry.get_width();
- auto const screen_height = screen_geometry.get_height();
-#else
- auto const screen_width = gdk_screen_width();
- auto const screen_height = gdk_screen_height();
-#endif
- gint w = MIN(screen_width, pw);
- gint h = MIN(screen_height, ph);
- gint x = MIN(screen_width - MIN_ONSCREEN_DISTANCE, px);
- gint y = MIN(screen_height - MIN_ONSCREEN_DISTANCE, py);
- if (w>0 && h>0) {
- x = MIN(screen_width - w, x);
- y = MIN(screen_height - h, y);
- desktop->setWindowSize(w, h);
- }
-
- // Only restore xy for the first window so subsequent windows don't overlap exactly
- // with first. (Maybe rule should be only restore xy if it's different from xy of
- // other desktops?)
-
- // Empirically it seems that active_desktop==this desktop only the first time a
- // desktop is created.
- SPDesktop *active_desktop = SP_ACTIVE_DESKTOP;
- if (active_desktop == desktop || active_desktop==NULL) {
- desktop->setWindowPosition(Geom::Point(x, y));
- }
+ Gdk::Rectangle monitor_geometry = Inkscape::UI::get_monitor_geometry_at_point(px, py);
+ pw = std::min(pw, monitor_geometry.get_width());
+ ph = std::min(ph, monitor_geometry.get_height());
+ desktop->setWindowSize(pw, ph);
+ desktop->setWindowPosition(Geom::Point(px, py));
}
if (maxed) {
win->maximize();
@@ -216,8 +183,7 @@ sp_create_window(SPViewWidget *vw, bool editable)
win->fullscreen();
}
}
-
- }
+ }
if ( completeDropTargets == 0 || completeDropTargetsCount == 0 )
{
diff --git a/src/ui/monitor.cpp b/src/ui/monitor.cpp
new file mode 100644
index 000000000..3e0c983fe
--- /dev/null
+++ b/src/ui/monitor.cpp
@@ -0,0 +1,107 @@
+/**
+ * \file
+ * \brief helper functions for retrieving monitor geometry, etc.
+ *//*
+ * Authors:
+ * Eduard Braun <eduard.braun2@gmx.de>
+ *
+ * Copyright 2018 Authors
+ *
+ * This file is part of Inkscape.
+ *
+ * Inkscape is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Inkscape 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Inkscape. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gdkmm/rectangle.h>
+#include <gdkmm/window.h>
+
+#if GTKMM_CHECK_VERSION(3,22,0)
+# include <gdkmm/monitor.h>
+#else
+# include <gdkmm/screen.h>
+#endif
+
+
+namespace Inkscape {
+namespace UI {
+
+/** get monitor geometry of primary monitor */
+Gdk::Rectangle get_monitor_geometry_primary() {
+ Gdk::Rectangle monitor_geometry;
+#if GTKMM_CHECK_VERSION(3,22,0)
+ auto const display = Gdk::Display::get_default();
+ auto const monitor = display->get_primary_monitor();
+
+ // Fallback to monitor number 0 if the user hasn't configured a primary monitor
+ if (!monitor) {
+ monitor = display->get_monitor(0);
+ }
+
+ monitor->get_geometry(monitor_geometry);
+#else
+ auto const default_screen = Gdk::Screen::get_default();
+ auto const monitor_number = default_screen->get_primary_monitor();
+ default_screen->get_monitor_geometry(monitor_number, monitor_geometry);
+#endif
+ return monitor_geometry;
+}
+
+/** get monitor geometry of monitor containing largest part of window */
+Gdk::Rectangle get_monitor_geometry_at_window(const Glib::RefPtr<Gdk::Window>& window) {
+ Gdk::Rectangle monitor_geometry;
+#if GTKMM_CHECK_VERSION(3,22,0)
+ auto const display = Gdk::Display::get_default();
+ auto const monitor = display->get_monitor_at_window(window);
+ monitor->get_geometry(monitor_geometry);
+#else
+ auto const default_screen = Gdk::Screen::get_default();
+ auto const monitor_number = default_screen->get_monitor_at_window(window);
+ default_screen->get_monitor_geometry(monitor_number, monitor_geometry);
+#endif
+ return monitor_geometry;
+}
+
+/** get monitor geometry of monitor at (or closest to) point on combined screen area */
+Gdk::Rectangle get_monitor_geometry_at_point(int x, int y) {
+ Gdk::Rectangle monitor_geometry;
+#if GTKMM_CHECK_VERSION(3,22,0)
+ auto const display = Gdk::Display::get_default();
+ auto const monitor = display->get_monitor_at_point(x ,y);
+ monitor->get_geometry(monitor_geometry);
+#else
+ auto const default_screen = Gdk::Screen::get_default();
+ auto const monitor_number = default_screen->get_monitor_at_point(x, y);
+ default_screen->get_monitor_geometry(monitor_number, monitor_geometry);
+#endif
+ return monitor_geometry;
+}
+
+}
+}
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace .0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99:
diff --git a/src/ui/monitor.h b/src/ui/monitor.h
new file mode 100644
index 000000000..696a8ed73
--- /dev/null
+++ b/src/ui/monitor.h
@@ -0,0 +1,51 @@
+/**
+ * \file
+ * \brief helper functions for retrieving monitor geometry, etc.
+ *//*
+ * Authors:
+ * Eduard Braun <eduard.braun2@gmx.de>
+ *
+ * Copyright 2018 Authors
+ *
+ * This file is part of Inkscape.
+ *
+ * Inkscape is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Inkscape 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Inkscape. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SEEN_MONITOR_H
+#define SEEN_MONITOR_H
+
+#include <gdkmm/rectangle.h>
+#include <gdkmm/window.h>
+
+namespace Inkscape {
+namespace UI {
+ Gdk::Rectangle get_monitor_geometry_primary();
+ Gdk::Rectangle get_monitor_geometry_at_window(const Glib::RefPtr<Gdk::Window>& window);
+ Gdk::Rectangle get_monitor_geometry_at_point(int x, int y);
+}
+}
+
+#endif // SEEN_MONITOR_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace .0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99:
diff --git a/src/ui/uxmanager.cpp b/src/ui/uxmanager.cpp
index f48f40879..3ec38edf9 100644
--- a/src/ui/uxmanager.cpp
+++ b/src/ui/uxmanager.cpp
@@ -17,12 +17,10 @@
#include "uxmanager.h"
#include "desktop.h"
+#include "ui/monitor.h"
#include "util/ege-tags.h"
#include "widgets/toolbox.h"
-#if GTKMM_CHECK_VERSION(3,22,0)
-# include <gdkmm/monitor.h>
-#endif
using std::vector;
@@ -125,27 +123,11 @@ UXManagerImpl::UXManagerImpl() :
tags.addTag(ege::Tag("Icons"));
// Figure out if we're on a widescreen display
-#if GTKMM_CHECK_VERSION(3,22,0)
- auto display = Gdk::Display::get_default();
- auto monitor = display->get_primary_monitor();
-
- // Fallback to monitor number 0 if the user hasn't configured a primary monitor
- if (!monitor) {
- monitor = display->get_monitor(0);
- }
+ Gdk::Rectangle monitor_geometry = Inkscape::UI::get_monitor_geometry_primary();
+ int const width = monitor_geometry.get_width();
+ int const height = monitor_geometry.get_height();
- if(monitor) {
- Gdk::Rectangle monitor_geometry;
- monitor->get_geometry(monitor_geometry);
-
- int const width = monitor_geometry.get_width();
- int const height = monitor_geometry.get_height();
-#else
- Glib::RefPtr<Gdk::Screen> defaultScreen = Gdk::Screen::get_default();
- if (defaultScreen) {
- int width = defaultScreen->get_width();
- int height = defaultScreen->get_height();
-#endif
+ if (width && height) {
gdouble aspect = static_cast<gdouble>(width) / static_cast<gdouble>(height);
if (aspect > 1.65) {
_widescreen = true;