Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Add an option to set a custom HiDPI scale factor #4454

Merged
merged 16 commits into from
Jun 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions spyder/app/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,9 @@
# be set before creating the application.
#==============================================================================
from spyder.config.main import CONF
if CONF.get('main', 'high_dpi_scaling'):
high_dpi_scaling = True
else:
high_dpi_scaling = False

if hasattr(Qt, 'AA_EnableHighDpiScaling'):
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling, high_dpi_scaling)
QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling, CONF.get('main', 'high_dpi_scaling'))


#==============================================================================
Expand Down
11 changes: 11 additions & 0 deletions spyder/app/restart.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from spyder.py3compat import to_text_string
from spyder.utils import icon_manager as ima
from spyder.utils.qthelpers import qapplication
from spyder.config.main import CONF


PY2 = sys.version[0] == '2'
Expand Down Expand Up @@ -153,6 +154,16 @@ def launch_error_message(self, error_type, error=None):


def main():
#==========================================================================
# Proper high DPI scaling is available in Qt >= 5.6.0. This attibute must
# be set before creating the application.
#==========================================================================
if CONF.get('main', 'high_dpi_custom_scale_factor'):
factors = str(CONF.get('main', 'high_dpi_custom_scale_factors'))
os.environ['QT_SCREEN_SCALE_FACTORS'] = factors
else:
os.environ['QT_SCREEN_SCALE_FACTORS'] = ''

# Splash screen
# -------------------------------------------------------------------------
# Start Qt Splash to inform the user of the current status
Expand Down
10 changes: 10 additions & 0 deletions spyder/app/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ def main():
# Store variable to be used in self.restart (restart spyder instance)
os.environ['SPYDER_ARGS'] = str(sys.argv[1:])

#==========================================================================
# Proper high DPI scaling is available in Qt >= 5.6.0. This attibute must
# be set before creating the application.
#==========================================================================
if CONF.get('main', 'high_dpi_custom_scale_factor'):
factors = str(CONF.get('main', 'high_dpi_custom_scale_factors'))
os.environ['QT_SCREEN_SCALE_FACTORS'] = factors
else:
os.environ['QT_SCREEN_SCALE_FACTORS'] = ''

