Improves RT window position management, fixes #6233 (#6239)

* Improves RT window events detection and RT window position computation

* Fixes some limitations in specific cases for Windows and MacOS

* Fixes RT window not restoring saved position at startup

- When maximized at startup, RT window position wasn't restored from
options file. So when unmaximazing RT, position was set to up left
corner instead of restored one
- Other fix: Removed some uses of deprecated Gtk functions

* Improves RT window management for independant edit window mode

Other fixes:
- Monitor ID wasn't correctly computed
- Removes some other deprecated functions uses
- Removes debug printf

* Fixes editor window aspects not restored in MEOW mode on Linux

Other fixes:
- Removes some Gtk warnings when adding a new editor panel in MEOW mode
- Adds robustness to avoid RT windows outside screen at startup loading
corrupted options file with negative position values

* Fixes incorrect max position saturation in dual screen configurations
This commit is contained in:
Pandagrapher
2021-06-21 21:22:14 +02:00
committed by GitHub
parent 7e36240f3a
commit 491b57bee7
6 changed files with 232 additions and 101 deletions

113
rtgui/rtwindow.cc Normal file → Executable file
View File

@@ -282,8 +282,10 @@ RTWindow::RTWindow ()
on_delete_has_run = false;
is_fullscreen = false;
is_minimized = false;
property_destroy_with_parent().set_value (false);
signal_window_state_event().connect ( sigc::mem_fun (*this, &RTWindow::on_window_state_event) );
onConfEventConn = signal_configure_event().connect ( sigc::mem_fun (*this, &RTWindow::on_configure_event) );
signal_key_press_event().connect ( sigc::mem_fun (*this, &RTWindow::keyPressed) );
signal_key_release_event().connect(sigc::mem_fun(*this, &RTWindow::keyReleased));
@@ -522,7 +524,7 @@ void RTWindow::showErrors()
bool RTWindow::on_configure_event (GdkEventConfigure* event)
{
if (!is_maximized() && is_visible()) {
if (!options.windowMaximized && !is_fullscreen && !is_minimized) {
get_size (options.windowWidth, options.windowHeight);
get_position (options.windowX, options.windowY);
}
@@ -535,10 +537,11 @@ bool RTWindow::on_configure_event (GdkEventConfigure* event)
bool RTWindow::on_window_state_event (GdkEventWindowState* event)
{
if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) {
options.windowMaximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED;
}
// Retrieve RT window states
options.windowMaximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED;
is_minimized = event->new_window_state & GDK_WINDOW_STATE_ICONIFIED;
is_fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN;
return Gtk::Widget::on_window_state_event (event);
}
@@ -577,8 +580,10 @@ void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name)
{
if (options.multiDisplayMode > 0) {
EditWindow * wndEdit = EditWindow::getInstance (this);
wndEdit->show();
wndEdit->addEditorPanel (ep, name);
wndEdit->show_all();
wndEdit->restoreWindow(); // Need to be called after RTWindow creation to work with all OS Windows Manager
ep->setAspect();
wndEdit->toFront();
} else {
ep->setParent (this);
@@ -795,7 +800,7 @@ bool RTWindow::on_delete_event (GdkEventAny* event)
if (isSingleTabMode() || simpleEditor) {
isProcessing = epanel->getIsProcessing();
} else if (options.multiDisplayMode > 0) {
editWindow = EditWindow::getInstance (this, false);
editWindow = EditWindow::getInstance (this);
isProcessing = editWindow->isProcessing();
} else {
int pageCount = mainNB->get_n_pages();
@@ -863,12 +868,22 @@ bool RTWindow::on_delete_event (GdkEventAny* event)
FileBrowserEntry::hdr.reset();
FileBrowserEntry::ps.reset();
if (!options.windowMaximized) {
if (!options.windowMaximized && !is_fullscreen && !is_minimized) {
get_size (options.windowWidth, options.windowHeight);
get_position (options.windowX, options.windowY);
}
options.windowMonitor = get_screen()->get_monitor_at_window (get_window());
// Retrieve window monitor ID
options.windowMonitor = 0;
const auto display = get_screen()->get_display();
const int monitor_nb = display->get_n_monitors();
for (int id = 0; id < monitor_nb; id++) {
if (display->get_monitor_at_window(get_window()) == display->get_monitor(id)) {
options.windowMonitor = id;
break;
}
}
try {
Options::save ();
@@ -981,25 +996,25 @@ void RTWindow::error(const Glib::ustring& descr)
void RTWindow::toggle_fullscreen ()
{
onConfEventConn.block(true); // Avoid getting size and position while window is getting fullscreen
if (is_fullscreen) {
unfullscreen();
is_fullscreen = false;
if (btn_fullscreen) {
//btn_fullscreen->set_label(M("MAIN_BUTTON_FULLSCREEN"));
btn_fullscreen->set_tooltip_markup (M ("MAIN_BUTTON_FULLSCREEN"));
btn_fullscreen->set_image (*iFullscreen);
}
} else {
fullscreen();
is_fullscreen = true;
if (btn_fullscreen) {
//btn_fullscreen->set_label(M("MAIN_BUTTON_UNFULLSCREEN"));
btn_fullscreen->set_tooltip_markup (M ("MAIN_BUTTON_UNFULLSCREEN"));
btn_fullscreen->set_image (*iFullscreen_exit);
}
}
onConfEventConn.block(false);
}
void RTWindow::SetEditorCurrent()
@@ -1105,40 +1120,70 @@ bool RTWindow::splashClosed (GdkEventAny* event)
void RTWindow::setWindowSize ()
{
onConfEventConn.block(true); // Avoid getting size and position while window is being moved, maximized, ...
Gdk::Rectangle lMonitorRect;
get_screen()->get_monitor_geometry (std::min (options.windowMonitor, Gdk::Screen::get_default()->get_n_monitors() - 1), lMonitorRect);
const auto display = get_screen()->get_display();
display->get_monitor (std::min (options.windowMonitor, display->get_n_monitors() - 1))->get_geometry(lMonitorRect);
#ifdef __APPLE__
// Get macOS menu bar height
const Gdk::Rectangle lWorkAreaRect = get_screen()->get_monitor_workarea (std::min (options.windowMonitor, Gdk::Screen::get_default()->get_n_monitors() - 1));
Gdk::Rectangle lWorkAreaRect;
display->get_monitor (std::min (options.windowMonitor, display->get_n_monitors() - 1))->get_workarea(lWorkAreaRect);
const int macMenuBarHeight = lWorkAreaRect.get_y();
// Place RT window to saved one in options file
if (options.windowX <= lMonitorRect.get_x() + lMonitorRect.get_width()
&& options.windowX >= 0
&& options.windowY <= lMonitorRect.get_y() + lMonitorRect.get_height() - macMenuBarHeight
&& options.windowY >= 0) {
move (options.windowX, options.windowY + macMenuBarHeight);
} else {
move (lMonitorRect.get_x(), lMonitorRect.get_y() + macMenuBarHeight);
}
#else
// Place RT window to saved one in options file
if (options.windowX <= lMonitorRect.get_x() + lMonitorRect.get_width()
&& options.windowX >= 0
&& options.windowY <= lMonitorRect.get_y() + lMonitorRect.get_height()
&& options.windowY >= 0) {
move (options.windowX, options.windowY);
} else {
move (lMonitorRect.get_x(), lMonitorRect.get_y());
}
#endif
// Maximize RT window according to options file
if (options.windowMaximized) {
#ifdef __APPLE__
move (lMonitorRect.get_x(), lMonitorRect.get_y() + macMenuBarHeight);
#else
move (lMonitorRect.get_x(), lMonitorRect.get_y());
#endif
maximize();
} else {
unmaximize();
resize (options.windowWidth, options.windowHeight);
#ifdef __APPLE__
if (options.windowX <= lMonitorRect.get_x() + lMonitorRect.get_width() && options.windowY <= lMonitorRect.get_y() + lMonitorRect.get_height() - macMenuBarHeight) {
move (options.windowX, options.windowY + macMenuBarHeight);
} else {
move (lMonitorRect.get_x(), lMonitorRect.get_y() + macMenuBarHeight);
}
#else
if (options.windowX <= lMonitorRect.get_x() + lMonitorRect.get_width() && options.windowY <= lMonitorRect.get_y() + lMonitorRect.get_height()) {
move (options.windowX, options.windowY);
} else {
move (lMonitorRect.get_x(), lMonitorRect.get_y());
}
#endif
}
onConfEventConn.block(false);
}
void RTWindow::get_position(int& x, int& y) const
{
// Call native function
Gtk::Window::get_position (x, y);
// Retrieve display (concatenation of all monitors) size
int width = 0, height = 0;
const auto display = get_screen()->get_display();
const int nbMonitors = display->get_n_monitors();
for (int i = 0; i < nbMonitors; i++) {
Gdk::Rectangle lMonitorRect;
display->get_monitor(i)->get_geometry(lMonitorRect);
width = std::max(width, lMonitorRect.get_x() + lMonitorRect.get_width());
height = std::max(height, lMonitorRect.get_y() + lMonitorRect.get_height());
}
// Saturate position at monitor limits to avoid unexpected behavior (fixes #6233)
x = std::min(width, std::max(0, x));
y = std::min(height, std::max(0, y));
}
void RTWindow::set_title_decorated (Glib::ustring fname)