This fixes a bug that was introduced by db1b24233e.
The reason why 0:0 coordinates were passed was that SWP_NOREPOSITION was
misinterpreted as SWP_NOMOVE. That is not the case - SWP_NOREPOSITION
prevents owner Z-order change, not the window position change.
Currently only one kind of decorative window is in use - the shape
indicator that is shown when snapping windows to the edge of the screen.
When normal toplevel class is used, its window procedure expects certain
motions from GDK (passing user data to CreateWindowEx(), registering
handle in a hash map etc), and might crash if that is not done.
Dumb window doesn't require anything, it can just be.
https://bugzilla.gnome.org/show_bug.cgi?id=763013
Now halfleft/halfright/fullup snaps do hug screen edges as intended.
Documents AeroSnap behaviour when snapped windows are drag-resized
(currently this implementation handles this in a very simplistic way).
Don't believe GTK when it tells us that window shadow is 0, preserve
previous values (but do remember that GTK wants no shadow, in case
we need that).
Fixes a couple of bugs in unsnapping (check offset against the half
of the window; don't put pointer in the middle of the window vertically
if it still fits in the top half).
https://bugzilla.gnome.org/show_bug.cgi?id=763013
Implements gdk_win32_window_set_shadow_width().
Uses shadow width/height to adjust max tracking size, allowing
windows to be drag-resized to cover the whole desktop.
Also uses SM_C*VIRTUALSCREEN instead of SM_C*MAXTRACK.
https://bugzilla.gnome.org/show_bug.cgi?id=763013
Indicator is a bare layered click-through native window,
painted completely by GDK, including animation.
This commit also isolates some of the more spam-ish debug logging
under ifdef.
This commit also changes the system metric used for maximal window
height for the snapping purposes. Turns out, SM_CYMAXTRACK is way
too large, use SM_CYVIRTUALSCREEN instead.
https://bugzilla.gnome.org/show_bug.cgi?id=763013
This implements the part of AeroSnap that snaps windows when you
drag them (while moving or resizing) to the edge of the screen.
It also fixes drag behaviour for snapped and maximized windows
(if such windows are dragged, first they must be unmaximized/unsnapped).
Note that this code does not take into account the shadow width, and
because of that the under-pointer-position-preserving window moves
might not look as such for maximized windows, which lack the shadow
when maximized, but do have the shadow when unmaximized.
This commit also doesn't cover some corner-cases the same way AeroSnap does.
Also, the snapping indicator (which is supposed to be a window shape that
shows where the window will be if the drag op is stopped at its current
point) is not being drawn, all routines responsible for its creation,
moving and drawing are stubs.
https://bugzilla.gnome.org/show_bug.cgi?id=763013
This is what AeroSnap does. If a window is being unsnapped on
a new monitor, check if the work area is large enough for the
window to fit in its normal size. If the window fits, just
reposition it so that the ratio of
left-window-edge-to-screen-edge / right-window-edge-to-screen-edge
remains the same, without scaling the window.
https://bugzilla.gnome.org/show_bug.cgi?id=763013
It works exactly like AeroSnap.
Except for shift+win+left/right, which is left for AeroSnap
to handle (AeroSnap takes action before we get the message,
so there's no way for us to override it).
The only thing that doesn't work is shift+win+left/right on
a maximized window, for reasons unknown at the moment.
This only implements winkey+stuff behaviour of AeroSnap,
not the drag-to-the-edge-and-something-funny-happens one.
https://bugzilla.gnome.org/show_bug.cgi?id=763013
If a layered window was hidden and is made visible, erase its
contents before showing it. GDK will schedule a redraw, but until
then we generally don't want to show old contents.
https://bugzilla.gnome.org/show_bug.cgi?id=763783
This is achieved by sending undocumented message WM_SYSMENU
to the window.
Before doing that, the window is given WS_SYSMENU style
(to enable window menu) and some combination of
WS_MAXIMIZEBOX (for "Mazimize" item)
WS_MINIMIZEBOX (for "Minimize" item)
WS_SIZEBOX (for "Size" item)
depending on which operations are currently permissible.
WM_SYSMENU is processed by DefWindowProc(), which results
in showing the window menu. We remove extra styles
at the first opportunity (WM_INITMENU message), as they
alter the way our window is rendered.
https://bugzilla.gnome.org/show_bug.cgi?id=763851
Delay as long as possible before calling OpenClipboard(),
call CloseClipboard() as quickly as possible after that.
Don't call OpenClipboard() when we don't need to (for example,
we don't need to open clipboard to call GetClipboardOwner()).
Also, print out actual W32 error code in some cases where it
was not printed before.
https://bugzilla.gnome.org/show_bug.cgi?id=763907
Error codes can be easily looked up in an error code list
and/or googled up. Error messages, while descriptive, often
describe the wrong thing, and the messages themselves are not
part of the documentation of a function, unlike error codes.
It would be preferable to have the code, or both.
https://bugzilla.gnome.org/show_bug.cgi?id=763913
Using UpdateLayeredWindow() on iconic windows brings them *back* from
their iconic (minimized) state. That is bad.
As a precaution, also don't use SetWindowPos() on iconic windows.
This means that iconic windows can't be moved. That is fixable
by using SetWindowPlacement(), but there is no pressing need to do so,
as there are very few cases when windows need to be moved while minimized.
https://bugzilla.gnome.org/show_bug.cgi?id=763835
Two errors here:
1) A typo in splashscreen rectangle calculation - sets right twice
instead of setting top
2) Centering for dialogs is off because it doesn't convert
GDK virtual desktop coordinates to Windows WM virtual desktop
coordinates by adding _gdk_offset_*
https://bugzilla.gnome.org/show_bug.cgi?id=763628
This code:
> gdk_window_get_root_origin (window, &x, &y);
> x -= root_x;
> y -= root_y;
> pointer_window = gdk_device_get_window_at_position (device, &x, &y);
was meant to find the child gdk window at coordinates root_x and root_y.
These 4 lines had 2 bugs:
1) x = x - root_x (same for y) is wrong, it should be x = root_x - x
2) gdk_device_get_window_at_position() does not give you the window
at position x and y. It gives you the window under the device
(mouse pointer) and the returns the device coordinates in x and y.
https://bugzilla.gnome.org/show_bug.cgi?id=763533
Other portions of the GDK-Win32 backend make use of this function as
layered windows need to be disabled for GL windows and possibly other
parts, so make this function a private function that is available within
the backend.
https://bugzilla.gnome.org/show_bug.cgi?id=763285
Layered windows and GL do not work well together, so disable layered
windows when initiating a GdkGLContext, so that GtkGLArea programs can run
properly.
Also based on patch by LRN to address the issue.
https://bugzilla.gnome.org/show_bug.cgi?id=763080
This removes the event_poll_fd global variable and the (ab)use of
get_default_display. It is also more consistent with other backends.
Also store display
Otherwise WM-dependent default cursor is used, which does not
match our theme. Worse, later GDK will realize that we have
our own left_ptr cursor and will apply it after all, making
the discrepancy even more noticeable.
https://bugzilla.gnome.org/show_bug.cgi?id=762902
* Explicitly grab the device, setting appropriate cursor on it.
* Fix gdk_device_virtual_set_window_cursor() to just set the
cursor, without trying to check that mouse is over the given
window. Also prevent it from immediately resetting cursor.
* Alse take into account things that happen in other parts of
GDK - don't look for replacement cursor, GDK already did that,
and don't create a default arrow cursor instead of NULL,
GDK-W32 already did that up the stack as well.
Warn about inappropriate cursor == NULL argument instead.
https://bugzilla.gnome.org/show_bug.cgi?id=762711
Toplevels are now true layered windows that are moved,
resized and repainted via UpdateLayeredWindow() API call.
This achieves transparency without any extra effort,
and prevents window size and window contents desychronization
(bug 761629).
This also changes the way CSD windows are detected. We now
use window decorations to detect CSDiness of a window,
and to decide whether a window should be layered (CSD windows should
be) or not.
Decorations are now stored in the window implementation,
not as a quark-based property of the window-as-gobject.
https://bugzilla.gnome.org/show_bug.cgi?id=748872
Normally works only on CSD windows, non-CSD windows continue
to use WM modal loop for drag-resizing and drag-moving. However,
if it is activated on non-CSD windows, it does work.
Has the advantage of being completely immune to AeroSnap.
AeroSnap only worked partially on CSD windows, with the only part
that worked being "don't let users drag window titlebar outside of
the desktop". Now AeroSnap doesn't work on windows moved by
this code at all, which is good, since they currently don't work
well with it due to the way shadows are drawn.
It's possible to also re-implement AeroSnap (or something similar),
but that is a story for another commit.
This code was originally intended to fix the problem of window
size and window contents desynchronization, but failed to achieve
that result in the end. Nevertheless, it serves as a foundation for
other changes to the way window resizing works.
https://bugzilla.gnome.org/show_bug.cgi?id=761629
gdk_display_list_devices is deprecated and all the backends
implement the same fallback by delegating to the device manager
and caching the list (caching it is needed since the method does
not transfer ownership of the container).
The compat code can be shared among all backends and we can
initialize the list lazily only in the case someone calls the
deprecated method.
https://bugzilla.gnome.org/show_bug.cgi?id=762891
Except for the init function, all the visual related code is made
of gdkscreen vfuncs, so let's move it to gdkscreen-win32. This way
we avoid keeping other static variables and instead store the info
inside the screen struct.
1f74f12d9 rendered entry of keypad decimal mark unuseable for
several national keyboard layouts, this commit amends that, at
least for W32, and makes GTK+ behave more or less the same way
W32 behaves.
The patch works like this:
- When typing the first character at the keyboard or when switching
keyboard layouts, the decimal mark character will be cached in the
static variable "decimal_mark" within gdkkeys-win32.c
- in case of WIN32, gdk_keyval_to_unicode() asks gdkkeys-win32.c for the
current decimal_mark when converting GDK_KEY_KP_Decimal.
https://bugzilla.gnome.org/show_bug.cgi?id=756751
1) MSDN says that the coordinates of the maximized window
must be specified as if the window was on the primary display,
even if nearest display where it ends up is not the primary display.
So instead of using nearest display work area verbatim,
use it only to account for taskbar size, while using
primary display top-left corner (0:0) as the reference point.
2) MSDN says that max tracking size is a system property, we
should just call GetSystemMetrics() and use that.
https://bugzilla.gnome.org/show_bug.cgi?id=762629