1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 22:17:45 +00:00

WindowServer: Validate that all screens can be reached

If there are any screens that are detached from other screens it would
not be possible to get to them using the mouse pointer. Also make sure
that none of the screens are overlapping.
This commit is contained in:
Tom 2021-06-13 21:09:47 -06:00 committed by Andreas Kling
parent 0547e0329a
commit 34394044b3

View file

@ -96,6 +96,20 @@ int main(int, char**)
wm_config->read_num_entry(group_name, "Width", 1024 / scale),
wm_config->read_num_entry("Screen", "Height", 768 / scale)
};
// Check if the screen would be overlapping with another one
if (WindowServer::Screen::for_each([&](auto& screen) {
if (screen.rect().intersects(virtual_rect)) {
dbgln("Screen {} rect {} overlaps with screen {} rect {}: Ignoring configuration", screen.index(), screen.rect(), screen_index, virtual_rect);
return IterationDecision::Break;
}
return IterationDecision::Continue;
})
== IterationDecision::Break) {
// Ignore the configuration
break;
}
auto* screen = WindowServer::Screen::create(device_path, virtual_rect, scale);
if (!screen) {
dbgln("Screen {} failed to be created", screen_index);
@ -109,6 +123,35 @@ int main(int, char**)
fb_devices_configured.set(device_path);
}
// Check that all screens are contiguous and can be "reached" from the main screen
{
Vector<WindowServer::Screen*, 16> reachable_screens { &WindowServer::Screen::main() };
bool did_reach_another_screen;
do {
did_reach_another_screen = false;
auto* latest_reachable_screen = reachable_screens[reachable_screens.size() - 1];
WindowServer::Screen::for_each([&](auto& screen) {
if (&screen == latest_reachable_screen || reachable_screens.contains_slow(&screen))
return IterationDecision::Continue;
if (screen.rect().is_adjacent(latest_reachable_screen->rect())) {
reachable_screens.append(&screen);
did_reach_another_screen = true;
return IterationDecision::Break;
}
return IterationDecision::Continue;
});
} while (did_reach_another_screen);
if (reachable_screens.size() != WindowServer::Screen::count()) {
WindowServer::Screen::for_each([&](auto& screen) {
if (!reachable_screens.contains_slow(&screen))
dbgln("Screen {} cannot be reached from main screen {}: Bad configuration!", screen.index(), WindowServer::Screen::main().index());
return IterationDecision::Continue;
});
dbgln("At least one screen is not adjacent to another screen, exiting!");
return 1;
}
}
// TODO: Enumerate the /dev/fbX devices and set up any ones we find that we haven't already used
auto& screen_input = WindowServer::ScreenInput::the();