diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index c7a2645893..e557144c50 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -295,6 +295,7 @@ set( COMMON_SRCS
     convert_basic_shapes_to_polygon.cpp
     dialog_shim.cpp
     displlst.cpp
+    dpi_scaling.cpp
     draw_graphic_text.cpp
     dsnlexer.cpp
     eagle_parser.cpp
diff --git a/common/dialogs/panel_common_settings.cpp b/common/dialogs/panel_common_settings.cpp
index 42a988a2ef..db51bf4310 100644
--- a/common/dialogs/panel_common_settings.cpp
+++ b/common/dialogs/panel_common_settings.cpp
@@ -21,20 +21,50 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
-#include <pgm_base.h>
-#include <dialog_shim.h>
-#include <kiface_i.h>
-#include <bitmap_types.h>
-#include <bitmaps.h>
-#include <wx/graphics.h>
 #include "panel_common_settings.h"
 
-PANEL_COMMON_SETTINGS::PANEL_COMMON_SETTINGS( DIALOG_SHIM* aDialog, wxWindow* aParent ) :
-        PANEL_COMMON_SETTINGS_BASE( aParent ),
-        m_dialog( aDialog ),
-        m_last_scale( -1 )
+#include <bitmap_types.h>
+#include <bitmaps.h>
+#include <dialog_shim.h>
+#include <dpi_scaling.h>
+#include <kiface_i.h>
+#include <pgm_base.h>
+
+#include <wx/graphics.h>
+
+
+static constexpr int dpi_scaling_precision = 1;
+static constexpr double dpi_scaling_increment = 0.5;
+
+
+PANEL_COMMON_SETTINGS::PANEL_COMMON_SETTINGS( DIALOG_SHIM* aDialog, wxWindow* aParent )
+        : PANEL_COMMON_SETTINGS_BASE( aParent ),
+          m_dialog( aDialog ),
+          m_last_scale( -1 )
 {
-    m_scaleSlider->SetStep( 25 );
+    m_canvasScaleCtrl->SetRange(
+            DPI_SCALING::GetMinScaleFactor(), DPI_SCALING::GetMaxScaleFactor() );
+    m_canvasScaleCtrl->SetDigits( dpi_scaling_precision );
+    m_canvasScaleCtrl->SetIncrement( dpi_scaling_increment );
+    m_canvasScaleCtrl->SetValue( DPI_SCALING::GetDefaultScaleFactor() );
+
+    m_canvasScaleCtrl->SetToolTip(
+            _( "Set the scale for the canvas."
+               "\n\n"
+               "On high-DPI displays on some platforms, KiCad cannot determine the "
+               "scaling factor. In this case you may need to set this to a value to "
+               "match your system's DPI scaling. 2.0 is a common value. "
+               "\n\n"
+               "If this does not match the system DPI scaling, the canvas will "
+               "not match the window size and cursor position." ) );
+
+    m_canvasScaleAuto->SetToolTip(
+            _( "Use an automatic value for the canvas scale."
+               "\n\n"
+               "On some platforms, the automatic value is incorrect and should be "
+               "set manually." ) );
+
+    m_iconScaleSlider->SetStep( 25 );
 
     m_textEditorBtn->SetBitmap( KiBitmap( folder_xpm ) );
     m_pdfViewerBtn->SetBitmap( KiBitmap( folder_xpm ) );
@@ -63,18 +93,24 @@ bool PANEL_COMMON_SETTINGS::TransferDataToWindow()
     commonSettings->Read( CAIRO_ANTIALIASING_MODE_KEY, &antialiasingMode, 0 );
     m_antialiasingFallback->SetSelection( antialiasingMode );
 
-    int scale_fourths;
-    commonSettings->Read( ICON_SCALE_KEY, &scale_fourths );
+    int icon_scale_fourths;
+    commonSettings->Read( ICON_SCALE_KEY, &icon_scale_fourths );
 
-    if( scale_fourths <= 0 )
+    if( icon_scale_fourths <= 0 )
     {
-        m_scaleAuto->SetValue( true );
-        m_scaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
+        m_iconScaleAuto->SetValue( true );
+        m_iconScaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
     }
     else
     {
-        m_scaleAuto->SetValue( false );
-        m_scaleSlider->SetValue( scale_fourths * 25 );
+        m_iconScaleAuto->SetValue( false );
+        m_iconScaleSlider->SetValue( icon_scale_fourths * 25 );
+    }
+
+    {
+        const DPI_SCALING dpi( commonSettings, this );
+        m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
+        m_canvasScaleAuto->SetValue( dpi.GetCanvasIsAutoScaled() );
     }
 
     bool option;
@@ -111,9 +147,14 @@ bool PANEL_COMMON_SETTINGS::TransferDataFromWindow()
 
     commonSettings->Write( CAIRO_ANTIALIASING_MODE_KEY, m_antialiasingFallback->GetSelection() );
 
-    const int scale_fourths = m_scaleAuto->GetValue() ? -1 : m_scaleSlider->GetValue() / 25;
+    const int scale_fourths = m_iconScaleAuto->GetValue() ? -1 : m_iconScaleSlider->GetValue() / 25;
     commonSettings->Write( ICON_SCALE_KEY, scale_fourths );
 
+    {
+        DPI_SCALING dpi( commonSettings, this );
+        dpi.SetDpiConfig( m_canvasScaleAuto->GetValue(), m_canvasScaleCtrl->GetValue() );
+    }
+
     commonSettings->Write( USE_ICONS_IN_MENUS_KEY, m_checkBoxIconsInMenus->GetValue() );
     commonSettings->Write( ENBL_ZOOM_NO_CENTER_KEY, !m_ZoomCenterOpt->GetValue() );
     commonSettings->Write( ENBL_MOUSEWHEEL_PAN_KEY, m_MousewheelPANOpt->GetValue() );
@@ -131,21 +172,42 @@ bool PANEL_COMMON_SETTINGS::TransferDataFromWindow()
 
 void PANEL_COMMON_SETTINGS::OnScaleSlider( wxScrollEvent& aEvent )
 {
-    m_scaleAuto->SetValue( false );
+    m_iconScaleAuto->SetValue( false );
 }
 
 
-void PANEL_COMMON_SETTINGS::OnScaleAuto( wxCommandEvent& aEvent )
+void PANEL_COMMON_SETTINGS::OnIconScaleAuto( wxCommandEvent& aEvent )
 {
-    if( m_scaleAuto->GetValue() )
+    if( m_iconScaleAuto->GetValue() )
     {
-        m_last_scale = m_scaleSlider->GetValue();
-        m_scaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
+        m_last_scale = m_iconScaleAuto->GetValue();
+        m_iconScaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
     }
     else
     {
         if( m_last_scale >= 0 )
-            m_scaleSlider->SetValue( m_last_scale );
+            m_iconScaleSlider->SetValue( m_last_scale );
+    }
+}
+
+
+void PANEL_COMMON_SETTINGS::OnCanvasScaleChange( wxCommandEvent& aEvent )
+{
+    m_canvasScaleAuto->SetValue( false );
+}
+
+
+void PANEL_COMMON_SETTINGS::OnCanvasScaleAuto( wxCommandEvent& aEvent )
+{
+    const bool automatic = m_canvasScaleAuto->GetValue();
+
+    if( automatic )
+    {
+        // set the scale to the auto value, without consulting the config
+        DPI_SCALING dpi( nullptr, this );
+
+        // update the field (no events sent)
+        m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
     }
 }
 
diff --git a/common/dialogs/panel_common_settings.h b/common/dialogs/panel_common_settings.h
index 40dbd37f95..0a96f48ad0 100644
--- a/common/dialogs/panel_common_settings.h
+++ b/common/dialogs/panel_common_settings.h
@@ -40,10 +40,20 @@ protected:
     bool TransferDataToWindow() override;
 
     void OnScaleSlider( wxScrollEvent& aEvent ) override;
-    void OnScaleAuto( wxCommandEvent& aEvent ) override;
+    void OnIconScaleAuto( wxCommandEvent& aEvent ) override;
     void OnTextEditorClick( wxCommandEvent& event ) override;
     void OnPDFViewerClick( wxCommandEvent& event ) override;
-	void onUpdateUIPdfPath( wxUpdateUIEvent& event ) override;
+    void onUpdateUIPdfPath( wxUpdateUIEvent& event ) override;
+
+    /**
+     * Event fired when the canvas scale field is modified
+     */
+    void OnCanvasScaleChange( wxCommandEvent& aEvent ) override;
+
+    /**
+     * Event fired when the canvas auto-scale option is changed
+     */
+    void OnCanvasScaleAuto( wxCommandEvent& aEvent ) override;
 
     DIALOG_SHIM*  m_dialog;
 
diff --git a/common/dialogs/panel_common_settings_base.cpp b/common/dialogs/panel_common_settings_base.cpp
index ee2053f68d..9731b83a41 100644
--- a/common/dialogs/panel_common_settings_base.cpp
+++ b/common/dialogs/panel_common_settings_base.cpp
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jan  5 2019)
+// C++ code generated with wxFormBuilder (version Nov 10 2018)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO *NOT* EDIT THIS FILE!
@@ -136,25 +136,26 @@ PANEL_COMMON_SETTINGS_BASE::PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWind
 
 	m_staticTexticonscale = new wxStaticText( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Icon scale:"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticTexticonscale->Wrap( -1 );
-	fgSizer11->Add( m_staticTexticonscale, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 4 );
+	fgSizer11->Add( m_staticTexticonscale, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 4 );
 
-	wxBoxSizer* bSizer4;
-	bSizer4 = new wxBoxSizer( wxHORIZONTAL );
+	m_iconScaleSlider = new STEPPED_SLIDER( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, 50, 50, 275, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL|wxSL_LABELS );
+	m_iconScaleSlider->SetMinSize( wxSize( 240,-1 ) );
 
-	m_scaleSlider = new STEPPED_SLIDER( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, 50, 50, 275, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL|wxSL_LABELS );
-	m_scaleSlider->SetMinSize( wxSize( 240,-1 ) );
+	fgSizer11->Add( m_iconScaleSlider, 1, wxBOTTOM|wxEXPAND, 4 );
 
-	bSizer4->Add( m_scaleSlider, 1, wxBOTTOM|wxEXPAND, 4 );
+	m_iconScaleAuto = new wxCheckBox( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Automatic"), wxDefaultPosition, wxDefaultSize, 0 );
+	fgSizer11->Add( m_iconScaleAuto, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 25 );
 
-	m_staticTextPerCent = new wxStaticText( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("%"), wxDefaultPosition, wxDefaultSize, 0 );
-	m_staticTextPerCent->Wrap( -1 );
-	bSizer4->Add( m_staticTextPerCent, 0, wxALIGN_CENTER_VERTICAL|wxALL, 2 );
+	m_staticTextCanvasScale = new wxStaticText( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Canvas scale:"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticTextCanvasScale->Wrap( -1 );
+	fgSizer11->Add( m_staticTextCanvasScale, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
 
+	m_canvasScaleCtrl = new wxSpinCtrlDouble( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 0, 1 );
+	m_canvasScaleCtrl->SetDigits( 0 );
+	fgSizer11->Add( m_canvasScaleCtrl, 0, wxALL|wxEXPAND, 5 );
 
-	fgSizer11->Add( bSizer4, 1, wxEXPAND, 5 );
-
-	m_scaleAuto = new wxCheckBox( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Automatic"), wxDefaultPosition, wxDefaultSize, 0 );
-	fgSizer11->Add( m_scaleAuto, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 25 );
+	m_canvasScaleAuto = new wxCheckBox( sbSizerIconsOpts->GetStaticBox(), wxID_ANY, _("Automatic"), wxDefaultPosition, wxDefaultSize, 0 );
+	fgSizer11->Add( m_canvasScaleAuto, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 25 );
 
 
 	fgSizer11->Add( 0, 0, 0, wxEXPAND, 5 );
@@ -202,16 +203,18 @@ PANEL_COMMON_SETTINGS_BASE::PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWind
 	m_PDFViewerPath->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_COMMON_SETTINGS_BASE::onUpdateUIPdfPath ), NULL, this );
 	m_pdfViewerBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnPDFViewerClick ), NULL, this );
 	m_pdfViewerBtn->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_COMMON_SETTINGS_BASE::onUpdateUIPdfPath ), NULL, this );