if CONF.get('main', 'single_instance') and not options.new_instance \
and not options.reset_config_files and not running_in_mac_app():
# Minimal delay (0.1-0.2 secs) to avoid that several
Expand Down
3 changes: 3 additions & 0 deletions spyder/config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@
'single_instance': True,
'open_files_port': OPEN_FILES_PORT,
'tear_off_menus': False,
'normal_screen_resolution': True,
'high_dpi_scaling': False,
'high_dpi_custom_scale_factor': False,
'high_dpi_custom_scale_factors': '1.5',
'vertical_dockwidget_titlebars': False,
'vertical_tabs': False,
'animated_docks': True,
Expand Down
12 changes: 10 additions & 2 deletions spyder/config/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,20 @@ def get(self, section, option, default=NoDefault):
value = float(value)
elif isinstance(default_value, int):
value = int(value)
else:
if PY2 and is_text_string(default_value):
elif is_text_string(default_value):
if PY2:
try:
value = value.decode('utf-8')
try:
# Some str config values expect to be eval after decoding
new_value = ast.literal_eval(value)
if is_text_string(new_value):
value = new_value
except (SyntaxError, ValueError):
pass
except (UnicodeEncodeError, UnicodeDecodeError):
pass
else:
try:
# lists, tuples, ...
value = ast.literal_eval(value)
Expand Down
77 changes: 71 additions & 6 deletions spyder/plugins/configdialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
from qtpy import API
from qtpy.compat import (getexistingdirectory, getopenfilename, from_qvariant,
to_qvariant)
from qtpy.QtCore import QSize, Qt, Signal, Slot
from qtpy.QtGui import QColor
from qtpy.QtCore import QSize, Qt, Signal, Slot, QRegExp
from qtpy.QtGui import QColor, QRegExpValidator
from qtpy.QtWidgets import (QButtonGroup, QCheckBox, QComboBox, QDialog,
QDialogButtonBox, QDoubleSpinBox, QFontComboBox,
QGridLayout, QGroupBox, QHBoxLayout, QLabel,
Expand Down Expand Up @@ -316,10 +316,14 @@ def load_from_conf(self):
radiobutton.setChecked(self.get_option(option, default))
radiobutton.toggled.connect(lambda _foo, opt=option:
self.has_been_modified(opt))
if radiobutton.restart_required:
self.restart_options[option] = radiobutton.label_text
for lineedit, (option, default) in list(self.lineedits.items()):
lineedit.setText(self.get_option(option, default))
lineedit.textChanged.connect(lambda _foo, opt=option:
self.has_been_modified(opt))
if lineedit.restart_required:
self.restart_options[option] = lineedit.label_text
for spinbox, (option, default) in list(self.spinboxes.items()):
spinbox.setValue(self.get_option(option, default))
spinbox.valueChanged.connect(lambda _foo, opt=option:
Expand Down Expand Up @@ -442,7 +446,8 @@ def show_message(is_checked=False):

def create_radiobutton(self, text, option, default=NoDefault,
tip=None, msg_warning=None, msg_info=None,
msg_if_enabled=False, button_group=None):
msg_if_enabled=False, button_group=None,
restart=False):
radiobutton = QRadioButton(text)
if button_group is None:
if self.default_button_group is None:
Expand All @@ -462,10 +467,13 @@ def show_message(is_checked):
QMessageBox.information(self, self.get_name(),
msg_info, QMessageBox.Ok)
radiobutton.toggled.connect(show_message)
radiobutton.restart_required = restart
radiobutton.label_text = text
return radiobutton

def create_lineedit(self, text, option, default=NoDefault,
tip=None, alignment=Qt.Vertical):
tip=None, alignment=Qt.Vertical, regex=None,
restart=False):
label = QLabel(text)
label.setWordWrap(True)
edit = QLineEdit()
Expand All @@ -475,11 +483,15 @@ def create_lineedit(self, text, option, default=NoDefault,
layout.setContentsMargins(0, 0, 0, 0)
if tip:
edit.setToolTip(tip)
if regex:
edit.setValidator(QRegExpValidator(QRegExp(regex)))
self.lineedits[edit] = (option, default)
widget = QWidget(self)
widget.label = label
widget.textbox = edit
widget.setLayout(layout)
edit.restart_required = restart
edit.label_text = text
return widget

def create_browsedir(self, text, option, default=NoDefault, tip=None):
Expand Down Expand Up @@ -938,6 +950,59 @@ def setup_page(self):
sbar_layout.addLayout(cpu_memory_layout)
sbar_group.setLayout(sbar_layout)

# --- Screen resolution Group (hidpi)
screen_resolution_group = QGroupBox(_("Screen resolution"))
screen_resolution_bg = QButtonGroup(screen_resolution_group)
screen_resolution_label = QLabel(_("Configurations for highdpi screens, "
"See: <a href=\"http://doc.qt.io/qt-5/highdpi.html\">http://doc.qt.io/qt-5/highdpi.html</a><> "
"for more information"))
screen_resolution_label.setWordWrap(True)

normal_radio = self.create_radiobutton(
_("Normal"),
'normal_screen_resolution',
button_group=screen_resolution_bg)
auto_scale_radio = self.create_radiobutton(
_("Enable auto high DPI scaling"),
'high_dpi_scaling',
button_group=screen_resolution_bg,
tip=_("Set this for high DPI displays"),
restart=True)

custom_scaling_radio = self.create_radiobutton(
_("Set a custom high DPI scaling"),
'high_dpi_custom_scale_factor',
button_group=screen_resolution_bg,
tip=_("Set this for high DPI displays when "
"auto scaling does not work"),
restart=True)

custom_scaling_edit = self.create_lineedit("",
'high_dpi_custom_scale_factors',
tip=_("Enter values for different screens "
"separated by semicolons ';', "
"float values are supported"),
alignment=Qt.Horizontal,
regex="[0-9]+(?:\.[0-9]*)(;[0-9]+(?:\.[0-9]*))*",
restart=True)

normal_radio.toggled.connect(custom_scaling_edit.setDisabled)
auto_scale_radio.toggled.connect(custom_scaling_edit.setDisabled)
custom_scaling_radio.toggled.connect(custom_scaling_edit.setEnabled)

# Layout Screen resolution
screen_resolution_layout = QVBoxLayout()
screen_resolution_layout.addWidget(screen_resolution_label)

screen_resolution_inner_layout = QGridLayout()
screen_resolution_inner_layout.addWidget(normal_radio, 0, 0)
screen_resolution_inner_layout.addWidget(auto_scale_radio, 1, 0)
screen_resolution_inner_layout.addWidget(custom_scaling_radio, 2, 0)
screen_resolution_inner_layout.addWidget(custom_scaling_edit, 2, 1)

screen_resolution_layout.addLayout(screen_resolution_inner_layout)
screen_resolution_group.setLayout(screen_resolution_layout)

# --- Theme and fonts
plain_text_font = self.create_fontgroup(
option='font',
Expand All @@ -963,8 +1028,8 @@ def setup_page(self):
fonts_group.setLayout(fonts_layout)

tabs = QTabWidget()
tabs.addTab(self.create_tab(fonts_group, interface_group),
_("Appearance"))
tabs.addTab(self.create_tab(fonts_group, screen_resolution_group,
interface_group), _("Appearance"))
tabs.addTab(self.create_tab(general_group, sbar_group),
_("Advanced Settings"))

Expand Down
4 changes: 3 additions & 1 deletion spyder/widgets/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
QVBoxLayout, QWidget)
from qtpy.QtWebEngineWidgets import (QWebEnginePage, QWebEngineSettings,
QWebEngineView, WEBENGINE)
from qtpy.QtGui import QFontInfo

# Local imports
from spyder.config.base import _, DEV
Expand Down Expand Up @@ -82,14 +83,15 @@ def get_selected_text(self):
return self.selectedText()

def set_font(self, font, fixed_font=None):
font = QFontInfo(font)
settings = self.page().settings()
for fontfamily in (settings.StandardFont, settings.SerifFont,
settings.SansSerifFont, settings.CursiveFont,
settings.FantasyFont):
settings.setFontFamily(fontfamily, font.family())
if fixed_font is not None:
settings.setFontFamily(settings.FixedFont, fixed_font.family())
size = font.pointSize()
size = font.pixelSize()
settings.setFontSize(settings.DefaultFontSize, size)
settings.setFontSize(settings.DefaultFixedFontSize, size)

Expand Down