When a passive touch grab is rejected over the frame, management is punted to
the frame itself, and pointer events emulated, but the attempt to transfer the
grab from the GDK connection to the Clutter one fails with AlreadyGrabbed, and
will fail until the Clutter connection receives the XI_TouchEnd resulting from
XIRejectTouch, gotten after the XI_ButtonPress on the GDK connection.
In order to bypass this shortcoming, store the current grab operation on the
frame as long as the button is pressed, so it is retried once on the next
motion event happening during frame dragging, that will have a recent enough
timestamp to succeed. If no grabbing succeeded, the current grab operation
data will be reset on GDK_BUTTON_RELEASE.
Designers got used to RGBA support in GTK+, so the colors we pick
up from there might well have an alpha channel; update our gradient
rendering to support this - eventually we should probably port that
code to cairo ...
Since GTK+ already clips to the extended region for us, there's no need
to combine the two. This does lose the fast-path, but I don't actually
expect this to fire, as when we're composited, we really won't ever get
partial exposes.
mutter is quite bad at using GTK+ correctly, relying on dumb things
like the single-buffering stuff. Hack up a temporary fix for the
newer GTK+ rendering changes.
While the comment claims that we may want to keep this around
for optimization purposes, the operations are raw bitmap operations
that would be cleaner done in cairo.
https://bugzilla.gnome.org/show_bug.cgi?id=662962
prelit_control is used for both prelight and pressed states, so the early
return in update_prelit_control() misses the case where prelit_control
already matches the control we are updating, but its state is PRESSED
rather than PRELIGHT. Fix the condition to not have pressed controls
linger around erroneously.
https://bugzilla.gnome.org/show_bug.cgi?id=731058
Since window menus have been moved to the compositor, the pressed
state of the corresponding window buttons is messed up, as it is
reset immediately when getting a LeaveNotify event due to the
compositor taking a grab. Fix this by ignoring that particular
event.
https://bugzilla.gnome.org/show_bug.cgi?id=731058
When opening the window menu without an associated control - e.g.
by right-clicking the titlebar or by keyboard - using coordinates
for the menu position is appropriate. However when the menu is
associated with a window button, the expected behavior in the
shell can be implemented much easier with the full button geometry:
the menu will point to the center of the button's bottom edge
rather than align to the left/right side of the titlebar as it
does now, and the clickable area where a release event does not
dismiss the menu will match the actual clickable area in mutter.
So add an additional show_window_menu_for_rect() function and
use it when opening the menu from a button.
https://bugzilla.gnome.org/show_bug.cgi?id=731058
We have two different coordinate spaces here. One is the rectangle
returned by meta_window_get_frame_rect, which is called the "frame
rect" or "the window geometry", which includes visible frame borders
but not invisible frame borders. The other is "frame->rect" which
corresponds to the frame's server geometry. That is, it includes
both visible and invisible frame borders.
These two were of course the same until we introduced invisible
frame borders, and an executive decision was made to make
meta_window_get_frame_rect return the rectangle bounding the
visible portions of the frame.
As time went on, the "frame rect" turned out to be more useful when
making decisions upon, since the user often doesn't think about the
invisible window geometry as part of the window.
We already calculate what amounts to the "frame rect" in the theme
code, so just change META_CORE_GET_FRAME_RECT to consume that
directly.
Since we're going to be calling meta_window_get_frame_rect in here
soon, I'd rather it be one method call, rather than two. We can't
put it at the toplevel, since that might cause infinite recursion
(e.g. meta_core_get calls meta_window_get_frame_rect calls
meta_ui_get_frame_borders calls meta_core_get, ...)
The last commit added support for the "appmenu" button in decorations,
but didn't actually implement it. Add a new MetaWindowMenuType parameter
to the show_window_menu () functions and use it to ask the compositor
to display the app menu when the new button is activated.
https://bugzilla.gnome.org/show_bug.cgi?id=730752
We want to synchronize the button layouts of our server side
decorations and GTK+'s client side ones. However each currently
may contain buttons not supported by the other, which makes this
unnecessarily tricky.
So add support for a new "appmenu" button in the layout, to display
the fallback app menu in the decorations.
https://bugzilla.gnome.org/show_bug.cgi?id=730752
It looks weird to have Alt+Space pop up under the cursor instead
of the top-left corner of the window, and the Wayland request will
pass through the coordinates as well.
Add it to the compositor interface, and extend the
_GTK_SHOW_WINDOW_MENU ClientMessage to support it as well.
We already do it in the theme code, but not the actual WM code. Since
we include the left/right borders, it only seems fair to include the
bottom border.
This effectively makes it so that shading a window means that the
client window "slot" has 0 height.
Grab operations are now always taken on the backend connection, and
this breaks GTK+'s event handling.
Instead of taking a grab op, just do the handling ourselves. The
GTK+ connection will get an implicit grab, which means pointer /
keyboard events won't be sent to the rest of mutter, which is good.
It's been long enough. We can mandate support for these, at least
at build-time. The code doesn't actually compile without either
of these, so just consider that unsupported.
This has one regression: the basic touch support added by
Carlos Garnacho in 991c85f is now partially reverted, since
we ported to Clutter events for this. We'll need to either
port his changes to Clutter, or restructure event handling
in mutter directly.
We can't really support the Gtk+ automatic scaling, as to much
code relies on the GdkWindow and XWindow sizes, etc to match.
In order to keep working we just disable the scaling, meaning
we will pick up the larger fonts, but nothing else. Its not
ideal but it works for now.
https://bugzilla.gnome.org/show_bug.cgi?id=706388
The reason we don't simply use gdk_window_add_filter directly is
because of some twisted idea that any GDK symbol being used from
core/ is a layer violation. While we certainly want to keep any
serious GDK code out of ui/, event handling is quite important
to have in core/, so simply use a GDK event filter directly.
Currently touch events are ignored in the core event handler,
and hence dealt with within GDK. If those touch events were
emulating pointer events, GDK would attempt to convert back
those events to pointer events as the frame GdkWindow doesn't
have the GDK_TOUCH_MASK set.
This results in XI_TouchBegin events being initially processed
by GDK, converted to button events, and triggering a grab op
that subverts touch events into pointer events, so the touch
is never ever seen again by GDK. This leaves GDK in an
inconsistent internal state wrt pointer grabs, so future
pointer-emulating touches will refer to the same window forever.
Fix this by handling touch events minimally, just enough to
convert XI_TouchBegin to GDK_BUTTON_PRESS within mutter, so GDK
is bypassed for every touch event just like it is for pointer
events. This, and the XIGrabDevice() that keeps coercing pointer
events when the grab operation starts, are enough to fix window
drag and drop on touch devices.
https://bugzilla.gnome.org/show_bug.cgi?id=723552
Since the introduction of frame sync in GTK+, updates to titlebar font and
colors haven't been working because GTK+ counts on the frame clock to
do style updates, and the frame clock doesn't run for an unmapped
GdkWindow. (It's possible that GtkStyleContext changes subsequent to
the introduction of the frame clock were also needed to fully break
things.)
We actually need to map the MetaFrames GdkWindow and let the
compositor code send out the frame sync messages in order to pick up
style changes.
Hopefully no bad side effects will occur from this - we make the window
override-redirect, 1x1, and outside the bounds of the screen.
https://bugzilla.gnome.org/show_bug.cgi?id=725751
Since the introduction of frame sync in GTK+, updates to titlebar font and
colors haven't been working because GTK+ counts on the frame clock to
do style updates, and the frame clock doesn't run for an unmapped
GdkWindow. (It's possible that GtkStyleContext changes subsequent to
the introduction of the frame clock were also needed to fully break
things.)
We actually need to map the MetaFrames GdkWindow and let the
compositor code send out the frame sync messages in order to pick up
style changes.
Hopefully no bad side effects will occur from this - we make the window
override-redirect, 1x1, and outside the bounds of the screen.
https://bugzilla.gnome.org/show_bug.cgi?id=725751
Switching meta/util.h to gi18n.h was wrong, mutter is a library
and needs gi18n-lib.h, but that cannot be included from a public
header (since it depends on config.h or command line options),
so split util.h into a public and a private part.
https://bugzilla.gnome.org/show_bug.cgi?id=707897
Conflicts:
src/compositor/compositor.c
src/meta/util.h
Switching meta/util.h to gi18n.h was wrong, mutter is a library
and needs gi18n-lib.h, but that cannot be included from a public
header (since it depends on config.h or command line options),
so split util.h into a public and a private part.
https://bugzilla.gnome.org/show_bug.cgi?id=707897
We can't really support the Gtk+ automatic scaling, as to much
code relies on the GdkWindow and XWindow sizes, etc to match.
In order to keep working we just disable the scaling, meaning
we will pick up the larger fonts, but nothing else. Its not
ideal but it works for now.
https://bugzilla.gnome.org/show_bug.cgi?id=706388
Mutter previously defined display->focus_window as the window that the
server says is focused, but kept display->expected_focus_window to
indicate the window that we have requested to be focused. But it turns
out that "expected_focus_window" was almost always what we wanted.
Make MetaDisplay do a better job of tracking focus-related requests
and events, and change display->focus_window to be our best guess of
the "currently" focused window (ie, the window that will be focused at
the time when the server processes the next request we send it).
https://bugzilla.gnome.org/show_bug.cgi?id=647706
g-ir-scanner will emit more warnings regarding broken GTK-Doc
syntax in the near future, which due to --warn-error being used
would break the build:
'''
ui/theme.c:1883: Warning: Meta: missing ":" at column 20:
* @tokens_p: (out) The resulting tokens
^
g-ir-scanner: compile: gcc -Wall -Wno-deprecated-declarations ...
g-ir-scanner: link: /bin/sh ../libtool --mode=link --tag=CC gcc ...
libtool: link: gcc -o /home/dieterv/gnome.org/checkout/mutter/...
<unknown>:: Fatal: Meta: warnings configured as fatal
<unknown>:: Fatal: Meta: warnings configured as fatal
make[4]: *** [Meta-3.0.gir] Error 1
'''
https://bugzilla.gnome.org/show_bug.cgi?id=699636
This essentially just moves install_corners() from the compositor, through
the core, into the UI layer where it arguably should have been anyway,
leaving behind stub functions which call through the various layers. This
removes the compositor's special knowledge of how rounded corners work,
replacing it with "ask the UI for an alpha mask".
The computation of border widths and heights changes a bit, because the
width and height used in install_corners() are the
meta_window_get_outer_rect() (which includes the visible borders but not
the invisible ones), whereas the more readily-available rectangle is the
MetaFrame.rect (which includes both). Computing the same width and height
as meta_window_get_outer_rect() involves compensating for the invisible
borders, but the UI layer is the authority on those anyway, so it seems
clearer to have it do the calculations from scratch.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=697758
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
This makes it a bit simpler for other functions on a MetaUIFrame to
get this information.
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=697758
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
A correctly constructed GtkStyleContext must have its screen
and widget paths set. Getting the frame font caused crashes
on some systems because those were not correctly initialised.
https://bugzilla.gnome.org/show_bug.cgi?id=696814
- set GTK_STYLE_CLASS_TOOLTIP on the window, and use the same code of
GtkTooltip to paint it
- set GDK_WINDOW_TYPE_HINT_TOOLTIP and make the window non-resizable, so
it doesn't get an incorrect shadow from the WM
https://bugzilla.gnome.org/show_bug.cgi?id=692741
Since we're going to use the tooltip's rounded corners we need a little
bit more of margin (which wasn't a bad idea even with the frame).
Also, don't use GtkMisc for this anymore.
https://bugzilla.gnome.org/show_bug.cgi?id=692741
gdk_device_manager_get_client_pointer which in calls
XIGetClientPointer seems to be very slow in a XI2 world.
So use
gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID)
instead.
https://bugzilla.gnome.org/show_bug.cgi?id=693354
GtkWindow added the BACKGROUND style class to all windows, which the
CSS file selects on to set a background color for all windows. Without
this, the background color becomes undefined, and thus window frames
look like they have "glitchy" graphics.
https://bugzilla.gnome.org/show_bug.cgi?id=690317
The style context of the widget is rarely what we want. We won't
fix this to be a MetaFrames style context yet; this just changes
the internal API.
https://bugzilla.gnome.org/show_bug.cgi?id=690317
This removes our final dependency on Core Events, meaning
we can remove support code for them soon.
This commit is a bit ugly as it requires ui having a dependency on
core, but this is already a hack, so this is thus a hack inside a
hack, and two hacks make a right or however that goes.
https://bugzilla.gnome.org/show_bug.cgi?id=688779
Since GTK+ commit b1ad5c8abc2c, GtkSetting's CSS provider uses a
priority of GTK_STYLE_PROVIDER_PRIORITY_SETTINGS, which means it
will overwrite the ones we create ourselves.
Bump the priority to fix dark window decorations.
https://bugzilla.gnome.org/show_bug.cgi?id=688182
The concept of a clip region doesn't make sense now that we have anti-aliased
corners and a full alpha channel. Once the theme transition is complete,
creating a preview image with an alpha channel will be possible by passing
an ARGB surface to gtk_widget_draw(preview_widget, ...);
https://bugzilla.gnome.org/show_bug.cgi?id=676052
Since we now cache windows in the X server, we don't really need to cache
them here. Since we are redirecting windows in most cases, we're not gaining
anything except added memory usage. Additionally, remove the clip to screen
optimization - if a window is partially off-screen, we still need to draw
the entire thing as redirection means we won't get an expose event for it.
Additionally, when introducing invisible borders, something accidentally
slipped through: we were getting expose events on the invisible borders,
and they weren't in the cached pixels rect, so we were painting the theme
for them, even if we didn't actually paint anything with cairo. Make sure
to clip out the invisible borders instead of just the client rect so that
we don't draw if our expose event is on the invisible borders.
https://bugzilla.gnome.org/show_bug.cgi?id=675111
It seems that the only usage of the "widget" parameter throughout
the entire call chain was to pass between two function calls as
mutual recursion.
https://bugzilla.gnome.org/show_bug.cgi?id=671104
After the changes in style handling in GTK+, mutter's tooltips no
longer match the tooltip style used in applications. Given that
all buttons in the default layout are well-known, killing tooltips
altogether rather than fixing the styling issues looks like a valid
approach.
https://bugzilla.gnome.org/show_bug.cgi?id=645101
We were relying on GTK+ emitting GtkWidget::style-updated during
widget initialization to create the GtkStyleContexts used for
window decorations. A recent GTK+ update broke this assumption,
so do the necessary initialization ourselves.
https://bugzilla.gnome.org/show_bug.cgi?id=671796
Move preferences to GSettings, using mainly shared schemas from
gsettings-desktop-schemas.
Unlike GConf, GSettings support is not optional, as Gio is already
a hard dependency of GTK+.
https://bugzilla.gnome.org/show_bug.cgi?id=635378
The theme state used to use GtkStateType, but was ported over to GtkStateFlags,
leaving behind a broken assertion that fails when using certain Metacity
themes, for example Nodoka.
https://bugzilla.gnome.org/show_bug.cgi?id=661286
Shaded windows are assumed to be reduced to the titlebar: the
current code enforces a visible bottom border of 0 and only takes
the size of the title bar (+ invisible top border) into account
when resizing the frame. However, we still add an invisible border
at the bottom, which is than subtracted from the title bar, resulting
in shaded windows being cut off.
Fix by forcing both visible and invisible bottom borders to 0.
https://bugzilla.gnome.org/show_bug.cgi?id=659266
If we do this, then there will be invisible borders around the top of attached
modal dialogs, which is unnecessary -- they can't be resized from the top
border and just interfere with the parent dialog.
This requires changing a bit of API to help identify the type of dialog.
https://bugzilla.gnome.org/show_bug.cgi?id=657795
gtk:custom() requires a fallback color in case the GTK+ theme in use
does not define the desired color. As in general the fallback color
will approximate the intended color, there is the risk of typos going
unnoticed. To make catching these kind of errors easier, allow to ignore
the fallback color specified (and fall back to a nice shade of pink
instead) by setting an environment variable.
https://bugzilla.gnome.org/show_bug.cgi?id=656112
Just a quick little commit to help clean things up for when we add invisible
borders. Additionally, do a little housekeeping in preview-widget as well.
https://bugzilla.gnome.org/show_bug.cgi?id=644930
There were actually *two* MetaFrameGeometry structs: one in theme-private.h,
one in frame.h. The latter public struct was populated by a mix of (void*)
casting and int pointers, usually pulling directly from the data in the private
struct.
Remove the public struct, replace it with MetaFrameBorders and scrap all
the pointer hacks to populate it, instead relying on both structs being used
in common code.
This commit should be relatively straightforward, and it should not do any
tricky logic at all, just a sophisticated find and replace.
https://bugzilla.gnome.org/show_bug.cgi?id=644930
In preparation for switching to handling the output shape purely by what we
paint, stop applying a shape to the frame of the window. Even when we restore
handling the output shape, this will change the behavior with respect to input;
transparent areas between the frame and the contents will stop clicks rather
than passing them through, but that is arguably at least as expected
considering how that we decorate shaped windows with a frame all around.
https://bugzilla.gnome.org/show_bug.cgi?id=644930
meta_frames_destroy() was not safe to be called multiple times, which
was causing a crash on exit due to something else changing somewhere
that makes it get called multiple times.
https://bugzilla.gnome.org/show_bug.cgi?id=654489
The code assumed that the focus window was always the one at the
top of the window stack, which is not true if an unfocused window
has the above hint set.
Rather than fixing this assumption, rename the function to
lower_beneath_grab_window() and use the display's grab window - the
function is only used for displaying the tile previews, which means
that we want the grab window anyway.
https://bugzilla.gnome.org/show_bug.cgi?id=650661
Add an additional color type to pick up colors defined with
@define-color in the GTK+ theme's CSS:
gtk:custom(name,fallback)
(where "name" refers to the name defined in GTK+'s CSS, and fallback
refers to an alternative color spec which is used when the color
referenced by "name" is not found)
The main intent of the change is to allow designers to improve
Adwaita's dark theme variant without having to compromise on colors
which work in the light variant as well.
https://bugzilla.gnome.org/show_bug.cgi?id=648709
We now use GtkStyleContext exclusively, so it's a bit weird to store
widget state as GtkStateType and translate it always to GtkStateFlags.
Just use GtkStateFlags instead of GtkStateType.
https://bugzilla.gnome.org/show_bug.cgi?id=650586
GtkStyleContext no longer has dark/light colors GtkStyle used to
have. We already have compatibility code for them in theme.c, so
add two helper functions to make it available outside theme.c.
https://bugzilla.gnome.org/show_bug.cgi?id=650586
GdkColor is about to be deprecated, so move to GdkRGBA instead.
It might be worth considering using cairo patterns for the gradients
rather than using custom code to render gradients to a pixbuf which
is then drawn with cairo, but for now this is just a straight port
of the existing code.
https://bugzilla.gnome.org/show_bug.cgi?id=650586