-	m_scaleSlider->Connect( wxEVT_SCROLL_TOP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Connect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Connect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Connect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Connect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Connect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Connect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Connect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleAuto->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleAuto ), NULL, this );
+	m_iconScaleSlider->Connect( wxEVT_SCROLL_TOP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Connect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Connect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Connect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Connect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Connect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Connect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Connect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleAuto->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnIconScaleAuto ), NULL, this );
+	m_canvasScaleCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnCanvasScaleChange ), NULL, this );
+	m_canvasScaleAuto->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnCanvasScaleAuto ), NULL, this );
 }
 
 PANEL_COMMON_SETTINGS_BASE::~PANEL_COMMON_SETTINGS_BASE()
@@ -221,15 +224,17 @@ PANEL_COMMON_SETTINGS_BASE::~PANEL_COMMON_SETTINGS_BASE()
 	m_PDFViewerPath->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_COMMON_SETTINGS_BASE::onUpdateUIPdfPath ), NULL, this );
 	m_pdfViewerBtn->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnPDFViewerClick ), NULL, this );
 	m_pdfViewerBtn->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_COMMON_SETTINGS_BASE::onUpdateUIPdfPath ), NULL, this );
-	m_scaleSlider->Disconnect( wxEVT_SCROLL_TOP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Disconnect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Disconnect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Disconnect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Disconnect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Disconnect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Disconnect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleSlider->Disconnect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
-	m_scaleAuto->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleAuto ), NULL, this );
+	m_iconScaleSlider->Disconnect( wxEVT_SCROLL_TOP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Disconnect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Disconnect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Disconnect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Disconnect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Disconnect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Disconnect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleSlider->Disconnect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( PANEL_COMMON_SETTINGS_BASE::OnScaleSlider ), NULL, this );
+	m_iconScaleAuto->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnIconScaleAuto ), NULL, this );
+	m_canvasScaleCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnCanvasScaleChange ), NULL, this );
+	m_canvasScaleAuto->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnCanvasScaleAuto ), NULL, this );
 
 }
