Skip to content

Commit

Permalink
Merge pull request #41456 from nekomatata/x11-fix-popups
Browse files Browse the repository at this point in the history
Popup fixes for X11 display server
  • Loading branch information
akien-mga authored Sep 2, 2020
2 parents 7cc1e20 + bb30675 commit 2a8531c
Show file tree
Hide file tree
Showing 11 changed files with 251 additions and 122 deletions.
249 changes: 168 additions & 81 deletions platform/linuxbsd/display_server_x11.cpp

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions platform/linuxbsd/display_server_x11.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ class DisplayServerX11 : public DisplayServer {

ObjectID instance_id;

bool menu_type = false;
bool no_focus = false;

//better to guess on the fly, given WM can change it
//WindowMode mode;
bool fullscreen = false; //OS can't exit from this mode
Expand Down Expand Up @@ -277,6 +280,7 @@ class DisplayServerX11 : public DisplayServer {
virtual Vector<DisplayServer::WindowID> get_window_list() const;

virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);

virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
Expand Down
1 change: 1 addition & 0 deletions platform/osx/display_server_osx.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ class DisplayServerOSX : public DisplayServer {
virtual Vector<int> get_window_list() const override;

virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
virtual void show_window(WindowID p_id) override;
virtual void delete_sub_window(WindowID p_id) override;

virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
Expand Down
11 changes: 8 additions & 3 deletions platform/osx/display_server_osx.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2314,18 +2314,23 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay
_THREAD_SAFE_METHOD_

WindowID id = _create_window(p_mode, p_rect);
WindowData &wd = windows[id];
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, id);
}
}

return id;
}

void DisplayServerOSX::show_window(WindowID p_id) {
WindowData &wd = windows[p_id];

if (wd.no_focus) {
[wd.window_object orderFront:nil];
} else {
[wd.window_object makeKeyAndOrderFront:nil];
}
return id;
}

void DisplayServerOSX::_send_window_event(const WindowData &wd, WindowEvent p_event) {
Expand Down Expand Up @@ -3774,7 +3779,7 @@ Point2i window_position(
window_set_flag(WindowFlags(i), true, main_window);
}
}
[windows[main_window].window_object makeKeyAndOrderFront:nil];
show_window(MAIN_WINDOW_ID);

#if defined(OPENGL_ENABLED)
if (rendering_driver == "opengl_es") {
Expand Down
20 changes: 12 additions & 8 deletions platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,15 +493,21 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
wd.no_focus = true;
}

_update_window_style(window_id);
return window_id;
}

ShowWindow(wd.hWnd, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) ? SW_SHOWNOACTIVATE : SW_SHOW); // Show The Window
if (!(p_flags & WINDOW_FLAG_NO_FOCUS_BIT)) {
void DisplayServerWindows::show_window(WindowID p_id) {
WindowData &wd = windows[p_id];

if (p_id != MAIN_WINDOW_ID) {
_update_window_style(p_id);
}

ShowWindow(wd.hWnd, wd.no_focus ? SW_SHOWNOACTIVATE : SW_SHOW); // Show The Window
if (!wd.no_focus) {
SetForegroundWindow(wd.hWnd); // Slightly Higher Priority
SetFocus(wd.hWnd); // Sets Keyboard Focus To
}

return window_id;
}

void DisplayServerWindows::delete_sub_window(WindowID p_window) {
Expand Down Expand Up @@ -3139,9 +3145,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
}

ShowWindow(windows[MAIN_WINDOW_ID].hWnd, SW_SHOW); // Show The Window
SetForegroundWindow(windows[MAIN_WINDOW_ID].hWnd); // Slightly Higher Priority
SetFocus(windows[MAIN_WINDOW_ID].hWnd); // Sets Keyboard Focus To
show_window(MAIN_WINDOW_ID);

#if defined(VULKAN_ENABLED)

Expand Down
1 change: 1 addition & 0 deletions platform/windows/display_server_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ class DisplayServerWindows : public DisplayServer {
virtual Vector<DisplayServer::WindowID> get_window_list() const;

virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_window);
virtual void delete_sub_window(WindowID p_window);

virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
Expand Down
68 changes: 41 additions & 27 deletions scene/gui/popup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,55 +41,71 @@ void Popup::_input_from_window(const Ref<InputEvent> &p_event) {
}
}

