Pick the W32 API for possible deadkey+<something> combinations
and prefer these to other sources of deadkey combos.
Specifically, if W32 API supports at least one combo for a particular
deadkey, only use that data and do not attempt to do other, unsupported
combinations, even if they make sense otherwise.
This is needed to, for example, correctly support US-International
keyboard layout, which produces a combined character for <' + a>
combo, but not for <' + s>, for example.
This is achieved by stashing all the deadkeys that we find in
an array, then doing extra loop through all virtual key codes and
trying to combine them with each of these deadkeys. Any combinations
that produce a single character are cached for later use.
In GTK Simple IM context, call a new GDK W32 function to do a lookup
on that cached combination table early on, among the "special cases"
(which are now partially obsolete).
A limitation of this code is that combinations with more than
one deadkey are not supported, except for combinations that consist
entirely of 2 known deadkeys. The upshot is that lookups should
be relatively fast, as deadkey array stays small and the combination
tree stays shallow.
Note that the use of ToUnicodeEx() seems suboptimal, as it should
be possible to just load a keyboard library (KBD*.DLL) manually
and obtain and use its key table directly. However, that is much more
complicated and would result in a significant rewrite of gdkkeys-win32.
The code from this commit, though hacky, is a direct addition to
existing code and should cover vast majority of the use-cases.
https://bugzilla.gnome.org/show_bug.cgi?id=569581
This changes the group/level semantic.
Previously W32 backend used "group 0/1" to denote "AltGr OFF/ON"
and "level 0/1" to denote "Shift is OFF/ON".
Now "group" means "keyboard layout" and there can be up to 255 groups,
while AltGr and Shift are combined into a single level enum that
takes values between 0 and 4.
Unlike X, W32 doesn't do effective group overriding, meaning that
it will never tell the caller that a different group was actually
used (even for universal keys, such as Enter), because key symbol
table is completely fabricated and there's no point in trying to
save a few of kilobytes of RAM by not duplicating universal key
records for all groups.
Also contains many whitespace changes (tab elimination, fixed
indentation) and cleanup (axed a few global variables, these are
now accessed via the default keymap).
https://bugzilla.gnome.org/show_bug.cgi?id=768722
WINBOOL is MinGW-specific, so change it to BOOL, which is universally
available.
Also, Visua Studio is more picky on where __stdcall (WINAPI) is placed, so
fix that to be in-sync with what is done in the other sources.
Always associate a drag context with a GdkDisplay and use that when
getting a cursor for a given action.
If we don't do this, dragging on a window that doesn't use the default
display will make us use cursors from the wrong display.
https://bugzilla.gnome.org/show_bug.cgi?id=765565
Windows save in hardware_keycode an information which is not so low
level and some application require the hardware scancode.
As Windows provides this information save it in GdkEventPrivate
and provide a function to get this information.
For no Windows system the function return the hardware_keycode instead.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
https://bugzilla.gnome.org/show_bug.cgi?id=765259
MoveWindow should not be used over the pre-existing move/resize
functions, which already correctly position a window with respect
to its parent, while also taking into account the size of window
decorations.
https://bugzilla.gnome.org/show_bug.cgi?id=765100
gdk_window_reparent() already changes children list for old and new parent.
Doing so twice results in a circular reference in the list, which can hang
the application later, for example in gtk_window_show().
https://bugzilla.gnome.org/show_bug.cgi?id=764845
This makes usage of _gdk_display again when creating a window.
This is needed because there is a window created when the display
is being initialized, so it becomes a chicken and egg problem.
For now we roll back this to fix the wintab crash but we might
want to fix this again in the future by improving the wintab
initialization.
https://bugzilla.gnome.org/show_bug.cgi?id=764664
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