diff --git a/common/dialogs/panel_common_settings_base.fbp b/common/dialogs/panel_common_settings_base.fbp
index 5ffa9864bb..8e246ec5e5 100644
--- a/common/dialogs/panel_common_settings_base.fbp
+++ b/common/dialogs/panel_common_settings_base.fbp
@@ -1219,7 +1219,7 @@
                                         <property name="vgap">0</property>
                                         <object class="sizeritem" expanded="0">
                                             <property name="border">4</property>
-                                            <property name="flag">wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
+                                            <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
                                             <property name="proportion">0</property>
                                             <object class="wxStaticText" expanded="0">
                                                 <property name="BottomDockable">1</property>
@@ -1278,142 +1278,70 @@
                                                 <property name="wrap">-1</property>
                                             </object>
                                         </object>
-                                        <object class="sizeritem" expanded="1">
-                                            <property name="border">5</property>
-                                            <property name="flag">wxEXPAND</property>
+                                        <object class="sizeritem" expanded="0">
+                                            <property name="border">4</property>
+                                            <property name="flag">wxBOTTOM|wxEXPAND</property>
                                             <property name="proportion">1</property>
-                                            <object class="wxBoxSizer" expanded="1">
-                                                <property name="minimum_size"></property>
-                                                <property name="name">bSizer4</property>
-                                                <property name="orient">wxHORIZONTAL</property>
-                                                <property name="permission">none</property>
-                                                <object class="sizeritem" expanded="0">
-                                                    <property name="border">4</property>
-                                                    <property name="flag">wxBOTTOM|wxEXPAND</property>
-                                                    <property name="proportion">1</property>
-                                                    <object class="wxSlider" expanded="0">
-                                                        <property name="BottomDockable">1</property>
-                                                        <property name="LeftDockable">1</property>
-                                                        <property name="RightDockable">1</property>
-                                                        <property name="TopDockable">1</property>
-                                                        <property name="aui_layer"></property>
-                                                        <property name="aui_name"></property>
-                                                        <property name="aui_position"></property>
-                                                        <property name="aui_row"></property>
-                                                        <property name="best_size"></property>
-                                                        <property name="bg"></property>
-                                                        <property name="caption"></property>
-                                                        <property name="caption_visible">1</property>
-                                                        <property name="center_pane">0</property>
-                                                        <property name="close_button">1</property>
-                                                        <property name="context_help"></property>
-                                                        <property name="context_menu">1</property>
-                                                        <property name="default_pane">0</property>
-                                                        <property name="dock">Dock</property>
-                                                        <property name="dock_fixed">0</property>
-                                                        <property name="docking">Left</property>
-                                                        <property name="enabled">1</property>
-                                                        <property name="fg"></property>
-                                                        <property name="floatable">1</property>
-                                                        <property name="font"></property>
-                                                        <property name="gripper">0</property>
-                                                        <property name="hidden">0</property>
-                                                        <property name="id">wxID_ANY</property>
-                                                        <property name="maxValue">275</property>
-                                                        <property name="max_size"></property>
-                                                        <property name="maximize_button">0</property>
-                                                        <property name="maximum_size"></property>
-                                                        <property name="minValue">50</property>
-                                                        <property name="min_size"></property>
-                                                        <property name="minimize_button">0</property>
-                                                        <property name="minimum_size">240,-1</property>
-                                                        <property name="moveable">1</property>
-                                                        <property name="name">m_scaleSlider</property>
-                                                        <property name="pane_border">1</property>
-                                                        <property name="pane_position"></property>
-                                                        <property name="pane_size"></property>
-                                                        <property name="permission">protected</property>
-                                                        <property name="pin_button">1</property>
-                                                        <property name="pos"></property>
-                                                        <property name="resize">Resizable</property>
-                                                        <property name="show">1</property>
-                                                        <property name="size"></property>
-                                                        <property name="style">wxSL_HORIZONTAL|wxSL_LABELS</property>
-                                                        <property name="subclass">STEPPED_SLIDER; widgets/stepped_slider.h; Not forward_declare</property>
-                                                        <property name="toolbar_pane">0</property>
-                                                        <property name="tooltip"></property>
-                                                        <property name="validator_data_type"></property>
-                                                        <property name="validator_style">wxFILTER_NONE</property>
-                                                        <property name="validator_type">wxDefaultValidator</property>
-                                                        <property name="validator_variable"></property>
-                                                        <property name="value">50</property>
-                                                        <property name="window_extra_style"></property>
-                                                        <property name="window_name"></property>
-                                                        <property name="window_style"></property>
-                                                        <event name="OnScroll">OnScaleSlider</event>
-                                                    </object>
-                                                </object>
-                                                <object class="sizeritem" expanded="0">
-                                                    <property name="border">2</property>
-                                                    <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
-                                                    <property name="proportion">0</property>
-                                                    <object class="wxStaticText" expanded="0">
-                                                        <property name="BottomDockable">1</property>
-                                                        <property name="LeftDockable">1</property>
-                                                        <property name="RightDockable">1</property>
-                                                        <property name="TopDockable">1</property>
-                                                        <property name="aui_layer"></property>
-                                                        <property name="aui_name"></property>
-                                                        <property name="aui_position"></property>
-                                                        <property name="aui_row"></property>
-                                                        <property name="best_size"></property>
-                                                        <property name="bg"></property>
-                                                        <property name="caption"></property>
-                                                        <property name="caption_visible">1</property>
-                                                        <property name="center_pane">0</property>
-                                                        <property name="close_button">1</property>
-                                                        <property name="context_help"></property>
-                                                        <property name="context_menu">1</property>
-                                                        <property name="default_pane">0</property>
-                                                        <property name="dock">Dock</property>
-                                                        <property name="dock_fixed">0</property>
-                                                        <property name="docking">Left</property>
-                                                        <property name="enabled">1</property>
-                                                        <property name="fg"></property>
-                                                        <property name="floatable">1</property>
-                                                        <property name="font"></property>
-                                                        <property name="gripper">0</property>
-                                                        <property name="hidden">0</property>
-                                                        <property name="id">wxID_ANY</property>
-                                                        <property name="label">%</property>
-                                                        <property name="markup">0</property>
-                                                        <property name="max_size"></property>
-                                                        <property name="maximize_button">0</property>
-                                                        <property name="maximum_size"></property>
-                                                        <property name="min_size"></property>
-                                                        <property name="minimize_button">0</property>
-                                                        <property name="minimum_size"></property>
-                                                        <property name="moveable">1</property>
-                                                        <property name="name">m_staticTextPerCent</property>
-                                                        <property name="pane_border">1</property>
-                                                        <property name="pane_position"></property>
-                                                        <property name="pane_size"></property>
-                                                        <property name="permission">protected</property>
-                                                        <property name="pin_button">1</property>
-                                                        <property name="pos"></property>
-                                                        <property name="resize">Resizable</property>
-                                                        <property name="show">1</property>
-                                                        <property name="size"></property>
-                                                        <property name="style"></property>
-                                                        <property name="subclass">; forward_declare</property>
-                                                        <property name="toolbar_pane">0</property>
-                                                        <property name="tooltip"></property>
-                                                        <property name="window_extra_style"></property>
-                                                        <property name="window_name"></property>
-                                                        <property name="window_style"></property>
-                                                        <property name="wrap">-1</property>
-                                                    </object>
-                                                </object>
+                                            <object class="wxSlider" expanded="0">
+                                                <property name="BottomDockable">1</property>
+                                                <property name="LeftDockable">1</property>
+                                                <property name="RightDockable">1</property>
+                                                <property name="TopDockable">1</property>
+                                                <property name="aui_layer"></property>
+                                                <property name="aui_name"></property>
+                                                <property name="aui_position"></property>
+                                                <property name="aui_row"></property>
+                                                <property name="best_size"></property>
+                                                <property name="bg"></property>
+                                                <property name="caption"></property>
+                                                <property name="caption_visible">1</property>
+                                                <property name="center_pane">0</property>
+                                                <property name="close_button">1</property>
+                                                <property name="context_help"></property>
+                                                <property name="context_menu">1</property>
+                                                <property name="default_pane">0</property>
+                                                <property name="dock">Dock</property>
+                                                <property name="dock_fixed">0</property>
+                                                <property name="docking">Left</property>
+                                                <property name="enabled">1</property>
+                                                <property name="fg"></property>
+                                                <property name="floatable">1</property>
+                                                <property name="font"></property>
+                                                <property name="gripper">0</property>
+                                                <property name="hidden">0</property>
+                                                <property name="id">wxID_ANY</property>
+                                                <property name="maxValue">275</property>
+                                                <property name="max_size"></property>
+                                                <property name="maximize_button">0</property>
+                                                <property name="maximum_size"></property>
+                                                <property name="minValue">50</property>
+                                                <property name="min_size"></property>
+                                                <property name="minimize_button">0</property>
+                                                <property name="minimum_size">240,-1</property>
+                                                <property name="moveable">1</property>
+                                                <property name="name">m_iconScaleSlider</property>
+                                                <property name="pane_border">1</property>
+                                                <property name="pane_position"></property>
+                                                <property name="pane_size"></property>
+                                                <property name="permission">protected</property>
+                                                <property name="pin_button">1</property>
+                                                <property name="pos"></property>
+                                                <property name="resize">Resizable</property>
+                                                <property name="show">1</property>
+                                                <property name="size"></property>
+                                                <property name="style">wxSL_HORIZONTAL|wxSL_LABELS</property>
+                                                <property name="subclass">STEPPED_SLIDER; widgets/stepped_slider.h; Not forward_declare</property>
+                                                <property name="toolbar_pane">0</property>
+                                                <property name="tooltip"></property>
+                                                <property name="validator_data_type"></property>
+                                                <property name="validator_style">wxFILTER_NONE</property>
+                                                <property name="validator_type">wxDefaultValidator</property>
+                                                <property name="validator_variable"></property>
+                                                <property name="value">50</property>
+                                                <property name="window_extra_style"></property>
+                                                <property name="window_name"></property>
+                                                <property name="window_style"></property>
+                                                <event name="OnScroll">OnScaleSlider</event>
                                             </object>
                                         </object>
                                         <object class="sizeritem" expanded="0">
