diff options
author | Pierre Ossman <ossman@cendio.se> | 2021-09-09 11:01:47 +0200 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2021-09-09 13:12:23 +0200 |
commit | fb561eb321b36dcf13932c903047ce08e55d67d5 (patch) | |
tree | a7e2f09bfb3bb50ff1c395361373c54b9b3036e3 /vncviewer/MonitorArrangement.cxx | |
parent | 56c50c01463c5cd15607d4efdacd03c090420d24 (diff) | |
download | tigervnc-fb561eb321b36dcf13932c903047ce08e55d67d5.tar.gz tigervnc-fb561eb321b36dcf13932c903047ce08e55d67d5.zip |
Handle mirrored monitors on X11
macOS and Windows present mirrored monitors as a single virtual monitor,
but X11 exposes this scenario as two distinct monitors with identical
coordinates. This messes up our logic, and is likely confusing for the
user. So instead we'll ignore any monitors that have identical
coordinates to any already seen monitors.
Diffstat (limited to 'vncviewer/MonitorArrangement.cxx')
-rw-r--r-- | vncviewer/MonitorArrangement.cxx | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/vncviewer/MonitorArrangement.cxx b/vncviewer/MonitorArrangement.cxx index b1d30128..735177ba 100644 --- a/vncviewer/MonitorArrangement.cxx +++ b/vncviewer/MonitorArrangement.cxx @@ -1,4 +1,5 @@ /* Copyright 2021 Hugo Lundin <huglu@cendio.se> for Cendio AB. + * Copyright 2021 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,8 +61,7 @@ MonitorArrangement::MonitorArrangement( int x, int y, int w, int h) : Fl_Group(x, y, w, h), SELECTION_COLOR(fl_lighter(FL_BLUE)), - AVAILABLE_COLOR(fl_lighter(fl_lighter(fl_lighter(FL_BACKGROUND_COLOR)))), - monitors() + AVAILABLE_COLOR(fl_lighter(fl_lighter(fl_lighter(FL_BACKGROUND_COLOR)))) { // Used for required monitors. Fl::set_boxtype(FL_CHECKERED_BOX, checkered_pattern_draw, 0, 0, 0, 0); @@ -87,10 +87,11 @@ MonitorArrangement::~MonitorArrangement() std::set<int> MonitorArrangement::get() { std::set<int> indices; + MonitorMap::const_iterator iter; - for (int i = 0; i < (int) monitors.size(); i++) { - if (monitors[i]->value() == 1) - indices.insert(i); + for (iter = monitors.begin(); iter != monitors.end(); ++iter) { + if (iter->second->value() == 1) + indices.insert(iter->first); } return indices; @@ -98,18 +99,23 @@ std::set<int> MonitorArrangement::get() void MonitorArrangement::set(std::set<int> indices) { - for (int i = 0; i < (int) monitors.size(); i++) { - bool selected = std::find(indices.begin(), indices.end(), i) != indices.end(); - monitors[i]->value(selected ? 1 : 0); + MonitorMap::const_iterator iter; + + for (iter = monitors.begin(); iter != monitors.end(); ++iter) { + bool selected = std::find(indices.begin(), indices.end(), + iter->first) != indices.end(); + iter->second->value(selected ? 1 : 0); } } void MonitorArrangement::draw() { - for (int i = 0; i < (int) monitors.size(); i++) { - Fl_Button * monitor = monitors[i]; + MonitorMap::const_iterator iter; + + for (iter = monitors.begin(); iter != monitors.end(); ++iter) { + Fl_Button * monitor = iter->second; - if (is_required(i)) { + if (is_required(iter->first)) { monitor->box(FL_CHECKERED_BOX); monitor->color(SELECTION_COLOR); } else { @@ -130,8 +136,26 @@ void MonitorArrangement::layout() std::pair<int, int> offset = this->offset(); for (int i = 0; i < Fl::screen_count(); i++) { + bool match; + Fl::screen_xywh(x, y, w, h, i); + // Only keep a single entry for mirrored screens + match = false; + for (int j = 0; j < i; j++) { + int x2, y2, w2, h2; + + Fl::screen_xywh(x2, y2, w2, h2, j); + + if ((x != x2) || (y != y2) || (w != w2) || (h != h2)) + continue; + + match = true; + break; + } + if (match) + continue; + Fl_Button *monitor = new Fl_Button( /* x = */ this->x() + offset.first + x*scale + (1 - MARGIN_SCALE_FACTOR)*x*scale, /* y = */ this->y() + offset.second + y*scale + (1 - MARGIN_SCALE_FACTOR)*y*scale, @@ -143,11 +167,9 @@ void MonitorArrangement::layout() monitor->callback(monitor_pressed, this); monitor->type(FL_TOGGLE_BUTTON); monitor->when(FL_WHEN_CHANGED); - monitors.push_back(monitor); + monitor->copy_tooltip(description(i).c_str()); + monitors[i] = monitor; } - - for (int i = 0; i < (int) monitors.size(); i++) - monitors[i]->copy_tooltip(description(i).c_str()); } void MonitorArrangement::refresh() @@ -308,7 +330,7 @@ std::pair<int, int> MonitorArrangement::origin() std::string MonitorArrangement::description(int m) { - assert(m < (int) monitors.size()); + assert(m < Fl::screen_count()); const size_t name_len = 1024; char name[name_len] = {}; int bytes_written = get_monitor_name(m, name, name_len); |