mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
Partially fix excessive event spam when resizing windows
This commit is contained in:
parent
987ba2083b
commit
083e160f89
@ -372,6 +372,7 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
# Now hang a hook on the window-event from Panda. This allows
|
# Now hang a hook on the window-event from Panda. This allows
|
||||||
# us to detect when the user resizes, minimizes, or closes the
|
# us to detect when the user resizes, minimizes, or closes the
|
||||||
# main window.
|
# main window.
|
||||||
|
self.__prevWindowProperties = None
|
||||||
self.accept('window-event', self.windowEvent)
|
self.accept('window-event', self.windowEvent)
|
||||||
|
|
||||||
# Transition effects (fade, iris, etc)
|
# Transition effects (fade, iris, etc)
|
||||||
@ -2614,9 +2615,15 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
return Task.cont
|
return Task.cont
|
||||||
|
|
||||||
def windowEvent(self, win):
|
def windowEvent(self, win):
|
||||||
if win == self.win:
|
if win != self.win:
|
||||||
properties = win.getProperties()
|
# This event isn't about our window.
|
||||||
self.notify.info("Got window event: %s" % (repr(properties)))
|
return
|
||||||
|
|
||||||
|
properties = win.getProperties()
|
||||||
|
if properties != self.__prevWindowProperties:
|
||||||
|
self.__prevWindowProperties = properties
|
||||||
|
|
||||||
|
self.notify.debug("Got window event: %s" % (repr(properties)))
|
||||||
if not properties.getOpen():
|
if not properties.getOpen():
|
||||||
# If the user closes the main window, we should exit.
|
# If the user closes the main window, we should exit.
|
||||||
self.notify.info("User closed main window.")
|
self.notify.info("User closed main window.")
|
||||||
|
@ -263,6 +263,12 @@ process_events() {
|
|||||||
XKeyEvent keyrelease_event;
|
XKeyEvent keyrelease_event;
|
||||||
bool got_keyrelease_event = false;
|
bool got_keyrelease_event = false;
|
||||||
|
|
||||||
|
XConfigureEvent configure_event;
|
||||||
|
bool got_configure_event = false;
|
||||||
|
|
||||||
|
WindowProperties properties;
|
||||||
|
bool changed_properties = false;
|
||||||
|
|
||||||
while (XCheckIfEvent(_display, &event, check_event, (char *)this)) {
|
while (XCheckIfEvent(_display, &event, check_event, (char *)this)) {
|
||||||
if (XFilterEvent(&event, None)) {
|
if (XFilterEvent(&event, None)) {
|
||||||
continue;
|
continue;
|
||||||
@ -295,7 +301,6 @@ process_events() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowProperties properties;
|
|
||||||
ButtonHandle button;
|
ButtonHandle button;
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
@ -303,38 +308,11 @@ process_events() {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ConfigureNotify:
|
case ConfigureNotify:
|
||||||
_awaiting_configure = false;
|
// When resizing or moving the window, multiple ConfigureNotify
|
||||||
|
// events may be sent in rapid succession. We only respond to
|
||||||
// Is this the inner corner or the outer corner? The Xlib docs
|
// the last one.
|
||||||
// say it should be the outer corner, but it appears to be the
|
configure_event = event.xconfigure;
|
||||||
// inner corner on my own implementation, which is inconsistent
|
got_configure_event = true;
|
||||||
// with XConfigureWindow. (Panda really wants to work with the
|
|
||||||
// inner corner, anyway, but that means we need to fix
|
|
||||||
// XConfigureWindow too.)
|
|
||||||
properties.set_origin(event.xconfigure.x, event.xconfigure.y);
|
|
||||||
|
|
||||||
if (_properties.get_fixed_size()) {
|
|
||||||
// If the window properties indicate a fixed size only, undo
|
|
||||||
// any attempt by the user to change them. In X, there
|
|
||||||
// doesn't appear to be a way to universally disallow this
|
|
||||||
// directly (although we do set the min_size and max_size to
|
|
||||||
// the same value, which seems to work for most window
|
|
||||||
// managers.)
|
|
||||||
WindowProperties current_props = get_properties();
|
|
||||||
if (event.xconfigure.width != current_props.get_x_size() ||
|
|
||||||
event.xconfigure.height != current_props.get_y_size()) {
|
|
||||||
XWindowChanges changes;
|
|
||||||
changes.width = current_props.get_x_size();
|
|
||||||
changes.height = current_props.get_y_size();
|
|
||||||
int value_mask = (CWWidth | CWHeight);
|
|
||||||
XConfigureWindow(_display, _xwindow, value_mask, &changes);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// A normal window may be resized by the user at will.
|
|
||||||
properties.set_size(event.xconfigure.width, event.xconfigure.height);
|
|
||||||
}
|
|
||||||
system_changed_properties(properties);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
@ -391,23 +369,23 @@ process_events() {
|
|||||||
|
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
properties.set_foreground(true);
|
properties.set_foreground(true);
|
||||||
system_changed_properties(properties);
|
changed_properties = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
_input_devices[0].focus_lost();
|
_input_devices[0].focus_lost();
|
||||||
properties.set_foreground(false);
|
properties.set_foreground(false);
|
||||||
system_changed_properties(properties);
|
changed_properties = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UnmapNotify:
|
case UnmapNotify:
|
||||||
properties.set_minimized(true);
|
properties.set_minimized(true);
|
||||||
system_changed_properties(properties);
|
changed_properties = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MapNotify:
|
case MapNotify:
|
||||||
properties.set_minimized(false);
|
properties.set_minimized(false);
|
||||||
system_changed_properties(properties);
|
changed_properties = true;
|
||||||
|
|
||||||
// Auto-focus the window when it is mapped.
|
// Auto-focus the window when it is mapped.
|
||||||
XSetInputFocus(_display, _xwindow, RevertToPointerRoot, CurrentTime);
|
XSetInputFocus(_display, _xwindow, RevertToPointerRoot, CurrentTime);
|
||||||
@ -449,6 +427,47 @@ process_events() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (got_configure_event) {
|
||||||
|
// Now handle the last configure event we found.
|
||||||
|
_awaiting_configure = false;
|
||||||
|
|
||||||
|
// Is this the inner corner or the outer corner? The Xlib docs
|
||||||
|
// say it should be the outer corner, but it appears to be the
|
||||||
|
// inner corner on my own implementation, which is inconsistent
|
||||||
|
// with XConfigureWindow. (Panda really wants to work with the
|
||||||
|
// inner corner, anyway, but that means we need to fix
|
||||||
|
// XConfigureWindow too.)
|
||||||
|
properties.set_origin(configure_event.x, configure_event.y);
|
||||||
|
|
||||||
|
if (_properties.get_fixed_size()) {
|
||||||
|
// If the window properties indicate a fixed size only, undo
|
||||||
|
// any attempt by the user to change them. In X, there
|
||||||
|
// doesn't appear to be a way to universally disallow this
|
||||||
|
// directly (although we do set the min_size and max_size to
|
||||||
|
// the same value, which seems to work for most window
|
||||||
|
// managers.) Incidentally, this also works to force my
|
||||||
|
// tiling window manager into 'floating' mode.
|
||||||
|
WindowProperties current_props = get_properties();
|
||||||
|
if (configure_event.width != current_props.get_x_size() ||
|
||||||
|
configure_event.height != current_props.get_y_size()) {
|
||||||
|
XWindowChanges changes;
|
||||||
|
changes.width = current_props.get_x_size();
|
||||||
|
changes.height = current_props.get_y_size();
|
||||||
|
int value_mask = (CWWidth | CWHeight);
|
||||||
|
XConfigureWindow(_display, _xwindow, value_mask, &changes);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// A normal window may be resized by the user at will.
|
||||||
|
properties.set_size(configure_event.width, configure_event.height);
|
||||||
|
}
|
||||||
|
changed_properties = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed_properties) {
|
||||||
|
system_changed_properties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
if (got_keyrelease_event) {
|
if (got_keyrelease_event) {
|
||||||
// This keyrelease event is not immediately followed by a
|
// This keyrelease event is not immediately followed by a
|
||||||
// matching keypress event, so it's a genuine release.
|
// matching keypress event, so it's a genuine release.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user