@@ -1457,7 +1385,7 @@
                                                 <property name="minimize_button">0</property>
                                                 <property name="minimum_size"></property>
                                                 <property name="moveable">1</property>
-                                                <property name="name">m_scaleAuto</property>
+                                                <property name="name">m_iconScaleAuto</property>
                                                 <property name="pane_border">1</property>
                                                 <property name="pane_position"></property>
                                                 <property name="pane_size"></property>
@@ -1478,7 +1406,198 @@
                                                 <property name="window_extra_style"></property>
                                                 <property name="window_name"></property>
                                                 <property name="window_style"></property>
-                                                <event name="OnCheckBox">OnScaleAuto</event>
+                                                <event name="OnCheckBox">OnIconScaleAuto</event>
+                                            </object>
+                                        </object>
+                                        <object class="sizeritem" expanded="1">
+                                            <property name="border">5</property>
+                                            <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+                                            <property name="proportion">0</property>
+                                            <object class="wxStaticText" expanded="1">
+                                                <property name="BottomDockable">1</property>
+                                                <property name="LeftDockable">1</property>
+                                                <property name="RightDockable">1</property>
+                                                <property name="TopDockable">1</property>
+                                                <property name="aui_layer"></property>
+                                                <property name="aui_name"></property>
+                                                <property name="aui_position"></property>
+                                                <property name="aui_row"></property>
+                                                <property name="best_size"></property>
+                                                <property name="bg"></property>
+                                                <property name="caption"></property>
+                                                <property name="caption_visible">1</property>
+                                                <property name="center_pane">0</property>
+                                                <property name="close_button">1</property>
+                                                <property name="context_help"></property>
+                                                <property name="context_menu">1</property>
+                                                <property name="default_pane">0</property>
+                                                <property name="dock">Dock</property>
+                                                <property name="dock_fixed">0</property>
+                                                <property name="docking">Left</property>
+                                                <property name="enabled">1</property>
+                                                <property name="fg"></property>
+                                                <property name="floatable">1</property>
+                                                <property name="font"></property>
+                                                <property name="gripper">0</property>
+                                                <property name="hidden">0</property>
+                                                <property name="id">wxID_ANY</property>
+                                                <property name="label">Canvas scale:</property>
+                                                <property name="markup">0</property>
+                                                <property name="max_size"></property>
+                                                <property name="maximize_button">0</property>
+                                                <property name="maximum_size"></property>
+                                                <property name="min_size"></property>
+                                                <property name="minimize_button">0</property>
+                                                <property name="minimum_size"></property>
+                                                <property name="moveable">1</property>
+                                                <property name="name">m_staticTextCanvasScale</property>
+                                                <property name="pane_border">1</property>
+                                                <property name="pane_position"></property>
+                                                <property name="pane_size"></property>
+                                                <property name="permission">protected</property>
+                                                <property name="pin_button">1</property>
+                                                <property name="pos"></property>
+                                                <property name="resize">Resizable</property>
+                                                <property name="show">1</property>
+                                                <property name="size"></property>
+                                                <property name="style"></property>
+                                                <property name="subclass">; forward_declare</property>
+                                                <property name="toolbar_pane">0</property>
+                                                <property name="tooltip"></property>
+                                                <property name="window_extra_style"></property>
+                                                <property name="window_name"></property>
+                                                <property name="window_style"></property>
+                                                <property name="wrap">-1</property>
+                                            </object>
+                                        </object>
+                                        <object class="sizeritem" expanded="1">
+                                            <property name="border">5</property>
+                                            <property name="flag">wxALL|wxEXPAND</property>
+                                            <property name="proportion">0</property>
+                                            <object class="wxSpinCtrlDouble" expanded="1">
+                                                <property name="BottomDockable">1</property>
+                                                <property name="LeftDockable">1</property>
+                                                <property name="RightDockable">1</property>
+                                                <property name="TopDockable">1</property>
+                                                <property name="aui_layer"></property>
+                                                <property name="aui_name"></property>
+                                                <property name="aui_position"></property>
+                                                <property name="aui_row"></property>
+                                                <property name="best_size"></property>
+                                                <property name="bg"></property>
+                                                <property name="caption"></property>
+                                                <property name="caption_visible">1</property>
+                                                <property name="center_pane">0</property>
+                                                <property name="close_button">1</property>
+                                                <property name="context_help"></property>
+                                                <property name="context_menu">1</property>
+                                                <property name="default_pane">0</property>
+                                                <property name="digits">0</property>
+                                                <property name="dock">Dock</property>
+                                                <property name="dock_fixed">0</property>
+                                                <property name="docking">Left</property>
+                                                <property name="enabled">1</property>
+                                                <property name="fg"></property>
+                                                <property name="floatable">1</property>
+                                                <property name="font"></property>
+                                                <property name="gripper">0</property>
+                                                <property name="hidden">0</property>
+                                                <property name="id">wxID_ANY</property>
+                                                <property name="inc">1</property>
+                                                <property name="initial">0</property>
+                                                <property name="max">100</property>
+                                                <property name="max_size"></property>
+                                                <property name="maximize_button">0</property>
+                                                <property name="maximum_size"></property>
+                                                <property name="min">0</property>
+                                                <property name="min_size"></property>
+                                                <property name="minimize_button">0</property>
+                                                <property name="minimum_size"></property>
+                                                <property name="moveable">1</property>
+                                                <property name="name">m_canvasScaleCtrl</property>
+                                                <property name="pane_border">1</property>
+                                                <property name="pane_position"></property>
+                                                <property name="pane_size"></property>
+                                                <property name="permission">protected</property>
+                                                <property name="pin_button">1</property>
+                                                <property name="pos"></property>
+                                                <property name="resize">Resizable</property>
+                                                <property name="show">1</property>
+                                                <property name="size"></property>
+                                                <property name="style">wxSP_ARROW_KEYS</property>
+                                                <property name="subclass">; ; forward_declare</property>
+                                                <property name="toolbar_pane">0</property>
+                                                <property name="tooltip"></property>
+                                                <property name="value"></property>
+                                                <property name="window_extra_style"></property>
+                                                <property name="window_name"></property>
+                                                <property name="window_style"></property>
+                                                <event name="OnSpinCtrlText">OnCanvasScaleChange</event>
+                                            </object>
+                                        </object>
+                                        <object class="sizeritem" expanded="1">
+                                            <property name="border">25</property>
+                                            <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
+                                            <property name="proportion">0</property>
+                                            <object class="wxCheckBox" expanded="1">
+                                                <property name="BottomDockable">1</property>
+                                                <property name="LeftDockable">1</property>
+                                                <property name="RightDockable">1</property>
+                                                <property name="TopDockable">1</property>
+                                                <property name="aui_layer"></property>
+                                                <property name="aui_name"></property>
+                                                <property name="aui_position"></property>
+                                                <property name="aui_row"></property>
+                                                <property name="best_size"></property>
+                                                <property name="bg"></property>
+                                                <property name="caption"></property>
+                                                <property name="caption_visible">1</property>
+                                                <property name="center_pane">0</property>
+                                                <property name="checked">0</property>
+                                                <property name="close_button">1</property>
+                                                <property name="context_help"></property>
+                                                <property name="context_menu">1</property>
+                                                <property name="default_pane">0</property>
+                                                <property name="dock">Dock</property>
+                                                <property name="dock_fixed">0</property>
+                                                <property name="docking">Left</property>
+                                                <property name="enabled">1</property>
+                                                <property name="fg"></property>
+                                                <property name="floatable">1</property>
+                                                <property name="font"></property>
+                                                <property name="gripper">0</property>
+                                                <property name="hidden">0</property>
+                                                <property name="id">wxID_ANY</property>
+                                                <property name="label">Automatic</property>
+                                                <property name="max_size"></property>
+                                                <property name="maximize_button">0</property>
+                                                <property name="maximum_size"></property>
+                                                <property name="min_size"></property>
+                                                <property name="minimize_button">0</property>
+                                                <property name="minimum_size"></property>
+                                                <property name="moveable">1</property>
+                                                <property name="name">m_canvasScaleAuto</property>
+                                                <property name="pane_border">1</property>
+                                                <property name="pane_position"></property>
+                                                <property name="pane_size"></property>
+                                                <property name="permission">protected</property>
+                                                <property name="pin_button">1</property>
+                                                <property name="pos"></property>
+                                                <property name="resize">Resizable</property>
+                                                <property name="show">1</property>
+                                                <property name="size"></property>
+                                                <property name="style"></property>
+                                                <property name="subclass">; forward_declare</property>
+                                                <property name="toolbar_pane">0</property>
+                                                <property name="tooltip"></property>
+                                                <property name="validator_data_type"></property>
+                                                <property name="validator_style">wxFILTER_NONE</property>
+                                                <property name="validator_type">wxDefaultValidator</property>
+                                                <property name="validator_variable"></property>
+                                                <property name="window_extra_style"></property>
+                                                <property name="window_name"></property>
+                                                <property name="window_style"></property>
+                                                <event name="OnCheckBox">OnCanvasScaleAuto</event>
                                             </object>
                                         </object>
                                         <object class="sizeritem" expanded="0">
