Fix various window sizing issues on X11

This commit is contained in:
rdb 2015-08-22 19:16:21 +02:00
parent eecded05bd
commit 902bce01e9
2 changed files with 80 additions and 58 deletions

View File

@ -429,6 +429,7 @@ process_events() {
// inner corner, anyway, but that means we need to fix
// XConfigureWindow too.)
properties.set_origin(configure_event.x, configure_event.y);
properties.set_size(configure_event.width, configure_event.height);
if (_properties.get_fixed_size()) {
// If the window properties indicate a fixed size only, undo
@ -436,21 +437,15 @@ process_events() {
// 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()) {
// managers.)
if (configure_event.width != _fixed_size.get_x() ||
configure_event.height != _fixed_size.get_y()) {
XWindowChanges changes;
changes.width = current_props.get_x_size();
changes.height = current_props.get_y_size();
changes.width = _fixed_size.get_x();
changes.height = _fixed_size.get_y();
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;
}
@ -494,16 +489,19 @@ set_properties_now(WindowProperties &properties) {
x11GraphicsPipe *x11_pipe;
DCAST_INTO_V(x11_pipe, _pipe);
// Handle fullscreen mode.
if (properties.has_fullscreen()) {
if (properties.get_fullscreen()) {
// We're either going into or out of fullscreen, or are in fullscreen
// and are changing the resolution.
bool is_fullscreen = _properties.has_fullscreen() && _properties.get_fullscreen();
bool want_fullscreen = properties.has_fullscreen() ? properties.get_fullscreen() : is_fullscreen;
if (is_fullscreen != want_fullscreen || (is_fullscreen && properties.has_size())) {
if (want_fullscreen) {
if (_have_xrandr) {
#ifdef HAVE_XRANDR
XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
if (_orig_size_id == (SizeID) -1) {
_orig_size_id = XRRConfigCurrentConfiguration(conf, &_orig_rotation);
}
int num_sizes, reqsizex, reqsizey, new_size_id = -1;
SizeID old_size_id = XRRConfigCurrentConfiguration(conf, &_orig_rotation);
SizeID new_size_id = (SizeID) -1;
int num_sizes = 0, reqsizex, reqsizey;
if (properties.has_size()) {
reqsizex = properties.get_x_size();
reqsizey = properties.get_y_size();
@ -519,16 +517,18 @@ set_properties_now(WindowProperties &properties) {
new_size_id = i;
}
}
if (new_size_id == -1) {
if (new_size_id == (SizeID) -1) {
x11display_cat.error()
<< "Videocard has no supported display resolutions at specified res ("
<< reqsizex << " x " << reqsizey <<")\n";
_orig_size_id = -1;
<< reqsizex << " x " << reqsizey << ")\n";
} else {
if (new_size_id != _orig_size_id) {
if (new_size_id != old_size_id) {
XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), new_size_id, _orig_rotation, CurrentTime);
} else {
_orig_size_id = -1;
if (_orig_size_id == (SizeID) -1) {
// Remember the original resolution so we can switch back to it.
_orig_size_id = old_size_id;
}
}
}
#endif
@ -545,7 +545,7 @@ set_properties_now(WindowProperties &properties) {
if (_have_xrandr && _orig_size_id != (SizeID) -1) {
XRRScreenConfiguration* conf = XRRGetScreenInfo(_display, x11_pipe->get_root());
XRRSetScreenConfig(_display, conf, x11_pipe->get_root(), _orig_size_id, _orig_rotation, CurrentTime);
_orig_size_id = -1;
_orig_size_id = (SizeID) -1;
}
#endif
// Set the origin back to what it was
@ -589,8 +589,7 @@ set_properties_now(WindowProperties &properties) {
// on the fly.
// We'll pass some property requests on as a window manager hint.
WindowProperties wm_properties = _properties;
wm_properties.add_properties(properties);
set_wm_properties(properties, true);
// The window title may be changed by issuing another hint request.
// Assume this will be honored.
@ -617,6 +616,7 @@ set_properties_now(WindowProperties &properties) {
changes.y = 0;
value_mask |= CWX | CWY;
properties.clear_origin();
} else if (properties.has_origin()) {
changes.x = properties.get_x_origin();
changes.y = properties.get_y_origin();
@ -625,10 +625,21 @@ set_properties_now(WindowProperties &properties) {
properties.clear_origin();
}
// This, too. But we can't currently change out of fixed_size mode.
if (properties.has_fixed_size() && properties.get_fixed_size()) {
_properties.set_fixed_size(properties.get_fixed_size());
properties.clear_fixed_size();
_fixed_size = _properties.get_size();
}
if (properties.has_size()) {
changes.width = properties.get_x_size();
changes.height = properties.get_y_size();
value_mask |= (CWWidth | CWHeight);
if (_properties.get_fixed_size()) {
_fixed_size = properties.get_size();
}
properties.clear_size();
}
@ -656,13 +667,6 @@ set_properties_now(WindowProperties &properties) {
properties.clear_z_order();
}
if (value_mask != 0) {
XReconfigureWMWindow(_display, _xwindow, _screen, value_mask, &changes);
// Don't draw anything until this is done reconfiguring.
_awaiting_configure = true;
}
// We hide the cursor by setting it to an invisible pixmap.
// We can also load a custom cursor from a file.
if (properties.has_cursor_hidden() || properties.has_cursor_filename()) {
@ -783,7 +787,14 @@ set_properties_now(WindowProperties &properties) {
}
}
set_wm_properties(wm_properties, true);
if (value_mask != 0) {
// We must call this after changing the WM properties, otherwise
// we may get misleading ConfigureNotify events in the wrong order.
XReconfigureWMWindow(_display, _xwindow, _screen, value_mask, &changes);
// Don't draw anything until this is done reconfiguring.
_awaiting_configure = true;
}
}
////////////////////////////////////////////////////////////////////
@ -962,6 +973,11 @@ open_window() {
<< "failed to create X window.\n";
return false;
}
if (_properties.get_fixed_size()) {
_fixed_size = _properties.get_size();
}
set_wm_properties(_properties, false);
// We don't specify any fancy properties of the XIC. It would be
@ -1034,8 +1050,8 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) {
XTextProperty window_name;
XTextProperty *window_name_p = (XTextProperty *)NULL;
if (properties.has_title()) {
char *name = (char *)properties.get_title().c_str();
if (XStringListToTextProperty(&name, 1, &window_name) != 0) {
const char *name = properties.get_title().c_str();
if (XStringListToTextProperty((char **)&name, 1, &window_name) != 0) {
window_name_p = &window_name;
}
}
@ -1056,18 +1072,19 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) {
}
size_hints_p->flags |= USPosition;
}
LVecBase2i size = _properties.get_size();
if (properties.has_size()) {
size_hints_p->width = properties.get_x_size();
size_hints_p->height = properties.get_y_size();
size = properties.get_size();
size_hints_p->width = size.get_x();
size_hints_p->height = size.get_y();
size_hints_p->flags |= USSize;
if (properties.get_fixed_size()) {
size_hints_p->min_width = properties.get_x_size();
size_hints_p->min_height = properties.get_y_size();
size_hints_p->max_width = properties.get_x_size();
size_hints_p->max_height = properties.get_y_size();
size_hints_p->flags |= (PMinSize | PMaxSize);
}
}
if (properties.get_fixed_size()) {
size_hints_p->min_width = size.get_x();
size_hints_p->min_height = size.get_y();
size_hints_p->max_width = size.get_x();
size_hints_p->max_height = size.get_y();
size_hints_p->flags |= (PMinSize | PMaxSize);
}
}
}
@ -1107,18 +1124,21 @@ set_wm_properties(const WindowProperties &properties, bool already_mapped) {
SetAction set_data[max_set_data];
int next_set_data = 0;
if (properties.get_fullscreen()) {
// For a "fullscreen" request, we pass this through, hoping the
// window manager will support EWMH.
type_data[next_type_data++] = x11_pipe->_net_wm_window_type_fullscreen;
if (properties.has_fullscreen()) {
if (properties.get_fullscreen()) {
// For a "fullscreen" request, we pass this through, hoping the
// window manager will support EWMH.
type_data[next_type_data++] = x11_pipe->_net_wm_window_type_fullscreen;
// We also request it as a state.
state_data[next_state_data++] = x11_pipe->_net_wm_state_fullscreen;
// Don't ask me why this has to be 1/0 and not _net_wm_state_add.
// It doesn't seem to work otherwise.
set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_fullscreen, 1);
} else {
set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_fullscreen, 0);
// We also request it as a state.
state_data[next_state_data++] = x11_pipe->_net_wm_state_fullscreen;
// Don't ask me why this has to be 1/0 and not _net_wm_state_add.
// It doesn't seem to work otherwise.
set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_fullscreen, 1);
} else {
set_data[next_set_data++] = SetAction(x11_pipe->_net_wm_state_fullscreen, 0);
}
}
// If we asked for a window without a border, there's no excellent

View File

@ -96,6 +96,8 @@ protected:
SizeID _orig_size_id;
#endif
LVecBase2i _fixed_size;
long _event_mask;
bool _awaiting_configure;
bool _dga_mouse_enabled;