The fix for returning accurate window position lead to a regression
computing inner size in pixels. This commit resolves that by getting
inner size from the window ID winit caches and still resolving position
by climbing the window hierarchy.
Resolves#398
* x11: Support XRandR versions older than 1.5
Fixes#392
Previously, initializing the member `xrandr` of `XConnection` resulted
in a panic when symbols from XRandR version 1.5 were missing. There was
already code to handle older versions of XRandR but it was never
executed because of the panic.
The member `XConnection.xrandr` now contains only functions that can
safely be used with older versions. Additionally, this commit adds a new
member to `XConnection` of type `Option<ffi::XRandr>` that only contains
a value if version 1.5 functionality is present.
* x11: Document the xrandr* members of XConnection
Some window managers like i3wm will actually nest application windows
(like those opened by winit) within other windows to, for example, add
decorations. Initially when debugging this method on i3, the x and y
positions were always returned as "2".
The solution that other xlib abstractions use is to climb up the window
hierarchy until just below the root window, and that window must be used
to determine the appropriate position.
This patch doesn't take into account borders or the window's offset
within its parent, but it's much more usable than the original
implementation on certain WMs.
* macOS: Move the window if there is no title bar
On macOS by default windows can only be moved by clicking and
dragging on the titlebar, if we spawn a window without one we
need to set the `movableByWindowBackground` property.
Partial fix for #368
* macOS: Make moveByWindowBackground optional
Implements setting the property via WindowBuilderExt:
WindowBuilder::new()
.with_decorations(false)
.with_movable_by_window_background(true)
* Update CHANGELOG
This was previously hardcoded to 1.0. The values for physical size in
millimeters and pixel counts on each axis are used to compute the dpi
per monitor.
The `CursorMoved` events that are used to send position updates alongside `Focused` and
`CursorEntered` events were using incorrect values for the window ID. This is a direct
result of the X11 backend being hard to understand, as those values came from variables in
the top-level scope of the function, which one would assume to be valid throughout the
entirety of their scope. In reality, their validity is dependent on the event belonging to
the `XEvent` union, so very surprising things can happen if those variables are read in the
case of XInput2/XKB/etc. events. To prevent future accidents, the aforementioned variables
have been removed, and are now defined per-event instead.
Additionally, the `CursorMoved` event sent alongside `Focused` now uses the correct device
ID; it previously used the ID of a master keyboard, but now uses the ID of the pointer
paired to that keyboard. Note that for those using multi-pointer X, the correctness of this
ID is dependent on the correctness of the window manager's focus model.
This has been stubbed on all platforms other than X11. The X11 implementation has also been
revised to toggle correctly, as it was previously only able to remove decorations.
Fixes#256
`get_xlib_window` and `get_xlib_screen_id` previously returned `Option<*mut c_void>` by
casting integer IDs into pointers, which while producing no functionality issues, is
semantically incorrect and rather surprising. Worse still, the docs for `get_xlib_window`
stated that it was in fact a valid pointer.
Additionally, now all `unix::WindowExt` methods return `std::os::raw` types rather than
`libc` types; note that the two versions of `c_void` are not interchangeable in the eyes of
the compiler, so those wanting the `libc` type will need to explicitly cast.
This is a breaking change, and will require some trivial changes to glutin.
Previously, the maximization hints were being sent as two separate client messages: one for
horizontal, and one for vertical. That resulted in the window only being maximized
horizontally (at least with my WM). The corrected client message sets both of these hints at
once.
In the process of implementing that, the relevant components were refactored to use the util
module, as we gradually move towards a hopeful future of a more readable X11 backend.
Fixes#282
Some tiling window managers (i3, dwm, etc.) determine how a window should behave based on
its name. If the name is set after mapping, then window managers will check the name before
we set it, followed by them detecting it as a change when the name is actually set. That
results in the window briefly behaving in an unexpected way, followed by a rapid switch to
the expected behavior.
In accordance to section 4.1.2 of ICCCM, the name, decorations, size hints, and window
deletion redirection have all been moved up to be set before mapping.
* Update mouse pos after cursor enter event
* Update mouse position on windows focus
* Send device_id
* Update other device id
* Fix windows import
* Remove deque for vec
* Just send event
* Use correct push_back method
* Push correct event
* Explicit mouse-related DeviceEvents
This makes the API more intuitive for common use-cases and allows us
to better propagate platform knowledge of motion semantics.
* Improve event naming consistency
* Clarify axis event forwards-compatibility
* Rename WindowEvent::MouseMoved/Entered/Left to CursorMoved/...
This emphasizes the difference between motion of the host GUI cursor,
as used for clicking on things, and raw mouse(-like) input data, as
used for first-person controls.
* Add support for windows and OSX, fix merging
* Fix warnings and errors on Linux
* Remove unnecessary breaking changes
* Add MouseWheel events to windows and OSX
* Fix bad push call.
* Fix docs, naming, and x11 events
* Remove mutability warning
* Add changelog entry
* wayland: upgrade wayland-window
This new version of wayland window considerably simplifies the
window handling for winit, meaning much of the previous juggling
is no longer needed, and the windows will appear even if nothing is
drawn.
* wayland: cleanup unused stuff
* Fix no primary monitor panic in XWayland
In this case try to use the first existing monitor instead of panicking.
Fixes#317
* Shift no monitor panic to x11::get_primary_monitor
* Update changelog with xll get_primary_monitor fallback
* Implement public API for high-DPI #105
* Recover get_inner_size_points and get_inner_size_pixels and change their implementation assuming get_inner_size() returns size in pixels
* Update changelog for high-DPI changes
This should trigger the compositor's mechanism for sending a
configure event, which should most of the time be processed
before any winit user actually tries to draw.
* Add an i386 target to travis
* Fix X11 on 32bit architectures
One would hope 32bit X11 was dead by now but apparently not :). Fix
the window hint setting code to not assume window IDs are 64bit as
apparently they are not in 32bit arches.
* wayland: don't create a second event_queue
As each EventsLoop has its own context, this is no longer necessary.
* wayland: buffer events rather than direct dispatch
Changes the behavior of the event loop to first internally
buffer the events generated by the wayland handlers, and then
dispatch them to the client's closure.
- It simplifies the event loop logic
- It makes it possible for the user to call window methods such as
`set_title()` or `set_inner_size()` without causing a deadlock
* wayland: add is_ready() & fix protocol errors
Adds a `is_ready()` method to the windows to advertize
when it is legal to start drawing, and fix a few wayland
protocol mishandling in the process.
* partial implementation for emscripten
this pull request contain a partial but working implementation of emscripten backend
some implementations may be controversial.
here some implementation detail:
* cursor state:
* on grab: emscripten request pointer lock deferred and also set a callback when pointer lock change
the callback request pointer lock deferred.
* on hide: `emscripten_hide_mouse` exist but not `emscripten_show_mouse`
a pull request has been open on october 2016 but never been merged
so I copied the javascript function and put it in emscripten_asm_const function
* fullscreen: if fullscreen is requested then it request fullscreen deferred and set a callback on fullscreen change
the callback request fullscreen deferred
* run forever: this method use emscripten main loop to run an infinite loop
* keyboard callback doesn't consume the event. I think it is more apopriate as in desktop environment it is the same, is it ?
* emscripten dir is added in example and contains html pages
Some things that are not implemented:
* lots of events
* min and max dimension can be implemented with a callback that listen to size change and resize if dimension out of bound
* title may be implemented using javascript to change document.title
* Use std::os::raw in the emscripten bindings
* Fix emscripten code
* Update code
* Add CI
* Remove the emscripten-specific examples
* Add some information to the README
* Fix X11 screen resolution change using XrandR
The previous XF86 resolution switching was broken and everything
seems to have moved on to xrandr. Use that instead while cleaning
up the code a bit as well.
* Use XRandR for actual multiscreen support in X11
* Use actual monitor names in X11
* Get rid of ptr::read usage in X11
* Use a bog standard Vec instead of VecDeque
* Get rid of the XRandR mode switching stuff
Wayland has made the decision that apps shouldn't change screen
resolutions and just take the screens as they've been setup. In the
modern world where GPU scaling is cheap and LCD panels are scaling
anyway it makes no sense to make "physical" resolution changes when
software should be taking care of it. This massively simplifies the
code and makes it easier to extend to more niche setups like MST and
videowalls.
* Rename fullscreen options to match new semantics
* Implement XRandR 1.5 support
* Get rid of the FullScreen enum
Moving to just having two states None and Some(MonitorId) and then
being able to set full screen in the current monitor with something
like:
window.set_fullscreen(Some(window.current_monitor()));
* Implement Window::get_current_monitor()
Do it by iterating over the available monitors and finding which
has the biggest overlap with the window. For this MonitorId needs
a new get_position() that needs to be implemented for all platforms.
* Add unimplemented get_position() to all MonitorId
* Make get_current_monitor() platform specific
* Add unimplemented get_current_monitor() to all
* Implement proper primary monitor selection in X11
* Shut up some warnings
* Remove libxxf86vm package from travis
Since we're no longer using XF86 there's no need to keep the package
around for CI.
* Don't use new struct syntax
* Fix indentation
* Adjust Android/iOS fullscreen/maximized
On Android and iOS we can assume single screen apps that are already
fullscreen and maximized so there are a few methods that are implemented
by just returning a fixed value or not doing anything.
* Mark OSX/Win fullscreen/maximized unimplemented()!
These would be safe as no-ops but we should make it explicit so
there is more of an incentive to actually implement them.
* Don't use UNIX_BACKEND in Window2::new
* Move get_available_monitors and get_primary_monitor to EventsLoop
* Remove UNIX_BACKEND
* Restore choosing the Linux backend
* Return a XNotSupported for new_x11()
* Fix fullscreen example
* Rework MonitorId::get_native_identifier
* Try fix compilation
* Returns the monitor ID on wayland as well
* Try fix compilation
* Fix iOS compilation
Use the enum to make a single fullscreen API that's much more
consistent. Both set_fullscreen() and with_fullscreen() take the
same enum and support all the variations so you can build the window
however you want and switch between the modes at runtime.
There are two kinds of fullscreen. One where you take over the whole
output the other where you just set the window size to the screen
size and get rid of decorations. The first one already existed,
implement the second which is more common for normal desktop apps.
Use an enum to consolidate all the fullscreen states.
When X's evdev input module is configured to emulate scroll events (as
used with e.g. trackpoints), it generates non-emulated scroll button
presses and does not generate motion events. This is contrary to the
behavior of all other hardware I've tested, and contrary to the
behavior of libinput, but nonetheless should be supported.
X11 always return the geometry in pixel units. Since
window.get_inner_size returns the size in points in other window manager
implementations X11 should also return in points instead of pixels.
This removes the need for the EventsLoop::interrupt method by inroducing
a ControlFlow type. This new type is to be returned by the user's
callback and indicates whether the `EventsLoop` should continue waiting
for events or break from the loop.
Only the wayland, x11 and api_transition backends have been updated so
far, and only the wayland backend has actually been tested.
X11 and Wayland implementations are now half implemented, however both
still do not correctly break from the inner blocking event dispatch
functions when `wakeup` is called, which they should do.
This commit only updates the top-level API to get some early feedback.
None of the platform-specific code has been updated yet. I'm hoping to
get around to this over the next couple days however if someone more
familiar with the windows backend would like to do a PR against this
fork that would be a great help.
Closes#187.
If the interrupted flag were set going into poll_events, it would only
ever handle the first event in the queue. Now, the flag is reset at the
start so events are processed until the caller requests otherwise.
This is the same behavior as with WindowProxy::wakeup_event_loop in
previous versions.
Unfortunately, `EventsLoop::interrupt` is also the recommend way to exit
a `run_forever` loop from within the event handler callback. Pushing an
extra event on the queue in that case is simply wasteful. Changing this
would require a refactor taking one of two possible forms:
1. Add a method *in addition* to interrupt intended for waking up the
event loop
2. Add a return type to the event callback like
enum Continue { True, False }
which would be used in lieu of the atomic interrupt flag.
It was only processing a single event per call. The docs say
> Fetches all the events that are pending, calls the callback function
> for each of them, and returns.
which suggests that was incorrect.
All platforms should now receive events in the following order:
1. KeyboardInput(ElementState::Pressed, ..)
2. ReceivedCharacter
3. KeyboardInput(ElementState::Released, ..)
cc https://github.com/tomaka/glutin/issues/878
ICCCM 4.1.2.5 (https://tronche.com/gui/x/icccm/sec-4.html#WM_CLASS)
states that:
> This property must be present when the window leaves the Withdrawn
> state and may be changed only while the window is in the Withdrawn
> state.
Previously, we would first map the window, and then set these
properties, causing sadness for window managers (#167,
tomaka/glutin#879). This patch changes that by setting the class and
name attributes immediately after the window is created, and before it
is mapped.
Fixes#167.
This expands input events to represent sub-pixel mouse positions, devices responsible for generating events, and raw
device-oriented events. The X11 back end is refactored to make full use of the new expressiveness. Other backends have
had new functionality minimally stubbed out, save for the macos backend which already supports sub-pixel mouse
positions.
Previously, if a `Window` was `Drop`ped while open, the window would
remain open until the user pressed the x button. This fixes the
behaviour so that the window is closed when dropped if it has not
already been closed.
This can happen when window is destroyed/created during a call to user
callback as this causes WindowDelegate method to be called.
Instead if the user callback is `None` store the event in
`pending_events`.
* Remove NSTitledWindowMask for windows with no decorations. This
makes sure that they do not have a title bar.
* Transparency is not be taken into account as we could have a window
with a titlebar or without that is transparent.
Making applications track modifier keys results in unnecessary work for
consumers, it's error prone, and it turns out to have unavoidable bugs.
For example, alt-tabbing with x11 results in the alt modifier state
getting stuck.
To resolve these problems, this patch adds a Mods value to the keyboard
input event.
Based on this patch: d287fa96e3
WaitEventsIterator implements waiting by first calling XPeekEvent which
will block until at least 1 event is queued, and then it delegates to
PollEventsIterator to actually handle the new event. PollEventsIterator
was previously picky about which events it would process. Events of
other types would get stuck at the head of the X event queue, and
PollEventsIterator would return None. This initiated a busy loop in the
WaitEventsIterator because it would XPeekEvent, see that something is
there, and then PollEventsIterator would return None, and the process
would repeat.
This is resolved by using XNextEvent in the PollEventsIterator instead
of XCheckTypedEvent. Any event in the queue will be popped. Even if
winit isn't interested in the event, this means XPeekEvent will block
again to wait for another event instead of the previous behavior.
the NSApplication is in focus.
This NSEvent produces an undocumented NSEventType value `21` that has no
associated variant within the cocoa-rs crate's `NSEventType` enum, thus
causing a segfault when attemptingt to match on the value.
This commit adds a check for `21` to avoid the segfault.
This fixes#104.
Fix issue where key window would lose all mouse events once mouse left
that window.
Make sure that only window under mouse receives mouse scroll wheel
events.
invariants
This also removes the need for "box"ing the callback in favour of
storing a raw `*mut` pointer. We can do this by ensuring that we never
store the pointer for longer than the lifetime of the user callback,
which is the duration of a call to `poll_events` or `run_forever`.
Also removes old commented out event code from the window module.
This is a follow up to the new API introduced in #20.
This also fixes the issue where window resize events would not be
emitted until the end of the resize. This PR fixese #39 by ensuring that
the user callback given to either `EventsLoop::poll_events` or
`EventsLoop::run_forever` can be called by each window delegate's resize
callback directly.
This tracks resizes separately, and synthesizes them for the event iterators as needed, so that OS X apps don't generate a whole set of resize events after each resize.
These events are batched, and delievered en masse at the end of the resize. This isn't a great developer experience (and it should probably be called out in the docs), but it makes it possible for winit client applications to detect and respond to resizes without special-casing Mac OS targets.
See #39. This is only a partial fix, and does not provide on-the-fly resize events.
This fixes propagation of Event::Awakend from wakeup_event_loop() when
using poll_event() on macOS.
Currently wait_event() translates all unknown events into
Event::Awakened so doesn't need the explicit translation.
This allows for passing the window_resize_callback fn during the window
building stage. More importantly, this allows setting the callback
without the need for mutable access to the Window, making it possible
to set the callback in the downstream glium crate.
This may solve tomaka/glium#1232 for most folk.
Due to XCB and Xlib compability, we can take a shortcut and use X11's
underlying xcb_connection. This way, a complete XCB backend implementation can
be avoided.
This removes all EGL-specific code from the wayland backend.
Notable unresolved question: due to wayland design, the resizing
methods will only get/set the size of the drawn borders, not of the
actual content drawn. This latter size cannot be controlled by winit.
1. Make it non failing. Before we tried to call XFreeCursor with a
cursor of 0 if we couldn't find a cursor. This has then caused a panic.
2. Introduce a system where multiple special cursors are tried
in order to work with different themes and desktop environments.
This way we get less often into the situation where we have to use a
default cursor.
3. Also set names for some cursors that previously only had a placeholder.
Fixes#765.
Will fix https://github.com/servo/servo/issues/10475 as well.
Despite the fact that the style mask contains `NSTitledWindowMask`, the
title doesn't show up for two reasons: (a) we draw over it; (b) we make
it invisible with a call to `-[NSWindow setTitleVisibility:]`.
Addresses servo/servo#9856 and servo/servo#9878.
Partially addresses servo/servo#9812.
Size hints are only being set for non-fullscreen windows, if
`max_dimensions` are set they'll override the normal `dimensions`
since X11 will not automatically resize the window after setting
the size hints.
`PSize` hint is currently set along with the `min/max` hints for
good measure.
Fixes#697
It seems that `XSync` doesn't really makes the window viewable.
This feels hacky, other option to do it could be using `XIfEvent` or
similar to listen to `MapNotify` events, but we'll have a loop still.
In practice, this lasts between two and thre iterations on my machine,
which is something not noticeable.
Regression introduced in 47df0e9eaa
Casting fullscreen_atom (which is the result from XInternAtom, i.e.
c_ulong) as i64 is obviously wrong -- the whole point of types such as
c_ulong is that long in C does *not* always have the same bit size...
Cast it as c_long instead.
While this is the most straightforward fix, I'm not sure it's the best
one: perhaps the x11 crate should offer a set_ulong() method along with
set_long(), which could be used here instead of the cast?
Previously, the function would actually set the outer size of the window
instead of the inner size.
We fix this by first letting windows calculate the outer size based upon
the specified inner size.
From the "Smooth Scrolling" section of [XI2Proto.txt][1]:
> One unit of scrolling in either direction is considered to be equivalent to
> one button event, e.g. for a unit size of 1.0, -2.0 on an valuator type
> Vertical sends two button press/release events for button 4. Likewise, a
> button press event for button 7 generates an event on the Horizontal
> valuator with a value of +1.0. The server may accumulate deltas of less than
> one unit of scrolling.
From [What's new in XI 2.1 - smooth scrolling][2]:
> The increment defines what delta the driver considers to be one scroll
> event. For an increment of +5, each delta of 5 should be regarded as one
> scroll unit down. For an increment of -3, each delta of 3 should be regarded
> as one scroll unit up (i.e. inverted).
[1]: http://www.x.org/releases/X11R7.7/doc/inputproto/XI2proto.txt
[2]: http://who-t.blogspot.com/2011/09/whats-new-in-xi-21-smooth-scrolling.html
This fixes scrolling with my Microsoft mouse in X11 on Debian 8.1.
wait_event used to call nextEventMatchingMask twice. Once with untilDate:distantFuture,
and dequeue:NO to wait until the next event but witout consuming it, and again with
untilDate:distantPast and dequeue:YES to retrieve the event (via poll_events).
For some reason, with osx 10.11, calling nextEventMatchingMask with dequeue:NO never
returns if the user scrolls, freezing the app.
So we now call nextEventMatchingMask only once, with dequeue:YES.
Integrate with wayland-window crate to draw decorations
allowing resize & move of the window.
Leaving the wayland backend as disabled until full usability
is ensured.
fixes#314 for me.
I've "tested" change by running examples (which prior to change simply
crashed), but since I did not run those examples successfuly ever before,
I don't know whether they worked as intended.
XInput2 has a concept of master and slave devices,
where a slave device is the actual physical device,
attached to a master device representing the cursor or keyboard
focus.
See http://who-t.blogspot.co.uk/2009/05/xi2-recipes-part-1.html
Mouse events were being received from both the master and slave
devices, but we are only interested in events from the master device.
Fixes#533
* Fix an issue where PollEventsIterator::next() would fail to return
keyboard input and mouse events immediately but instead only
return them on the next call to next()
* Inline process_generic_event() and queue_event()
Scroll deltas are calculated in X11 by comparing the current and
previous absolute values for the scroll axis when a scroll motion
event is received. If the user scrolls whilst the cursor is outside
of the window then an incorrect delta is reported when the cursor
re-enters the window.
Fix this by resetting the last-seen axis values whenever the cursor
re-enters the window.
* For the moment we're still using plain core X11 events
for handling keyboard activity, so remove the XInput2 code for that
* Small refactoring of X11 input handling and documentation fixes
Depending on the platform and device, scroll deltas may either
be represented as pixel deltas specifying the amount
in pixels to scroll or they may be expressed in 'lines' or 'chunks'
for low resolution devices (eg. a traditional mouse wheel).
Pixel deltas are currently available on OS X. X11 currently
supports only integer line deltas, though pixel deltas
are available via XInput2. Windows supports fractional
line deltas.