|
@@ -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;
|
|
|
|
|
-
|
|
|
|
|
- // 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(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);
|
|
|
|
|
|
|
+ // When resizing or moving the window, multiple ConfigureNotify
|
|
|
|
|
+ // events may be sent in rapid succession. We only respond to
|
|
|
|
|
+ // the last one.
|
|
|
|
|
+ configure_event = event.xconfigure;
|
|
|
|
|
+ got_configure_event = true;
|
|
|
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.
|