void Popup::_parent_focused() {
_close_pressed();
void Popup::_initialize_visible_parents() {
visible_parents.clear();

Window *parent_window = this;
while (parent_window) {
parent_window = parent_window->get_parent_visible_window();
if (parent_window) {
visible_parents.push_back(parent_window);
parent_window->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
parent_window->connect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
}
}
}

void Popup::_deinitialize_visible_parents() {
for (uint32_t i = 0; i < visible_parents.size(); ++i) {
visible_parents[i]->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
visible_parents[i]->disconnect("tree_exited", callable_mp(this, &Popup::_deinitialize_visible_parents));
}

visible_parents.clear();
}

void Popup::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
parent_visible = get_parent_visible_window();
if (parent_visible) {
parent_visible->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
}
_initialize_visible_parents();
} else {
if (parent_visible) {
parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
parent_visible = nullptr;
}

_deinitialize_visible_parents();
emit_signal("popup_hide");
}

} break;
case NOTIFICATION_EXIT_TREE: {
if (parent_visible) {
parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
parent_visible = nullptr;
case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
if (has_focus()) {
popped_up = true;
}
} break;
case NOTIFICATION_EXIT_TREE: {
_deinitialize_visible_parents();
} break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
_close_pressed();

} break;
case NOTIFICATION_APPLICATION_FOCUS_OUT: {
_close_pressed();
} break;
}
}

void Popup::_close_pressed() {
Window *parent_window = parent_visible;
if (parent_visible) {
parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
parent_visible = nullptr;
void Popup::_parent_focused() {
if (popped_up) {
_close_pressed();
}
}

void Popup::_close_pressed() {
popped_up = false;

_deinitialize_visible_parents();

call_deferred("hide");

emit_signal("cancelled");

if (parent_window) {
//parent_window->grab_focus();
}
}

void Popup::set_as_minsize() {
Expand Down Expand Up @@ -152,8 +168,6 @@ Rect2i Popup::_popup_adjust_rect() const {
}

Popup::Popup() {
parent_visible = nullptr;

set_wrap_controls(true);
set_visible(false);
set_transient(true);
Expand Down
9 changes: 8 additions & 1 deletion scene/gui/popup.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,19 @@

#include "scene/main/window.h"

#include "core/local_vector.h"

class Popup : public Window {
GDCLASS(Popup, Window);

Window *parent_visible;
LocalVector<Window *> visible_parents;
bool popped_up = false;

void _input_from_window(const Ref<InputEvent> &p_event);

void _initialize_visible_parents();
void _deinitialize_visible_parents();

void _parent_focused();

protected:
Expand Down
5 changes: 3 additions & 2 deletions scene/main/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,10 @@ void Window::_make_window() {
}
}

_update_window_callbacks();

RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
DisplayServer::get_singleton()->show_window(window_id);
}

void Window::_update_from_window() {
Expand Down Expand Up @@ -378,7 +381,6 @@ void Window::set_visible(bool p_visible) {
}
if (p_visible && window_id == DisplayServer::INVALID_WINDOW_ID) {
_make_window();
_update_window_callbacks();
}
} else {
if (visible) {
Expand Down Expand Up @@ -737,7 +739,6 @@ void Window::_notification(int p_what) {
//create
if (visible) {
_make_window();
_update_window_callbacks();
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions servers/display_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server.");
}

void DisplayServer::show_window(WindowID p_id) {
ERR_FAIL_MSG("Sub-windows not supported by this display server.");
}

void DisplayServer::delete_sub_window(WindowID p_id) {
ERR_FAIL_MSG("Sub-windows not supported by this display server.");
}
Expand Down
1 change: 1 addition & 0 deletions servers/display_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ class DisplayServer : public Object {
};

virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);

virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0;
Expand Down

0 comments on commit 2a8531c

Please sign in to comment.