diff --git a/common/dialogs/panel_common_settings_base.h b/common/dialogs/panel_common_settings_base.h
index a0fc37df5f..6bf69116fc 100644
--- a/common/dialogs/panel_common_settings_base.h
+++ b/common/dialogs/panel_common_settings_base.h
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jan  5 2019)
+// C++ code generated with wxFormBuilder (version Nov 10 2018)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO *NOT* EDIT THIS FILE!
@@ -61,9 +61,11 @@ class PANEL_COMMON_SETTINGS_BASE : public wxPanel
 		wxTextCtrl* m_PDFViewerPath;
 		wxBitmapButton* m_pdfViewerBtn;
 		wxStaticText* m_staticTexticonscale;
-		STEPPED_SLIDER* m_scaleSlider;
-		wxStaticText* m_staticTextPerCent;
-		wxCheckBox* m_scaleAuto;
+		STEPPED_SLIDER* m_iconScaleSlider;
+		wxCheckBox* m_iconScaleAuto;
+		wxStaticText* m_staticTextCanvasScale;
+		wxSpinCtrlDouble* m_canvasScaleCtrl;
+		wxCheckBox* m_canvasScaleAuto;
 		wxCheckBox* m_checkBoxIconsInMenus;
 		wxCheckBox* m_ZoomCenterOpt;
 		wxCheckBox* m_MousewheelPANOpt;
