-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
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
Improve editor popups with multiple screens #37506
Conversation
I saw your comment on IRC, I was unable to fix two screen bugs because hardware limitation (I'm trapped on Brazil because Coronavirus, and only have my notebook with limited hardware). Set the position and size with XSizeHints is obsolete (https://tronche.com/gui/x/xlib/ICC/client-to-window-manager/wm-normal-hints.html), to set the position. A better aproach is with https://tronche.com/gui/x/xlib/window/configure.html |
Oh sorry. I didn't saw you are working on it... |
I tested this PR and #37320 doesn't happen anymore. |
ce41f13
to
24955cf
Compare
X11 comments: Cannot continue due to window position checks returning (0,0) sometimes and sometimes not. I have tried combining XGetWindowAttributes with XQueryTree and XTranslateCoordinates but it doesn't fix the problem. It may be the window manager being insane, but I still don't know. I have tried setting XConfigureWindow as @kuruk-mm (I hope you are well) suggested on the create window function but I didn't get different results. I will be pushing that structure so he won't have to make these changes. To set a new screen for the window, the trick could be taking the current coordinates and subtracting the current screen offset (screen_get_position). Then getting the new screen offset and adding it to the previous subtraction. But we require the window position to be the real one. X11 in conclusion: XGetWindowAttributes or XTranslateCoordinates sometimes returns incorrect positions when the editor is not in the default/primary screen. Watch the print_line() in _window_changed and the print_line() in _create_window while randomly clicking "Scene, Project, Debug, Editor and Help" dropdown menus in the editor. This must be fixed to allow moving windows within screens reliably. Due to being a problem that a lot of people will encounter I have decided to simply adapt this PR to be merged so that it is not tried to be solved multiple times. EDIT: This comment is outdated from the current changes (last push). |
24955cf
to
0ada1e6
Compare
0ada1e6
to
6784b57
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some other places with global_position
/global_transform
used for pop-up:
godot/editor/animation_bezier_editor.cpp
Lines 654 to 667 in 6366332
Vector2 popup_pos = get_global_transform().xform(mb->get_position()); | |
menu->clear(); | |
menu->add_icon_item(bezier_icon, TTR("Insert Key Here"), MENU_KEY_INSERT); | |
if (selection.size()) { | |
menu->add_separator(); | |
menu->add_icon_item(get_theme_icon("Duplicate", "EditorIcons"), TTR("Duplicate Selected Key(s)"), MENU_KEY_DUPLICATE); | |
menu->add_separator(); | |
menu->add_icon_item(get_theme_icon("Remove", "EditorIcons"), TTR("Delete Selected Key(s)"), MENU_KEY_DELETE); | |
} | |
menu->set_as_minsize(); | |
menu->set_position(popup_pos); | |
menu->popup(); |
godot/editor/connections_dialog.cpp
Line 828 in 6366332
Vector2 global_position = tree->get_global_position() + position; |
godot/editor/dependency_editor.cpp
Line 281 in 6366332
file_options->set_position(owners->get_global_position() + p_pos); |
godot/editor/editor_audio_buses.cpp
Lines 506 to 507 in 6366332
effect_options->set_position(effects->get_global_position() + area.position + Vector2(0, area.size.y)); | |
effect_options->popup(); |
godot/editor/editor_audio_buses.cpp
Lines 561 to 562 in 6366332
bus_popup->set_position(get_global_position() + pos); | |
bus_popup->popup(); |
godot/editor/editor_file_dialog.cpp
Lines 605 to 606 in 6366332
item_menu->set_position(item_list->get_global_position() + p_pos); | |
item_menu->popup(); |
godot/editor/editor_file_dialog.cpp
Lines 627 to 628 in 6366332
item_menu->set_position(item_list->get_global_position() + p_pos); | |
item_menu->popup(); |
Lines 4760 to 4761 in 6366332
scene_tabs_context_menu->set_position(mb->get_global_position()); | |
scene_tabs_context_menu->popup(); |
godot/editor/filesystem_dock.cpp
Lines 2267 to 2268 in 6366332
tree_popup->set_position(tree->get_global_position() + p_pos); | |
tree_popup->popup(); |
godot/editor/filesystem_dock.cpp
Lines 2281 to 2282 in 6366332
tree_popup->set_position(tree->get_global_position() + p_pos); | |
tree_popup->popup(); |
godot/editor/filesystem_dock.cpp
Lines 2307 to 2308 in 6366332
file_list_popup->set_position(files->get_global_position() + p_pos); | |
file_list_popup->popup(); |
godot/editor/filesystem_dock.cpp
Lines 2326 to 2327 in 6366332
file_list_popup->set_position(files->get_global_position() + p_pos); | |
file_list_popup->popup(); |
godot/editor/project_settings_editor.cpp
Lines 628 to 634 in 6366332
Point2 ofs = input_editor->get_global_position(); | |
Rect2 ir = input_editor->get_item_rect(ti); | |
ir.position.y -= input_editor->get_scroll().y; | |
ofs += ir.position + ir.size; | |
ofs.x -= 100; | |
popup_add->set_position(ofs); | |
popup_add->popup(); |
godot/editor/debugger/script_editor_debugger.cpp
Lines 1396 to 1397 in 6366332
item_menu->set_position(error_tree->get_global_position() + p_pos); | |
item_menu->popup(); |
godot/editor/plugins/curve_editor_plugin.cpp
Line 121 in 6366332
open_context_menu(get_global_transform().xform(mpos)); |
members_dialog->set_position(graph->get_global_position() + Point2(5 * EDSCALE, 65 * EDSCALE)); |
These callbacks arguments probably aren't in the screen coordinates either:
godot/editor/scene_tree_dock.cpp
Line 2387 in 6366332
void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { |
void AnimationNodeBlendTreeEditor::_popup_request(const Vector2 &p_position) { |
get_global_mouse_position()
→ get_screen_transform().xform(get_local_mouse_position()
:
godot/editor/editor_audio_buses.cpp
Lines 752 to 753 in 6366332
delete_effect_popup->set_position(get_global_mouse_position()); | |
delete_effect_popup->popup(); |
And unlikely I have found all places.
int current_screen = window_get_current_screen(p_window); | ||
if (p_screen != current_screen) { | ||
|
||
Point2i to_screen_pos = screen_get_position(p_screen); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notes for the future improvemet:
- Special Fullscreen case probably should be ported to Windows and macOS as well.
- In case current window position (relative to the current screen) is bigger than target screen size, window will be moved to the wrong screen (not handled on any platform).
e.g. with the following display config, moving window to screen 1 will move it to screen 2 instead:
6784b57
to
dfdc05a
Compare
In X11, we're currently saving the coordinates in the _create_window() function to the rect provided as argument to the function but after making a XMoveResizeWindow() call. The problem of this is that we may not be able to set the first window position (the WM will probably place it somewhere else, like would happen with tiling WMs but it doesn't have to be tiled to ignore your placement). XCreateWindow() coordinates are sometimes ignored too. As a consequence, the saved coordinates may not be correct and up to date with the real position when making the window (this should only happen once). I would recommend to use ConfigureNotify event as a source of truth for the real position of the window, which means that only _window_changed() function should modify and save coordinates of the window structure. Having said that, XSync only makes sure that the command is sent, received and processed by the X server which means that it still has to give us the REAL coordinates back sending the client a ConfigureNotify event. In conclusion, I have not found any other method to get real coordinates other than waiting for ConfigureNotify event and updating the saved coordinates accordingly (without using any type of transformation as coordinates should be global like happens in MacOS and should happen in Windows). Future work could concentrate on waiting for the first ConfigureNotify event inside the _create_window() function or searching for another way to retrieve real coordinates (which I don't recommend if you're not an expert with X11). EDIT: I have tried adding this:
instead of setting coordinates manually when creating the window but no success, windows are warped to the corner somewhere and I have not checked if they're updated properly (it could still be that some of the popups are not properly fixed). I propose to keep it as it is for now until it stops working for someone (if it ever does). |
Requesting rebase. |
dfdc05a
to
dee904b
Compare
This enables working with multiple screens at least on X11. Fullscreen now preserves borders when being toggled off (only on X11). Also fixes cross platform issues like position transforms to screen space in files (thanks to bruvzg). Co-authored-by: bruvzg <[email protected]>
dee904b
to
9bf03ee
Compare
Changes from this PR have been included in the other PR except changes to: |
As this PR has 10 conflicting files (which would require me to download, compile and test the code after changes or patch the code from the open PRs only and add the code changes that have been left out) I would suggest merging #52280 and #42117. #41395 mitigated tooltip positioning and with #40922 it is possible that X11 may work correctly after these two are merged. However, if after merging #52280 and #42117, someone finds that in X11 windows (tooltips will be probably be already fixed) are still placed in the first screen and not in the screen where the editor (which is the parent window) is running, create a new PR adding the changes from the If in X11 anyone still has problems after merging these two PR mentioned above, compile the engine with both the changes from Be aware that when this PR was made, the code here was tested on at least 2 KDE desktops and an Ubuntu one (Gnome or Unity, I don't remember), working fine (tiling WMs worked but the windows or tooltips ocuppied a big screen area and I don't know if they were supposed to). |
Alright, closing as per the above comment. :) |
Hopefully this PR will be able to fix multi-screen support.
Fixes #37320
Fixes #38591