forked from openlp/openlp
Merge branch 'fix-screen-number-misalignment' into 'master'
Fixes associated with Openlp crashing when display screen unplugged Closes #794 See merge request openlp/openlp!331
This commit is contained in:
commit
b4570b9ad0
@ -142,7 +142,6 @@ class Screen(object):
|
||||
|
||||
:param dict screen_dict: The dictionary which we want to apply to the screen
|
||||
"""
|
||||
self.number = int(screen_dict['number']) if 'number' in screen_dict else self.number
|
||||
self.is_display = screen_dict.get('is_display', self.is_display)
|
||||
self.is_primary = screen_dict.get('is_primary', self.is_primary)
|
||||
if 'geometry' in screen_dict:
|
||||
@ -257,13 +256,12 @@ class ScreenList(metaclass=Singleton):
|
||||
screen_settings = self.settings.value('core/screens')
|
||||
if screen_settings:
|
||||
need_new_display_screen = False
|
||||
for number, screen_dict in screen_settings.items():
|
||||
# Sometimes this loads as a string instead of an int
|
||||
number = int(number)
|
||||
for screen_dict in screen_settings.values():
|
||||
# Compare geometry, primary of screen from settings with available screens
|
||||
if self.has_screen(screen_dict):
|
||||
screen_number = self.get_screen_number(screen_dict)
|
||||
if screen_number is not None:
|
||||
# If match was found, we're all happy, update with custom geometry, display info, if available
|
||||
self[number].update(screen_dict)
|
||||
self[screen_number].update(screen_dict)
|
||||
else:
|
||||
# If no match, ignore this screen, also need to find new display screen if the discarded screen was
|
||||
# marked as such.
|
||||
@ -333,17 +331,19 @@ class ScreenList(metaclass=Singleton):
|
||||
if can_save:
|
||||
self.save_screen_settings()
|
||||
|
||||
def has_screen(self, screen_dict):
|
||||
def get_screen_number(self, screen_dict):
|
||||
"""
|
||||
Confirms a screen is known.
|
||||
Tries to match a screen with the passed-in screen_dict attributes
|
||||
If a match is found then the number of the screen is returned.
|
||||
If not then None is returned.
|
||||
|
||||
:param screen_dict: The dict descrebing the screen.
|
||||
:param screen_dict: The dict describing the screen to match.
|
||||
"""
|
||||
for screen in self.screens:
|
||||
if screen.to_dict()['geometry'] == screen_dict['geometry'] \
|
||||
and screen.is_primary == screen_dict['is_primary']:
|
||||
return True
|
||||
return False
|
||||
return screen.number
|
||||
return None
|
||||
|
||||
def update_screens(self):
|
||||
"""
|
||||
|
@ -93,6 +93,146 @@ def test_create_screen_list(mocked_screens, settings):
|
||||
assert screen_list.screens[1].is_primary is False
|
||||
|
||||
|
||||
@patch('openlp.core.display.screens.QtWidgets.QApplication.screens')
|
||||
def test_create_screen_list_with_settings_matching(mocked_screens, settings):
|
||||
"""
|
||||
Create the screen list and match with saved settings
|
||||
"""
|
||||
# GIVEN: Mocked application and saved screen settings
|
||||
mocked_application = MagicMock()
|
||||
settings.setValue('core/screens', {'0': {'number': 0, 'geometry': {'x': 0, 'y': 0, 'width': 1024, 'height': 768},
|
||||
'is_primary': True, 'is_display': False,
|
||||
'custom_geometry': {'x': 50, 'y': 50, 'width': 924, 'height': 668}},
|
||||
'1': {'number': 0, 'geometry': {'x': 1024, 'y': 0, 'width': 1024, 'height': 768},
|
||||
'is_primary': False, 'is_display': True,
|
||||
'custom_geometry': {'x': 50, 'y': 50, 'width': 924, 'height': 568}}})
|
||||
mocked_screen1 = MagicMock(**{'geometry.return_value': QtCore.QRect(0, 0, 1024, 768)})
|
||||
mocked_screen2 = MagicMock(**{'geometry.return_value': QtCore.QRect(1024, 0, 1024, 768)})
|
||||
mocked_application.screens.return_value = [mocked_screen1, mocked_screen2]
|
||||
mocked_application.primaryScreen.return_value = mocked_screen1
|
||||
|
||||
# WHEN: create() is called
|
||||
screen_list = ScreenList.create(mocked_application)
|
||||
|
||||
# THEN: The correct screens have been set up, matching the saved settings
|
||||
assert screen_list.screens[0].number == 0
|
||||
assert screen_list.screens[0].geometry == QtCore.QRect(0, 0, 1024, 768)
|
||||
assert screen_list.screens[0].is_primary is True
|
||||
assert screen_list.screens[0].is_display is False
|
||||
assert screen_list.screens[0].custom_geometry == QtCore.QRect(50, 50, 924, 668)
|
||||
assert screen_list.screens[1].number == 1
|
||||
assert screen_list.screens[1].geometry == QtCore.QRect(1024, 0, 1024, 768)
|
||||
assert screen_list.screens[1].is_primary is False
|
||||
assert screen_list.screens[1].is_display is True
|
||||
assert screen_list.screens[1].custom_geometry == QtCore.QRect(50, 50, 924, 568)
|
||||
|
||||
|
||||
@patch('openlp.core.display.screens.QtWidgets.QApplication.screens')
|
||||
@patch('openlp.core.display.screens.QtWidgets.QMessageBox.warning')
|
||||
def test_create_screen_list_with_screen_unplugged(screen_warning, mocked_screens, settings):
|
||||
"""
|
||||
Create the screen list where saved screens > os screens (ie display unplugged)
|
||||
"""
|
||||
# GIVEN: Mocked application and saved screen settings
|
||||
mocked_application = MagicMock()
|
||||
settings.setValue('core/screens', {'0': {'number': 0,
|
||||
'geometry': {'x': -1024, 'y': 0, 'width': 1024, 'height': 768},
|
||||
'is_primary': False,
|
||||
'is_display': True,
|
||||
'custom_geometry': {'x': 50, 'y': 50, 'width': 924, 'height': 668}},
|
||||
'1': {'number': 0,
|
||||
'geometry': {'x': 0, 'y': 0, 'width': 1024, 'height': 768},
|
||||
'is_primary': True,
|
||||
'is_display': False,
|
||||
'custom_geometry': {'x': 50, 'y': 50, 'width': 924, 'height': 568}}})
|
||||
# set up mocked_screen to match the 2nd screen in the settings
|
||||
mocked_screen1 = MagicMock(**{'geometry.return_value': QtCore.QRect(0, 0, 1024, 768)})
|
||||
mocked_application.screens.return_value = [mocked_screen1]
|
||||
mocked_application.primaryScreen.return_value = mocked_screen1
|
||||
|
||||
# WHEN: create() is called
|
||||
screen_list = ScreenList.create(mocked_application)
|
||||
|
||||
# THEN: The correct screens have been set up
|
||||
assert len(screen_list.screens) == 1
|
||||
assert screen_list.screens[0].number == 0
|
||||
assert screen_list.screens[0].geometry == QtCore.QRect(0, 0, 1024, 768)
|
||||
assert screen_list.screens[0].is_primary is True
|
||||
# find_new_display_screen() sets this screen's is_display to True
|
||||
assert screen_list.screens[0].is_display is True
|
||||
assert screen_list.screens[0].custom_geometry == QtCore.QRect(50, 50, 924, 568)
|
||||
|
||||
|
||||
@patch('openlp.core.display.screens.QtWidgets.QApplication.screens')
|
||||
def test_create_screen_list_with_screen_replugged_1(mocked_screens, settings):
|
||||
"""
|
||||
Create the screen list where saved screens < os screens (ie display plugged in again)
|
||||
with saved screen matching the first screen
|
||||
"""
|
||||
# GIVEN: Mocked application and saved screen settings
|
||||
mocked_application = MagicMock()
|
||||
settings.setValue('core/screens', {'0': {'number': 0,
|
||||
'geometry': {'x': 0, 'y': 0, 'width': 1024, 'height': 768},
|
||||
'is_primary': True,
|
||||
'is_display': True,
|
||||
'custom_geometry': {'x': 50, 'y': 50, 'width': 924, 'height': 668}}})
|
||||
# set up mocked_screen so that mocked_screen1 matches saved screen
|
||||
mocked_screen1 = MagicMock(**{'geometry.return_value': QtCore.QRect(0, 0, 1024, 768)})
|
||||
mocked_screen2 = MagicMock(**{'geometry.return_value': QtCore.QRect(1024, 0, 1024, 768)})
|
||||
mocked_application.screens.return_value = [mocked_screen1, mocked_screen2]
|
||||
mocked_application.primaryScreen.return_value = mocked_screen1
|
||||
|
||||
# WHEN: create() is called
|
||||
screen_list = ScreenList.create(mocked_application)
|
||||
|
||||
# THEN: The correct screens have been set up
|
||||
assert screen_list.screens[0].number == 0
|
||||
assert screen_list.screens[0].geometry == QtCore.QRect(0, 0, 1024, 768)
|
||||
assert screen_list.screens[0].is_primary is True
|
||||
assert screen_list.screens[0].is_display is True
|
||||
assert screen_list.screens[0].custom_geometry == QtCore.QRect(50, 50, 924, 668)
|
||||
assert screen_list.screens[1].number == 1
|
||||
assert screen_list.screens[1].geometry == QtCore.QRect(1024, 0, 1024, 768)
|
||||
assert screen_list.screens[1].is_primary is False
|
||||
assert screen_list.screens[1].is_display is False
|
||||
assert screen_list.screens[1].custom_geometry is None
|
||||
|
||||
|
||||
@patch('openlp.core.display.screens.QtWidgets.QApplication.screens')
|
||||
def test_create_screen_list_with_screen_replugged_2(mocked_screens, settings):
|
||||
"""
|
||||
Create the screen list where saved screens < os screens (ie display plugged in again)
|
||||
with saved screen matching the second screen
|
||||
"""
|
||||
# GIVEN: Mocked application and saved screen settings
|
||||
mocked_application = MagicMock()
|
||||
settings.setValue('core/screens', {'0': {'number': 0,
|
||||
'geometry': {'x': 0, 'y': 0, 'width': 1024, 'height': 768},
|
||||
'is_primary': True,
|
||||
'is_display': True,
|
||||
'custom_geometry': {'x': 50, 'y': 50, 'width': 924, 'height': 668}}})
|
||||
# set up mocked_screen so that mocked_screen2 matches saved screen
|
||||
mocked_screen1 = MagicMock(**{'geometry.return_value': QtCore.QRect(-1024, 0, 1024, 768)})
|
||||
mocked_screen2 = MagicMock(**{'geometry.return_value': QtCore.QRect(0, 0, 1024, 768)})
|
||||
mocked_application.screens.return_value = [mocked_screen1, mocked_screen2]
|
||||
mocked_application.primaryScreen.return_value = mocked_screen2
|
||||
|
||||
# WHEN: create() is called
|
||||
screen_list = ScreenList.create(mocked_application)
|
||||
|
||||
# THEN: The correct screens have been set up
|
||||
assert screen_list.screens[0].number == 0
|
||||
assert screen_list.screens[0].geometry == QtCore.QRect(-1024, 0, 1024, 768)
|
||||
assert screen_list.screens[0].is_primary is False
|
||||
assert screen_list.screens[0].is_display is False
|
||||
assert screen_list.screens[0].custom_geometry is None
|
||||
assert screen_list.screens[1].number == 1
|
||||
assert screen_list.screens[1].geometry == QtCore.QRect(0, 0, 1024, 768)
|
||||
assert screen_list.screens[1].is_primary is True
|
||||
assert screen_list.screens[1].is_display is True
|
||||
assert screen_list.screens[1].custom_geometry == QtCore.QRect(50, 50, 924, 668)
|
||||
|
||||
|
||||
@patch('openlp.core.display.screens.QtWidgets.QApplication.screens')
|
||||
def test_screen_list_on_primary_changed(mocked_screens, settings, registry):
|
||||
"""Test that the screen is correctly updated when a primary screen is changed"""
|
||||
|
Loading…
Reference in New Issue
Block a user