@@ -74,7 +76,9 @@ class PANEL_COMMON_SETTINGS_BASE : public wxPanel
 		virtual void onUpdateUIPdfPath( wxUpdateUIEvent& event ) { event.Skip(); }
 		virtual void OnPDFViewerClick( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnScaleSlider( wxScrollEvent& event ) { event.Skip(); }
-		virtual void OnScaleAuto( wxCommandEvent& event ) { event.Skip(); }
+		virtual void OnIconScaleAuto( wxCommandEvent& event ) { event.Skip(); }
+		virtual void OnCanvasScaleChange( wxCommandEvent& event ) { event.Skip(); }
+		virtual void OnCanvasScaleAuto( wxCommandEvent& event ) { event.Skip(); }
 
 
 	public:
diff --git a/common/dpi_scaling.cpp b/common/dpi_scaling.cpp
new file mode 100644
index 0000000000..bdd27d540b
--- /dev/null
+++ b/common/dpi_scaling.cpp
@@ -0,0 +1,178 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <dpi_scaling.h>
+
+#include <core/optional.h>
+
+#include <env_vars.h>
+#include <pgm_base.h>
+
+#include <wx/config.h>
+#include <wx/log.h>
+
+
+/**
+ * Flag to enable trace for HiDPI scaling factors
+ *
+ * Use "KICAD_TRACE_HIGH_DPI" to enable.
+ *
+ * @ingroup trace_env_vars
+ */
+const wxChar* const traceHiDpi = wxT( "KICAD_TRACE_HIGH_DPI" );
+
+
+/**
+ * Get a user-configured scale factor from KiCad config file
+ *
+ * @return the scale factor, if set
+ */
+static OPT<double> getKiCadConfiguredScale( const wxConfigBase& aConfig )
+{
+    OPT<double> scale;
+    double      canvas_scale = 0.0;
+    aConfig.Read( CANVAS_SCALE_KEY, &canvas_scale, 0.0 );
+
+    if( canvas_scale > 0.0 )
+    {
+        scale = canvas_scale;
+    }
+
+    if( scale )
+    {
+        wxLogTrace( traceHiDpi, "Scale factor (configured): %f", *scale );
+    }
+
+    return scale;
+}
+
+
+/**
+ * Get the toolkit scale factor from a user-set environment variable
+ * (for example GDK_SCALE on GTK).
+ *
+ * @return the scale factor, if set
+ */
+static OPT<double> getEnviromentScale()
+{
+    const wxPortId port_id = wxPlatformInfo::Get().GetPortId();
+    OPT<double>    scale;
+
+    if( port_id == wxPORT_GTK )
+    {
+        // Under GTK, the user can use GDK_SCALE to force the scaling
+        scale = GetEnvVar<double>( "GDK_SCALE" );
+    }
+
+    if( scale )
+    {
+        wxLogTrace( traceHiDpi, "Scale factor (environment): %f", *scale );
+    }
+
+    return scale;
+}
+
+
+DPI_SCALING::DPI_SCALING( wxConfigBase* aConfig, const wxWindow* aWindow )
+        : m_config( aConfig ), m_window( aWindow )
+{
+}
+
+
+double DPI_SCALING::GetScaleFactor() const
+{
+    OPT<double> val;
+
+    if( m_config )
+    {
+        val = getKiCadConfiguredScale( *m_config );
+    }
+
+    if( !val )
+    {
+        val = getEnviromentScale();
+    }
+
+    if( !val && m_window )
+    {
+        // Use the native WX reporting.
+        // On Linux, this will not work until WX 3.2 and GTK >= 3.10
+        // Otherwise it returns 1.0
+        val = m_window->GetContentScaleFactor();
+        wxLogTrace( traceHiDpi, "Scale factor (WX): %f", *val );
+    }
+
+    if( !val )
+    {
+        // Nothing else we can do, give it a default value
+        val = GetDefaultScaleFactor();
+        wxLogTrace( traceHiDpi, "Scale factor (default): %f", *val );
+    }
+
+    return *val;
+}
+
+
+bool DPI_SCALING::GetCanvasIsAutoScaled() const
+{
+    if( m_config == nullptr )
+    {
+        // No configuration given, so has to be automatic scaling
+        return true;
+    }
+
+    const bool automatic = getKiCadConfiguredScale( *m_config ) == boost::none;
+    wxLogTrace( traceHiDpi, "Scale is automatic: %d", automatic );
+    return automatic;
+}
+
+
+void DPI_SCALING::SetDpiConfig( bool aAuto, double aValue )
+{
+    wxCHECK_RET( m_config != nullptr, "Setting DPI config without a config store." );
+
+    const double value = aAuto ? 0.0 : aValue;
+
+    m_config->Write( CANVAS_SCALE_KEY, value );
+}
+
+
+double DPI_SCALING::GetMaxScaleFactor()
+{
+    // displays with higher than 4.0 DPI are not really going to be useful
+    // for KiCad (even an 8k display would be effectively only ~1080p at 4x)
+    return 6.0;
+}
+
+
+double DPI_SCALING::GetMinScaleFactor()
+{
+    // scales under 1.0 don't make sense from a HiDPI perspective
+    return 1.0;
+}
+
+double DPI_SCALING::GetDefaultScaleFactor()
+{
+    // no scaling => 1.0
+    return 1.0;
+}
\ No newline at end of file
diff --git a/common/env_vars.cpp b/common/env_vars.cpp
index ee51087eda..83baa5e909 100644
--- a/common/env_vars.cpp
+++ b/common/env_vars.cpp
@@ -23,6 +23,8 @@
 
 #include <common.h>
 
+#include <wx/utils.h>
+
 using STRING_MAP = std::map<wxString, wxString>;
 
 /*
@@ -102,4 +104,37 @@ wxString LookUpEnvVarHelp( const wxString& aEnvVar )
         initialiseEnvVarHelp( env_var_help_text );
 
     return env_var_help_text[aEnvVar];
+}
+
+
+template<>
+OPT<double> GetEnvVar( const wxString& aEnvVarName )
+{
+    OPT<double> opt_value;
+
+    wxString env;
+    if( wxGetEnv( aEnvVarName, &env ) )
+    {
+        double value;
+        if( env.ToDouble( &value ) )
+        {
+            opt_value = value;
+        }
+    }
+
+    return opt_value;
+}
+
+template<>
+OPT<wxString> GetEnvVar( const wxString& aEnvVarName )
+{
+    OPT<wxString> opt_value;
+
+    wxString env;
+    if( wxGetEnv( aEnvVarName, &env ) )
+    {
+        opt_value = env;
+    }
+
+    return opt_value;
 }
\ No newline at end of file
diff --git a/common/gal/gal_display_options.cpp b/common/gal/gal_display_options.cpp
index 0c9a43a51d..3b4be00757 100644
--- a/common/gal/gal_display_options.cpp
+++ b/common/gal/gal_display_options.cpp
@@ -22,9 +22,11 @@
 */
 
 #include <gal/gal_display_options.h>
+
 #include <wx/config.h>
 
 #include <config_map.h>
+#include <dpi_scaling.h>
 
 using namespace KIGFX;
 
@@ -55,7 +57,8 @@ GAL_DISPLAY_OPTIONS::GAL_DISPLAY_OPTIONS()
       m_gridMinSpacing( 10.0 ),
       m_axesEnabled( false ),
       m_fullscreenCursor( false ),
-      m_forceDisplayCursor( false )
+      m_forceDisplayCursor( false ),
+      m_scaleFactor( DPI_SCALING::GetDefaultScaleFactor() )
 {}
 
 
diff --git a/common/gal/hidpi_gl_canvas.cpp b/common/gal/hidpi_gl_canvas.cpp
index f1404b99c5..fcc0807bf4 100644
--- a/common/gal/hidpi_gl_canvas.cpp
+++ b/common/gal/hidpi_gl_canvas.cpp
@@ -26,16 +26,14 @@
 
 #include <gal/hidpi_gl_canvas.h>
 
+#include <dpi_scaling.h>
 
-HIDPI_GL_CANVAS::HIDPI_GL_CANVAS( wxWindow *parent,
-           wxWindowID id,
-           const int *attribList,
-           const wxPoint& pos,
-           const wxSize& size,
-           long style,
-           const wxString& name,
-           const wxPalette& palette ) :
-    wxGLCanvas( parent, id, attribList, pos, size, style, name, palette )
+
+HIDPI_GL_CANVAS::HIDPI_GL_CANVAS( wxWindow* parent, wxWindowID id, const int* attribList,
+        const wxPoint& pos, const wxSize& size, long style, const wxString& name,
+        const wxPalette& palette )
+        : wxGLCanvas( parent, id, attribList, pos, size, style, name, palette ),
+          m_scale_factor( DPI_SCALING::GetDefaultScaleFactor() )
 {
 #ifdef RETINA_OPENGL_PATCH
     SetViewWantsBestResolution( true );
@@ -47,15 +45,14 @@ wxSize HIDPI_GL_CANVAS::GetNativePixelSize() const
 {
     wxSize size = wxGLCanvas::GetClientSize();
 
-#ifdef RETINA_OPENGL_PATCH
     const float scaleFactor = GetBackingScaleFactor();
     size.x *= scaleFactor;
     size.y *= scaleFactor;
-#endif
 
     return size;
 }
 
+
 float HIDPI_GL_CANVAS::GetBackingScaleFactor() const
 {
 #ifdef RETINA_OPENGL_PATCH
@@ -63,6 +60,20 @@ float HIDPI_GL_CANVAS::GetBackingScaleFactor() const
     // => clean up when it officially has arrived in wxWidgets
     return static_cast< wxGLCanvas* >( const_cast< HIDPI_GL_CANVAS* >( this ))->GetBackingScaleFactor();
 #else
-    return 1.0f;
+
+    // Return the cached value (which originally was set from config or automatically)
+    return m_scale_factor;
 #endif
 }
+
+
+void HIDPI_GL_CANVAS::SetScaleFactor( double aNewScaleFactor )
+{
+    m_scale_factor = aNewScaleFactor;
+}
+
+
+double HIDPI_GL_CANVAS::GetScaleFactor() const
+{
+    return m_scale_factor;
+}
\ No newline at end of file
diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp
index 9c4215e9c4..fc34b4e495 100644
--- a/common/gal/opengl/opengl_gal.cpp
+++ b/common/gal/opengl/opengl_gal.cpp
@@ -336,6 +336,12 @@ bool OPENGL_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
         refresh = true;
     }
 
+    if( options.m_scaleFactor != GetScaleFactor() )
+    {
+        SetScaleFactor( options.m_scaleFactor );
+        refresh = true;
+    }
+
     if( super::updatedGalDisplayOptions( aOptions ) || refresh )
     {
         Refresh();
@@ -1224,7 +1230,8 @@ void OPENGL_GAL::DrawGrid()
     nonCachedManager->EnableDepthTest( false );
 
     // sub-pixel lines all render the same
-    float minorLineWidth = std::fmax( 1.0f, gridLineWidth ) * getWorldPixelSize();
+    float minorLineWidth =
+            std::fmax( 1.0f, gridLineWidth ) * getWorldPixelSize() / GetBackingScaleFactor();
     float majorLineWidth = minorLineWidth * 2.0f;
 
     // Draw the axis and grid
diff --git a/common/legacy_gal/eda_draw_frame.cpp b/common/legacy_gal/eda_draw_frame.cpp
index fa1eec228b..9a32d22d6e 100644
--- a/common/legacy_gal/eda_draw_frame.cpp
+++ b/common/legacy_gal/eda_draw_frame.cpp
@@ -67,6 +67,7 @@
 #include <page_info.h>
 #include <title_block.h>
 #include <advanced_config.h>
+#include <dpi_scaling.h>
 
 /**
  * Definition for enabling and disabling scroll bar setting trace output.  See the
@@ -301,6 +302,11 @@ void EDA_DRAW_FRAME::CommonSettingsChanged()
     settings->Read( CAIRO_ANTIALIASING_MODE_KEY, &tmp, (int) KIGFX::CAIRO_ANTIALIASING_MODE::NONE );
     m_galDisplayOptions.cairo_antialiasing_mode = (KIGFX::CAIRO_ANTIALIASING_MODE) tmp;
 
+    {
+        const DPI_SCALING dpi{ settings, this };
+        m_galDisplayOptions.m_scaleFactor = dpi.GetScaleFactor();
+    }
+
     m_galDisplayOptions.NotifyChanged();
 }
 
@@ -852,6 +858,11 @@ void EDA_DRAW_FRAME::LoadSettings( wxConfigBase* aCfg )
     cmnCfg->Read( CAIRO_ANTIALIASING_MODE_KEY, &temp, (int) KIGFX::CAIRO_ANTIALIASING_MODE::NONE );
     m_galDisplayOptions.cairo_antialiasing_mode = (KIGFX::CAIRO_ANTIALIASING_MODE) temp;
 
+    {
+        const DPI_SCALING dpi{ cmnCfg, this };
+        m_galDisplayOptions.m_scaleFactor = dpi.GetScaleFactor();
+    }
+
     m_galDisplayOptions.NotifyChanged();
 }
 
diff --git a/common/legacy_wx/eda_draw_frame.cpp b/common/legacy_wx/eda_draw_frame.cpp
index 8702c30315..6e73422712 100644
--- a/common/legacy_wx/eda_draw_frame.cpp
+++ b/common/legacy_wx/eda_draw_frame.cpp
@@ -46,6 +46,7 @@
 #include <math/box2.h>
 #include <lockfile.h>
 #include <trace_helpers.h>
+#include <dpi_scaling.h>
 
 #include <wx/clipbrd.h>
 #include <fctsys.h>
@@ -303,6 +304,11 @@ void EDA_DRAW_FRAME::CommonSettingsChanged()
     settings->Read( CAIRO_ANTIALIASING_MODE_KEY, &tmp, (int) KIGFX::CAIRO_ANTIALIASING_MODE::NONE );
     m_galDisplayOptions.cairo_antialiasing_mode = (KIGFX::CAIRO_ANTIALIASING_MODE) tmp;
 
+    {
+        const DPI_SCALING dpi{ settings, this };
+        m_galDisplayOptions.m_scaleFactor = dpi.GetScaleFactor();
+    }
+
     m_galDisplayOptions.NotifyChanged();
 }
 
@@ -871,6 +877,11 @@ void EDA_DRAW_FRAME::LoadSettings( wxConfigBase* aCfg )
     cmnCfg->Read( CAIRO_ANTIALIASING_MODE_KEY, &temp, (int) KIGFX::CAIRO_ANTIALIASING_MODE::NONE );
     m_galDisplayOptions.cairo_antialiasing_mode = (KIGFX::CAIRO_ANTIALIASING_MODE) temp;
 
+    {
+        const DPI_SCALING dpi{ cmnCfg, this };
+        m_galDisplayOptions.m_scaleFactor = dpi.GetScaleFactor();
+    }
+
     m_galDisplayOptions.NotifyChanged();
 }
 
diff --git a/include/dpi_scaling.h b/include/dpi_scaling.h
new file mode 100644
index 0000000000..b81e982817
--- /dev/null
+++ b/include/dpi_scaling.h
@@ -0,0 +1,102 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors.
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef DPI_SCALING__H
+#define DPI_SCALING__H
+
+#include <wx/config.h>
+#include <wx/window.h>
+
+/**
+ * Class to handle configuration and automatic determination of the DPI
+ * scale to use for canvases. This has several sources and the availability of
+ * some of them are platform dependent.
+ */
+class DPI_SCALING
+{
+public:
+    /**
+     * Construct a DPI scale provider.
+     *
+     * @param aConfig the config store to check for a user value (can be nullptr,
+     * in which case on automatically determined values are considered)
+     * @param aWindow a WX window to use for automatic DPI determination
+     * @return the scaling factor (1.0 = no scaling)
+     */
+    DPI_SCALING( wxConfigBase* aConfig, const wxWindow* aWindow );
+
+    /**
+     * Get the DPI scale from all known sources in order:
+     *
+     * * user config, if given
+     * * user's environment variables, if set and according to platform
+     * * WX's internal determination of the DPI scaling (WX > 3.1)
+     */
+    double GetScaleFactor() const;
+
+    /**
+     * Is the current value auto scaled, or is it user-set in the config
+     */
+    bool GetCanvasIsAutoScaled() const;
+
+    /**
+     * Set the common DPI config in a given config object
+     *
+     * The encoding of the automatic/manual nature of the config is handled internally.
+     *
+     * @param aAuto   store a value meaning "no user-set scale"
+     * @param aValue  the value to store (ignored if aAuto set)
+     */
+    void SetDpiConfig( bool aAuto, double aValue );
+
+    /*
+     * Get the maximum scaling factor that should be presented to the user.
+     * This is only advisory, it has no real technical use other than for validation.
+     */
+    static double GetMaxScaleFactor();
+
+    /*
+     * Get the minimum scaling factor that should be presented to the user.
+     * This is only advisory, it has no real technical use other than for validation.
+     */
+    static double GetMinScaleFactor();
+
+    /**
+     * Get the "default" scaling factor to use if not other config is available
+     */
+    static double GetDefaultScaleFactor();
+
+private:
+    /**
+     * The configuration object to use to get/set user setting. nullptr
+     * if only automatic options are wanted
+     */
+    wxConfigBase* m_config;
+
+    /**
+     * The WX window to use for WX's automatic DPI checking
+     */
+    const wxWindow* m_window;
+};
+
+#endif // DPI_SCALING__H
\ No newline at end of file
diff --git a/include/env_vars.h b/include/env_vars.h
index cec25c2e04..d2200a4c2a 100644
--- a/include/env_vars.h
+++ b/include/env_vars.h
@@ -19,15 +19,18 @@
 
 /**
  * @file env_vars.h
- * Functions to provide helpful hints about what environment vars do
+ * Functions related to environment variables, including help functions
  */
 
 #ifndef ENV_VARS_H
 #define ENV_VARS_H
 
 #include <wx/string.h>
+
 #include <vector>
 
+#include <core/optional.h>
+
 using ENV_VAR_LIST = std::vector<wxString>;
 
 /**
@@ -56,4 +59,33 @@ const ENV_VAR_LIST& GetPredefinedEnvVars();
  */
 wxString LookUpEnvVarHelp( const wxString& aEnvVar );
 
+/**
+ * Get an environment variable as a specific type, if set correctly
+ *
+ * @param aEnvVarName the name of the environment variable
+ * @return an OPT containing the value, if set and parseable, otherwise empty.
+ */
+template <typename VAL_TYPE>
+OPT<VAL_TYPE> GetEnvVar( const wxString& aEnvVarName );
+
+/**
+ * Get a string environment variable, if it is set.
+ *
+ * @param aEnvVarName the name of the environment variable
+ * @return an OPT containing the value, if set, otherwise empty.
+ */
+template<>
+OPT<wxString> GetEnvVar( const wxString& aEnvVarName );
+
+/**
+ * Get a double from an environment variable, if set
+ *
+ * @param aEnvVarName the name of the environment variable
+ * @return an OPT containing the value, if set and parseable as a double,
+ * otherwise empty.
+ */
+template <>
+OPT<double> GetEnvVar( const wxString& aEnvVarName );
+
+
 #endif /* ENV_VARS_H */
diff --git a/include/gal/gal_display_options.h b/include/gal/gal_display_options.h
index 0b592d7a32..44bf3c0a7c 100644
--- a/include/gal/gal_display_options.h
+++ b/include/gal/gal_display_options.h
@@ -100,6 +100,9 @@ namespace KIGFX
 
         ///> Force cursor display
         bool m_forceDisplayCursor;
+
+        ///> The pixel scale factor (>1 for hi-DPI scaled displays)
+        double m_scaleFactor;
     };
 
 }
diff --git a/include/gal/hidpi_gl_canvas.h b/include/gal/hidpi_gl_canvas.h
index e8ed4c3f95..ebe3a789a9 100644
--- a/include/gal/hidpi_gl_canvas.h
+++ b/include/gal/hidpi_gl_canvas.h
@@ -53,6 +53,22 @@ public:
 
     virtual wxSize GetNativePixelSize() const;
     virtual float GetBackingScaleFactor() const;
+
+    /**
+     * Set the canvas scale factor, probably for a hi-DPI display.
+     */
+    void SetScaleFactor( double aFactor );
+
+    /**
+     * Get the current scale factor
+     */
+    double GetScaleFactor() const;
+
+private:
+    /**
+     * The current scale factor (e.g. for hi-DPI displays)
+     */
+    double m_scale_factor;
 };
 
 #endif // HIDPI_GL_CANVAS_H
diff --git a/include/pgm_base.h b/include/pgm_base.h
index 05cecd00f5..b03c1e62ec 100644
--- a/include/pgm_base.h
+++ b/include/pgm_base.h
@@ -44,6 +44,7 @@
 
 #define USE_ICONS_IN_MENUS_KEY          wxT( "UseIconsInMenus" )
 #define ICON_SCALE_KEY                  wxT( "IconScale" )
+#define CANVAS_SCALE_KEY                wxT( "CanvasScale" )
 #define AUTOSAVE_INTERVAL_KEY           wxT( "AutoSaveInterval" )
 #define ENBL_ZOOM_NO_CENTER_KEY         wxT( "ZoomNoCenter" )
 #define ENBL_MOUSEWHEEL_PAN_KEY         wxT( "MousewheelPAN" )