Compare commits
134 Commits
wip/resize
...
3.12.0-way
Author | SHA1 | Date | |
---|---|---|---|
![]() |
eba848e8aa | ||
![]() |
71be7e8493 | ||
![]() |
7484d540cd | ||
![]() |
a55622d924 | ||
![]() |
1cfaf45389 | ||
![]() |
42491f7724 | ||
![]() |
9696e785da | ||
![]() |
0de83ebfb5 | ||
![]() |
337db2a660 | ||
![]() |
054c307353 | ||
![]() |
852589897e | ||
![]() |
46b4d6c0f0 | ||
![]() |
ab2224686a | ||
![]() |
24b08d1a36 | ||
![]() |
0808adefaf | ||
![]() |
14f424cd02 | ||
![]() |
9debd2fb0d | ||
![]() |
57359da9b4 | ||
![]() |
e67abdd3ff | ||
![]() |
ca4777f778 | ||
![]() |
76dc0ca681 | ||
![]() |
8968501031 | ||
![]() |
1b29113150 | ||
![]() |
15c59f9919 | ||
![]() |
a53e094fcd | ||
![]() |
a377a1a110 | ||
![]() |
74a1e00e30 | ||
![]() |
1c41f71eef | ||
![]() |
63350c52cc | ||
![]() |
56e8c3b625 | ||
![]() |
ce3d9fb89f | ||
![]() |
27c018ab98 | ||
![]() |
a1427c7130 | ||
![]() |
91ad92c968 | ||
![]() |
f0c7b518e6 | ||
![]() |
5fa5ace5e6 | ||
![]() |
044c06bff3 | ||
![]() |
a3ccc4fd1c | ||
![]() |
0a20f7458c | ||
![]() |
9c94f8ae47 | ||
![]() |
f940292cfe | ||
![]() |
48a36356dd | ||
![]() |
f05983be42 | ||
![]() |
dfcefd3315 | ||
![]() |
3fe755e684 | ||
![]() |
0eb86de807 | ||
![]() |
ff635bad3b | ||
![]() |
43a409dec4 | ||
![]() |
b087fce062 | ||
![]() |
420f322910 | ||
![]() |
4bf6e0ae8c | ||
![]() |
97872e70a5 | ||
![]() |
be57308663 | ||
![]() |
33f1bd96f5 | ||
![]() |
9ba49358e5 | ||
![]() |
8b2b65246a | ||
![]() |
4fdbb466e1 | ||
![]() |
da48b18188 | ||
![]() |
a5f1790828 | ||
![]() |
6efcf2526d | ||
![]() |
d6a27195d3 | ||
![]() |
8f151842fb | ||
![]() |
6f7023bc6b | ||
![]() |
63b158e4da | ||
![]() |
b3364cad3e | ||
![]() |
3502cfba34 | ||
![]() |
5cc6becb63 | ||
![]() |
ae8f21a3dc | ||
![]() |
0cdf3bd383 | ||
![]() |
3de58189c0 | ||
![]() |
5270c469a3 | ||
![]() |
7504f16e59 | ||
![]() |
cdb7947dd1 | ||
![]() |
cdfc6f5b53 | ||
![]() |
fcb2ab41b2 | ||
![]() |
f5bd7c5f50 | ||
![]() |
cb549154aa | ||
![]() |
ada9610e30 | ||
![]() |
f11bf44525 | ||
![]() |
1f15c85c00 | ||
![]() |
8b4c5459c0 | ||
![]() |
d07d5d1328 | ||
![]() |
535685742a | ||
![]() |
62e45b6d5e | ||
![]() |
3c6dd5bf6d | ||
![]() |
0f85986340 | ||
![]() |
93ac0329db | ||
![]() |
c539dfe0d7 | ||
![]() |
1502d2a79f | ||
![]() |
a9d8107c3d | ||
![]() |
a5d2c51392 | ||
![]() |
d1ea17e6a4 | ||
![]() |
b37ad66e9d | ||
![]() |
c1f15348a5 | ||
![]() |
857561baed | ||
![]() |
a44cc9ef47 | ||
![]() |
d47b7ba038 | ||
![]() |
f21312e2fd | ||
![]() |
394af33607 | ||
![]() |
7314cdac94 | ||
![]() |
81025e37ea | ||
![]() |
1bb9f1e333 | ||
![]() |
b11c75c1c9 | ||
![]() |
757b626aee | ||
![]() |
fb3df5243f | ||
![]() |
e34792d9f0 | ||
![]() |
f397c32192 | ||
![]() |
f79314d7b5 | ||
![]() |
55c61259d8 | ||
![]() |
5298cf0a3a | ||
![]() |
f1dc1a0cbc | ||
![]() |
2cf80bc647 | ||
![]() |
40c15f6e2a | ||
![]() |
a8849621c9 | ||
![]() |
49c0be11d6 | ||
![]() |
9df8e831be | ||
![]() |
84c6b2a3fa | ||
![]() |
06cd669ccb | ||
![]() |
81eb7d9537 | ||
![]() |
dd8d8e436d | ||
![]() |
d6b6b363ad | ||
![]() |
254e2e993c | ||
![]() |
c595a9c29f | ||
![]() |
dfc7f7222b | ||
![]() |
ef278eb547 | ||
![]() |
38e26e5cc3 | ||
![]() |
9773a879c3 | ||
![]() |
abd2abcde6 | ||
![]() |
a8f4651c72 | ||
![]() |
54df7934ea | ||
![]() |
9052efb0d9 | ||
![]() |
b346f98eb0 | ||
![]() |
365af53797 | ||
![]() |
bee59ec0e1 |
19
.gitignore
vendored
19
.gitignore
vendored
@@ -78,12 +78,12 @@ src/stamp-mutter-marshal.h
|
||||
src/meta-dbus-xrandr.[ch]
|
||||
src/meta-dbus-idle-monitor.[ch]
|
||||
src/mutter-plugins.pc
|
||||
src/wayland/gtk-shell-protocol.c
|
||||
src/wayland/gtk-shell-server-protocol.h
|
||||
src/wayland/xdg-shell-protocol.c
|
||||
src/wayland/xdg-shell-server-protocol.h
|
||||
src/wayland/xserver-protocol.c
|
||||
src/wayland/xserver-server-protocol.h
|
||||
src/gtk-shell-protocol.c
|
||||
src/gtk-shell-server-protocol.h
|
||||
src/xdg-shell-protocol.c
|
||||
src/xdg-shell-server-protocol.h
|
||||
src/xserver-protocol.c
|
||||
src/xserver-server-protocol.h
|
||||
doc/reference/*.args
|
||||
doc/reference/*.bak
|
||||
doc/reference/*.hierarchy
|
||||
@@ -101,3 +101,10 @@ doc/reference/meta-undocumented.txt
|
||||
doc/reference/meta-unused.txt
|
||||
doc/reference/meta-docs.sgml
|
||||
doc/reference/meta.types
|
||||
gtk-doc.m4
|
||||
intltool.m4
|
||||
libtool.m4
|
||||
ltoptions.m4
|
||||
ltsugar.m4
|
||||
ltversion.m4
|
||||
lt~obsolete.m4
|
||||
|
159
COMPLIANCE
159
COMPLIANCE
@@ -1,159 +0,0 @@
|
||||
Metacity Standards Compliance
|
||||
=============================
|
||||
$Id$
|
||||
|
||||
1) Introduction
|
||||
2) EWMH Compliance
|
||||
a. Root Window Properties
|
||||
b. Root Window Messages
|
||||
c. Application Window Properties
|
||||
d. Window Manager Protocols
|
||||
3) ICCCM Compliance
|
||||
|
||||
1) Introduction
|
||||
---------------
|
||||
|
||||
This document details metacity compliance with the relevent standards.
|
||||
The format of this document is as follows:
|
||||
|
||||
[-/+?] Hint Name/Feature Name (Version number)
|
||||
Errata/Comments
|
||||
|
||||
The first character indicates the level of compliance as follows:
|
||||
- none
|
||||
/ partial
|
||||
+ complete
|
||||
? unknown
|
||||
|
||||
The title indicates a feature or a hint in the specification, and the
|
||||
version number indicates the minimum version of the specification
|
||||
supported by metacity. Later versions may be supported if no
|
||||
incompatible changes have been made in the specification.
|
||||
|
||||
2) EWMH Compliance
|
||||
------------------
|
||||
|
||||
The EWMH, or Extended Window Manager Hints is a freedesktop.org-
|
||||
developed standard to support a number of conventions for
|
||||
communication between the window manager and clients. It builds on
|
||||
and extends the ICCCM (See Section 3). A copy of the current EWMH
|
||||
standard is available at http://freedesktop.org/Standards/wm-spec/
|
||||
|
||||
a. Root Window Properties
|
||||
-------------------------
|
||||
|
||||
+ _NET_SUPPORTED (1.3)
|
||||
|
||||
+ _NET_CLIENT_LIST (1.3)
|
||||
|
||||
+ _NET_NUMBER_OF_DESKTOPS (1.3)
|
||||
|
||||
+ _NET_DESKTOP_GEOMETRY (1.3)
|
||||
Metacity does not implement large desktops, so this is kept set to
|
||||
the screen size.
|
||||
|
||||
+ _NET_DESKTOP_VIEWPORT (1.3)
|
||||
Metacity does not implement viewports, so this is a constant (0,0).
|
||||
|
||||
+ _NET_CURRENT_DESKTOP (1.3)
|
||||
|
||||
+ _NET_DESKTOP_NAMES (1.3)
|
||||
|
||||
+ _NET_ACTIVE_WINDOW (1.3)
|
||||
|
||||
+ _NET_WORKAREA (1.3)
|
||||
|
||||
+ _NET_SUPPORTING_WM_CHECK (1.3)
|
||||
|
||||
+ _NET_VIRTUAL_ROOTS (1.3)
|
||||
Metacity does not read or set this property, but it does not use
|
||||
virtual roots to implement virtual desktops, so it complies with the
|
||||
specification.
|
||||
|
||||
+ _NET_DESKTOP_LAYOUT (1.3)
|
||||
|
||||
+ _NET_SHOWING_DESKTOP (1.3)
|
||||
|
||||
b. Root Window Messages
|
||||
-----------------------
|
||||
|
||||
+ _NET_CLOSE_WINDOW (1.3)
|
||||
|
||||
- _NET_MOVERESIZE_WINDOW (1.3)
|
||||
Metacity supports this message, but the specification is unclear on
|
||||
the layout of the detail value, and as such it is #if 0'd in the code
|
||||
|
||||
+ _NET_WM_MOVERESIZE (1.3)
|
||||
|
||||
- _NET_RESTACK_WINDOW (1.3)
|
||||
Metacity will raise or lower windows in response to this message,
|
||||
but the sibling restack modes are not supported, and it is currently
|
||||
#if 0'd in the code.
|
||||
|
||||
+ _NET_REQUEST_FRAME_EXTENTS (1.3)
|
||||
|
||||
c. Application Window Properties
|
||||
--------------------------------
|
||||
|
||||
+ _NET_WM_NAME (1.3)
|
||||
|
||||
+ _NET_WM_VISIBLE_NAME (1.3)
|
||||
Metacity does not set this property, but metacity will never display
|
||||
a name different from _NET_WM_NAME
|
||||
|
||||
+ _NET_WM_ICON_NAME (1.3)
|
||||
|
||||
+ _NET_WM_VISIBLE_ICON_NAME (1.3)
|
||||
Metacity does not set this property, but metacity will never display
|
||||
a name different from _NET_WM_NAME
|
||||
|
||||
+ _NET_WM_DESKTOP (1.3)
|
||||
|
||||
+ _NET_WM_WINDOW_TYPE (1.3)
|
||||
|
||||
/ _NET_WM_STATE (1.3)
|
||||
This property is read and updated according to the specification,
|
||||
but see caveat below.
|
||||
Metacity does not recognize separate vertical and horizontal
|
||||
maximization states. Currently metacity will do a two-dimensional
|
||||
maximization if either property is set.
|
||||
See: http://bugzilla.gnome.org/show_bug.cgi?id=113601
|
||||
Metacity doesn't implement viewports so _NET_WM_STATE_STICKY is
|
||||
unimplemented.
|
||||
|
||||
+ _NET_WM_ALLOWED_ACTIONS (1.3)
|
||||
Metacity keeps this hint up to date. The code is somewhat crufty
|
||||
and should be rewritten, though it is functional.
|
||||
See: http://bugzilla.gnome.org/show_bug.cgi?id=90420
|
||||
|
||||
+ _NET_WM_STRUT (1.3)
|
||||
|
||||
+ _NET_WM_STRUT_PARTIAL (1.3)
|
||||
|
||||
+ _NET_WM_ICON_GEOMETRY (1.3)
|
||||
Metacity uses this property to draw minimize/restore animations
|
||||
|
||||
+ _NET_WM_ICON (1.3)
|
||||
|
||||
+ _NET_WM_PID (1.3)
|
||||
|
||||
+ _NET_WM_HANDLED_ICONS (1.3)
|
||||
Metacity does not read or set this property. However, metacity
|
||||
never manages iconified windows, and so has no need to do so.
|
||||
|
||||
+ _NET_WM_USER_TIME (1.3)
|
||||
Metacity uses this property to prevent applications from stealing
|
||||
focus if supported by the toolkit.
|
||||
|
||||
+ _NET_FRAME_EXTENTS (1.3)
|
||||
If set in response to a _NET_REQUEST_FRAME_EXTENTS message received
|
||||
prior to the window being mapped, this may be an estimate. This is,
|
||||
however, expressly allowed by the specification.
|
||||
|
||||
d. Window Manager Protocols
|
||||
---------------------------
|
||||
+ _NET_WM_PING (1.3)
|
||||
|
||||
3) ICCCM Compliance
|
||||
-------------------
|
||||
TODO
|
298
HACKING
298
HACKING
@@ -1,298 +0,0 @@
|
||||
Intro...
|
||||
|
||||
Window managers have a few ways in which they are significantly different
|
||||
from other applications. This file, combined with the code overview in
|
||||
doc/code-overview.txt, should hopefully provide a series of relatively
|
||||
quick pointers (hopefully only a few minutes each) to some of the places
|
||||
one can look to orient themselves and get started. Some of this will be
|
||||
general to window managers on X, much will be specific to Metacity, and
|
||||
there's probably some information that's common to programs in general but
|
||||
is nonetheless useful.
|
||||
|
||||
Overview
|
||||
Administrative issues
|
||||
Minimal Building/Testing Environment
|
||||
Relevant standards and X properties
|
||||
Debugging and testing
|
||||
Debugging logs
|
||||
Adding information to the log
|
||||
Valgrind
|
||||
Testing Utilities
|
||||
Technical gotchas to keep in mind
|
||||
Other important reading
|
||||
Extra reading
|
||||
Ideas for tasks to work on
|
||||
|
||||
|
||||
Administrative issues
|
||||
Don't commit substantive code in here without asking hp@redhat.com.
|
||||
Adding translations, no-brainer typo fixes, etc. is fine.
|
||||
|
||||
The code could use cleanup in a lot of places, feel free to do so.
|
||||
|
||||
See http://developer.gnome.org/dotplan/for_maintainers.html for
|
||||
information on how to make a release. The only difference from those
|
||||
instructions is that the minor version number of a Metacity release
|
||||
should always be a number from the Fibonacci sequence.
|
||||
|
||||
Minimal Building/Testing Environment
|
||||
You do not need to _install_ a development version of Metacity to
|
||||
build, run and test it; you can run it from some temporary
|
||||
directory. Also, you do not need to build all of Gnome in order to
|
||||
build a development version of Metacity -- odds are, you may be able
|
||||
to build metacity from CVS without building any other modules.
|
||||
|
||||
As long as you have gtk+ >= 3.0 and GIO >= 2.25.10 with your distro
|
||||
(gtk+ >= 2.6 if you manually revert the change from bug 348633), you
|
||||
should be able to install your distro's development packages
|
||||
(e.g. gtk2-devel, glib-devel, startup-notification-devel on
|
||||
Fedora; also, remember to install the gnome-common package which is
|
||||
needed for building cvs versions of Gnome modules like Metacity) as
|
||||
well as the standard development tools (gcc, autoconf, automake,
|
||||
pkg-config, intltool, and libtool) and be ready to build and test
|
||||
Metacity. Steps to do so:
|
||||
|
||||
$ svn checkout http://svn.gnome.org/svn/metacity/trunk metacity
|
||||
$ cd metacity
|
||||
$ ./autogen.sh --prefix /usr
|
||||
$ make
|
||||
$ ./src/metacity --replace
|
||||
|
||||
Again, note that you do not need to run 'make install'.
|
||||
|
||||
Relevant standards and X properties
|
||||
There are two documents that describe some basics about how window
|
||||
managers should behave: the ICCCM (Inter-Client Communication Conventions
|
||||
Manual) and EWMH (Extended Window Manager Hints). You can find these at
|
||||
the following locations:
|
||||
ICCCM - http://tronche.com/gui/x/icccm/
|
||||
EWMH - :pserver:anoncvs@pdx.freedesktop.org:/cvs
|
||||
The ICCCM is usually available in RPM or DEB format as well. There is
|
||||
actually an online version of the EWMH, but it is almost always woefully
|
||||
out of date. Just get it from cvs with these commands (the backslash
|
||||
means include the stuff from the next line):
|
||||
cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions login
|
||||
cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/icccm-extensions \
|
||||
checkout wm-spec
|
||||
|
||||
DO NOT GO AND READ THOSE THINGS. THEY ARE REALLY, REALLY BORING.
|
||||
|
||||
If you do, you'll probably end up catching up on your sleep instead of
|
||||
hacking on Metacity. ;-) Instead, just look at the table of contents and
|
||||
glance at a page or two to get an idea of what's in there. Then only
|
||||
refer to it if you see something weird in the code and you don't know
|
||||
what it is but has some funny looking name like you see in one of those
|
||||
two documents.
|
||||
|
||||
You can refer to the COMPLIANCE file for additional information on these
|
||||
specifications and Metacity's compliance therewith.
|
||||
|
||||
One of the major things those documents cover that are useful to learn
|
||||
about immediately are X properties. The right way to learn about those,
|
||||
though, is through hand on experimentation with the xprop command (and
|
||||
then look up things you find from xprop in those two manuals if you're
|
||||
curious enough). First, try running
|
||||
xprop
|
||||
in a terminal and click on one of the windows on your screen. That gives
|
||||
you the x properties for that window. Look through them and get a basic
|
||||
idea of what's there for kicks. Note that you can get rid of some of the
|
||||
verboseness by grepping out the _NET_WM_ICON stuff, i.e.
|
||||
xprop | grep -v _NET_WM_ICON
|
||||
Next, try running
|
||||
xprop -root
|
||||
in a terminal. There's all the properties of the root window (which you
|
||||
can think of as the "main" Xserver window). You can also manually
|
||||
specify individual windows that you want the properties of with
|
||||
xprop -id <id>
|
||||
if you know the id of the window in question. You can get the id of a
|
||||
given window by either running xwininfo, e.g.
|
||||
xwininfo | grep "Window id" | cut -f 4 -d ' '
|
||||
or by looking at the _NET_CLIENT_STACKING property of the root
|
||||
window. Finally, it can also be useful to add "-spy" (without the
|
||||
quotes) to the xprop command to get it to continually monitor that
|
||||
window and report any changes to you.
|
||||
|
||||
Debugging information
|
||||
Trying to run a window manager under a typical debugger, such as gdb,
|
||||
unfortunately just doesn't work very well. So, we have to resort to
|
||||
other methods.
|
||||
|
||||
Debugging logs
|
||||
|
||||
First, note that you can start a new version of metacity to replace the
|
||||
existing one by running
|
||||
metacity --replace
|
||||
(which also comes in handy in the form "./src/metacity --replace" when
|
||||
trying to quickly test a small change while hacking on metacity without
|
||||
doing a full "make install", though I'm going off topic...) This will
|
||||
allow you to see any warnings printed at the terminal. Sometimes it's
|
||||
useful to have these directed to a logfile instead, which you can do by
|
||||
running
|
||||
METACITY_USE_LOGFILE=1 metacity --replace
|
||||
The logfile it uses will be printed in the terminal. Sometimes, it's
|
||||
useful to get more information than just warnings. You can set
|
||||
METACITY_VERBOSE to do that, like so:
|
||||
METACITY_VERBOSE=1 METACITY_USE_LOGFILE=1 metacity --replace
|
||||
(note that METACITY_VERBOSE=1 can be problematic without
|
||||
METACITY_USE_LOGFILE=1; avoid it unless running in from something that
|
||||
won't be managed by the new Metacity--see bug 305091 for more details).
|
||||
There are also other flags, such as METACITY_DEBUG, most of which I
|
||||
haven't tried and don't know what they do. Go to the source code
|
||||
directory and run
|
||||
grep "METACITY_" * | grep getenv
|
||||
to find out what the other ones are.
|
||||
|
||||
Adding information to the log
|
||||
|
||||
Since we can't single step with a debugger, we often have to fall back to
|
||||
the primitive method of getting information we want to know: adding
|
||||
"print" statements. Metacity has a fairly structured way to do this,
|
||||
using the functions meta_warning, meta_topic, and meta_verbose. All
|
||||
three have the same basic format as printf, except that meta_topic also
|
||||
takes a leading enumeration parameter to specify the type of message
|
||||
being shown (makes it easier for grepping in a verbose log). You'll find
|
||||
tons of examples in the source code if you need them; just do a quick
|
||||
grep or look in most any file. Note that meta_topic and meta_verbose
|
||||
messages only appear if verbosity is turned on. I tend to frequently add
|
||||
temporary meta_warning statements (or switch meta_topic or meta_verbose
|
||||
ones to meta_warning ones) and then undo the changes once I've learned
|
||||
the info that I needed.
|
||||
|
||||
There is also a meta_print_backtrace (which again is only active if
|
||||
verbosity is turned on) that can also be useful if you want to learn how
|
||||
a particular line of code gets called. And, of course, there's always
|
||||
g_assert if you want to make sure some section isn't executed (or isn't
|
||||
executed under certain conditions).
|
||||
|
||||
Valgrind
|
||||
|
||||
Valgrind is awesome for finding memory leaks or corruption and
|
||||
uninitialized variables. But I also tend to use it in a non-traditional
|
||||
way as a partial substitute for a normal debugger: it can provide me with
|
||||
a stack trace of where metacity is crashing if I made a change that
|
||||
caused it to do so, which is one of the major uses of debuggers. (And,
|
||||
what makes it cooler than a debugger is that there will also often be
|
||||
warnings pinpointing the cause of the crash from either some kind of
|
||||
simple memory corruption or an uninitialized variable). Sometimes, when
|
||||
I merely want to know what is calling a particular function I'll just
|
||||
throw in an "int i; printf("%d\n", i);" just because valgrind will give
|
||||
me a full stacktrace whenever it sees that uninitialized variable being
|
||||
used (yes, I could use meta_print_backtrace, but that means I have to
|
||||
turn verbosity on).
|
||||
|
||||
To run metacity under valgrind, use options typical for any Gnome
|
||||
program, such as
|
||||
valgrind --log-file=metacity.log --tool=memcheck --num-callers=48 \
|
||||
--leak-check=yes --leak-resolution=high --show-reachable=yes \
|
||||
./src/metacity --replace
|
||||
where, again, the backslashes mean to join all the stuff on the following
|
||||
line with the previous one.
|
||||
|
||||
However, there is a downside. Things run a little bit slowly, and it
|
||||
appears that you'll need about 1.5GB of ram, which unfortunately prevents
|
||||
most people from trying this.
|
||||
|
||||
Testing Utilities
|
||||
|
||||
src/run-metacity.sh
|
||||
The script src/run-metacity.sh is useful to hack on the window manager.
|
||||
It runs metacity in an Xnest. e.g.:
|
||||
CLIENTS=3 ./run-metacity.sh
|
||||
or
|
||||
DEBUG=memprof ./run-metacity.sh
|
||||
or
|
||||
DEBUG_TEST=1 ./run-metacity-sh
|
||||
or whatever.
|
||||
|
||||
metacity-message
|
||||
The tool metacity-message can be used as follows:
|
||||
metacity-message reload-theme
|
||||
metacity-message restart
|
||||
metacity-message enable-keybindings
|
||||
metacity-message disable-keybindings
|
||||
The first of these is useful for testing themes, the second is just
|
||||
another way (besides the --restart flag to metacity itself) of
|
||||
restarting metacity, and the third is useful for testing Metacity when
|
||||
running it under an Xnest (typically, the Metacity under the Xnest
|
||||
wouldn't get keybinding notifications--making keyboard navigation not
|
||||
work--but if you disable the keybindings for the global Metacity then
|
||||
the Metacity under the Xnest can then get those keybinding notifications).
|
||||
|
||||
metacity-window-demo
|
||||
metacity-window-demo is good for trying behavior of various kinds
|
||||
of window without launching a full desktop.
|
||||
|
||||
Technical gotchas to keep in mind
|
||||
Files that include gdk.h or gtk.h are not supposed to include
|
||||
display.h or window.h or other core files. Files in the core
|
||||
(display.[hc], window.[hc]) are not supposed to include gdk.h or
|
||||
gtk.h. Reasons:
|
||||
|
||||
"Basically you don't want GDK most of the time. It adds
|
||||
abstractions that cause problems, because they aren't designed to
|
||||
be used in a WM where we do weird stuff (display grabs, and just
|
||||
being the WM). At best GDK adds inefficiency, at worst it breaks
|
||||
things in weird ways where you have to be a GDK guru to figure
|
||||
them out. Owen also told me that they didn't want to start adding
|
||||
a lot of hacks to GDK to let a WM use it; we both agreed back in
|
||||
the mists of time that metacity would only use it for the "UI"
|
||||
bits as it does.
|
||||
|
||||
Having the split in the source code contains and makes very clear
|
||||
the interface between the WM and GDK/GTK. This keeps people from
|
||||
introducing extra GDK/GTK usage when it isn't needed or
|
||||
appropriate. Also, it speeds up the compilation a bit, though this
|
||||
was perhaps more relevant 5 years ago than it is now.
|
||||
|
||||
There was also a very old worry that the GDK stuff might have to
|
||||
be in a separate process to work right; that turned out to be
|
||||
untrue. Though who knows what issues the CM will introduce."
|
||||
|
||||
Remember that strings stored in X properties are not in UTF-8, and they
|
||||
have to end up in UTF-8 before we try putting them through Pango.
|
||||
|
||||
If you make any X request involving a client window, you have to
|
||||
meta_error_trap_push() around the call; this is not necessary for X
|
||||
requests on the frame windows.
|
||||
|
||||
Remember that not all windows have frames, and window->frame can be NULL.
|
||||
|
||||
Other important reading & where to get started
|
||||
Extra reading
|
||||
|
||||
There are some other important things to read to get oriented as well.
|
||||
These are:
|
||||
http://pobox.com/~hp/features.html
|
||||
rationales.txt
|
||||
doc/code-overview.txt
|
||||
|
||||
It pays to read http://pobox.com/~hp/features.html in order
|
||||
to understand the philosophy of Metacity.
|
||||
|
||||
The rationales.txt file has two things: (1) a list of design choices with
|
||||
links in the form of bugzilla bugs that discuss the issue, and (2) a list
|
||||
outstanding bug categories, each of which is tracked by a particular
|
||||
tracker bug in bugzilla from which you can find several closely related
|
||||
bug reports.
|
||||
|
||||
doc/code-overview.txt provides a fairly good overview of the code,
|
||||
including coverage of the function of the various files, the main
|
||||
structures and their relationships, and places to start looking in the
|
||||
code tailored to general categories of tasks.
|
||||
|
||||
Ideas for tasks to work on
|
||||
|
||||
There are a variety of things you could work on in the code. You may
|
||||
have ideas of your own, but in case you don't, let me provide a list of
|
||||
ideas you could choose from:
|
||||
|
||||
If you're ambitious, there's a list of things Havoc made that he'd really
|
||||
like to see tackled, which you can find at
|
||||
http://log.ometer.com/2004-05.html. Be sure to double check with someone
|
||||
to make sure the item is still relevant if you're interested in one of
|
||||
these. Another place to look for ideas, of course, is bugzilla. One can
|
||||
just do queries and look for things that look fixable.
|
||||
|
||||
However, perhaps the best way of getting ideas of related tasks to work
|
||||
on, is to look at the second half of the rationales.txt file, which tries
|
||||
to group bugs by type.
|
@@ -1,8 +0,0 @@
|
||||
Tomas Frydrych
|
||||
Email: tf linux intel com
|
||||
Userid: tomasf
|
||||
|
||||
Owen Taylor
|
||||
Email: otaylor redhat com
|
||||
Userid: otaylor
|
||||
|
@@ -1,43 +0,0 @@
|
||||
Currently active maintainers
|
||||
--------------------------------
|
||||
|
||||
Elijah Newren
|
||||
Email: newren gmail com
|
||||
Userid: newren
|
||||
|
||||
- Usually won't touch the theme bugs (isn't interested) or the
|
||||
compositor (until open source nvidia drivers are up to snuff).
|
||||
Tends to be most interested in libwnck/gtk interactions, focus
|
||||
issues, constraints problems, and raising/stacking, but works on
|
||||
just about anything other than themes and the compositor.
|
||||
|
||||
Thomas Thurman
|
||||
Email: thomas thurman org uk
|
||||
Userid: tthurman
|
||||
|
||||
- Responsible for all theme bugs and the compositor (thank goodness
|
||||
Thomas got involved, eh?). I'm sure he'll replace this sentence
|
||||
with his interests when he reads it. ;-)
|
||||
|
||||
|
||||
Semi-active maintainers
|
||||
--------------------------------
|
||||
|
||||
Havoc Pennington
|
||||
Email: hp redhat com
|
||||
Userid: hp
|
||||
- Original author. Doesn't patch metacity anymore, but is active in
|
||||
answering questions, responding to bugs, providing very helpful
|
||||
suggestions and insight, and even assisting with debugging.
|
||||
|
||||
|
||||
Important historical figureheads
|
||||
--------------------------------
|
||||
|
||||
Rob Adams (readams readams net)
|
||||
- Was the main maintainer of metacity for a while; particular areas
|
||||
of focus included xinerama, placement, and an older version of the
|
||||
constraints code. Still responds to bugs every once in a while.
|
||||
|
||||
Søren Sandmann (sandmann redhat com)
|
||||
- Wrote most of the current compositing manager code + libcm
|
@@ -1,7 +1,5 @@
|
||||
|
||||
SUBDIRS=src protocol po doc
|
||||
|
||||
EXTRA_DIST = HACKING MAINTAINERS rationales.txt
|
||||
SUBDIRS=src po doc
|
||||
|
||||
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
||||
|
||||
|
33
NEWS
33
NEWS
@@ -1,3 +1,36 @@
|
||||
3.12.0
|
||||
======
|
||||
* Fix grab issue with SSD xwayland windows [Rui; #726123]
|
||||
* Misc. bug fixes [Jasper, Ray, Rui, Florian; #727011]
|
||||
|
||||
Contributors:
|
||||
Rui Matos, Florian Müllner, Jasper St. Pierre, Ray Strode
|
||||
|
||||
3.11.92
|
||||
=======
|
||||
* Fix identification of CSD windows [Owen; #723029]
|
||||
* Update keyboard state unconditionally [Rui; #722847]
|
||||
* Misc bug fixes and cleanups [Owen, Rui, Giovanni, Matthias, Adel, Ryan,
|
||||
Jasper, Marek, Florian; #723580, #726123, #726683]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Marek Chalupa, Matthias Clasen, Adel Gadllah, Ryan Lortie,
|
||||
Rui Matos, Florian Müllner, Jasper St. Pierre, Owen W. Taylor
|
||||
|
||||
3.11.91
|
||||
=======
|
||||
* Don't use keysym to match keybindings [Rui; #678001]
|
||||
* Fix message tray icons showing up blank (again) [Adel; #725180]
|
||||
* Improve keybinding lookups [Rui; #725588]
|
||||
* Fix dynamic updates of titlebar style properties [Owen; #725751]
|
||||
* Fix positioning of manually positioned windows [Owen; #724049]
|
||||
* Misc bug fixes and cleanups [Jasper, Carlos, Adel, Giovanni, Florian; #720631,
|
||||
#724969, #725216, #724402, #722266, #725338, #725525]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
|
||||
Jasper St. Pierre, Owen W. Taylor
|
||||
|
||||
3.11.90
|
||||
=======
|
||||
* Fix double-scaling on high DPI resolutions [Adel; #723931]
|
||||
|
416
README
416
README
@@ -1,416 +0,0 @@
|
||||
The original codebase named "Metacity" is not a meta-City as in an
|
||||
urban center, but rather Meta-ness as in the state of being
|
||||
meta. i.e. metacity : meta as opacity : opaque. Also it may have
|
||||
something to do with the Meta key on UNIX keyboards.
|
||||
|
||||
Since then, it has been renamed mutter after a rebase on top of
|
||||
clutter as a compositing manager.
|
||||
|
||||
COMPILING MUTTER
|
||||
===
|
||||
|
||||
You need GTK+ 2.2. For startup notification to work you need
|
||||
libstartup-notification at
|
||||
http://www.freedesktop.org/software/startup-notification/ or on the
|
||||
GNOME ftp site.
|
||||
You need Clutter 1.0. You need gobject-introspection 0.6.3.
|
||||
|
||||
REPORTING BUGS AND SUBMITTING PATCHES
|
||||
===
|
||||
|
||||
Report new bugs on http://bugzilla.gnome.org. Please check for
|
||||
duplicates, *especially* if you are reporting a feature request.
|
||||
|
||||
Please do *not* add "me too!" or "yes I really want this!" comments to
|
||||
feature requests in bugzilla. Please read
|
||||
http://pobox.com/~hp/features.html prior to adding any kind of flame
|
||||
about missing features or misfeatures.
|
||||
|
||||
Feel free to send patches too; Metacity is relatively small and
|
||||
simple, so if you find a bug or want to add a feature it should be
|
||||
pretty easy. Send me mail, or put the patch in bugzilla.
|
||||
|
||||
See the HACKING file for some notes on hacking Mutter.
|
||||
|
||||
MUTTER FEATURES
|
||||
===
|
||||
|
||||
- Uses GTK+ 2.0 for drawing window frames. This means colors, fonts,
|
||||
etc. come from GTK+ theme.
|
||||
|
||||
- Does not expose the concept of "window manager" to the user. Some
|
||||
of the features in the GNOME control panel and other parts of the
|
||||
desktop happen to be implemented in metacity, such as changing your
|
||||
window border theme, or changing your window navigation shortcuts,
|
||||
but the user doesn't need to know this.
|
||||
|
||||
- Includes only the window manager; does not try to be a desktop
|
||||
environment. The pager, configuration, etc. are all separate and
|
||||
modular. The "libwnck" library (which I also wrote) is available
|
||||
for writing metacity extensions, pagers, and so on. (But libwnck
|
||||
isn't metacity specific, or GNOME-dependent; it requires only GTK,
|
||||
and should work with KWin, fvwm2, and other EWMH-compliant WMs.)
|
||||
|
||||
- Has a simple theme system and a couple of extra themes come with it.
|
||||
Change themes via gsettings:
|
||||
gsettings set org.gnome.desktop.wm.preferences theme Crux
|
||||
gsettings set org.gnome.desktop.wm.preferences theme Gorilla
|
||||
gsettings set org.gnome.desktop.wm.preferences theme Atlanta
|
||||
gsettings set org.gnome.desktop.wm.preferences theme Bright
|
||||
|
||||
See theme-format.txt for docs on the theme format. Use
|
||||
metacity-theme-viewer to preview themes.
|
||||
|
||||
- Change number of workspaces via gsettings:
|
||||
gsettings set org.gnome.desktop.wm.preferences num-workspaces 5
|
||||
|
||||
Can also change workspaces from GNOME 2 pager.
|
||||
|
||||
- Change focus mode:
|
||||
gsettings set org.gnome.desktop.wm.preferences focus-mode mouse
|
||||
gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy
|
||||
gsettings set org.gnome.desktop.wm.preferences focus-mode click
|
||||
|
||||
- Global keybinding defaults include:
|
||||
|
||||
Alt-Tab forward cycle window focus
|
||||
Alt-Shift-Tab backward cycle focus
|
||||
Alt-Ctrl-Tab forward cycle focus among panels
|
||||
Alt-Ctrl-Shift-Tab backward cycle focus among panels
|
||||
Alt-Escape cycle window focus without a popup thingy
|
||||
Ctrl-Alt-Left Arrow previous workspace
|
||||
Ctrl-Alt-Right Arrow next workspace
|
||||
Ctrl-Alt-D minimize/unminimize all, to show desktop
|
||||
|
||||
Change keybindings for example:
|
||||
|
||||
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 '[<Alt>F1]'
|
||||
|
||||
Also try the GNOME keyboard shortcuts control panel.
|
||||
|
||||
- Window keybindings:
|
||||
|
||||
Alt-space window menu
|
||||
|
||||
Mnemonics work in the menu. That is, Alt-space then underlined
|
||||
letter in the menu item works.
|
||||
|
||||
Choose Move from menu, and arrow keys to move the window.
|
||||
|
||||
While moving, hold down Control to move slower, and
|
||||
Shift to snap to edges.
|
||||
|
||||
Choose Resize from menu, and nothing happens yet, but
|
||||
eventually I might implement something.
|
||||
|
||||
Keybindings for things like maximize window, vertical maximize,
|
||||
etc. can be bound, but may not all exist by default. See
|
||||
metacity.schemas.
|
||||
|
||||
- Window mouse bindings:
|
||||
|
||||
Clicking anywhere on frame with button 1 will raise/focus window
|
||||
|
||||
If you click a window control, such as the close button, then the
|
||||
control will activate on button release if you are still over it
|
||||
on release (as with most GUI toolkits)
|
||||
|
||||
If you click and drag borders with button 1 it resizes the window
|
||||
|
||||
If you click and drag the titlebar with button 1 it moves the
|
||||
window.
|
||||
|
||||
If you click anywhere on the frame with button 2 it lowers the
|
||||
window.
|
||||
|
||||
If you click anywhere on the frame with button 3 it shows the
|
||||
window menu.
|
||||
|
||||
If you hold down Super (windows key) and click inside a window, it
|
||||
will move the window (buttons 1 and 2) or show menu (button 3).
|
||||
Or you can configure a different modifier for this.
|
||||
|
||||
If you pick up a window with button 1 and then switch workspaces
|
||||
the window will come with you to the new workspace, this is
|
||||
a feature copied from Enlightenment.
|
||||
|
||||
If you hold down Shift while moving a window, the window snaps
|
||||
to edges of other windows and the screen.
|
||||
|
||||
- Session management:
|
||||
|
||||
Mutter connects to the session manager and will set itself up to
|
||||
be respawned. It theoretically restores sizes/positions/workspace
|
||||
for session-aware applications.
|
||||
|
||||
- Mutter implements much of the EWMH window manager specification
|
||||
from freedesktop.org, as well as the older ICCCM. Please refer to
|
||||
the COMPLIANCE file for information on mutter compliance with
|
||||
these standards.
|
||||
|
||||
- Uses Pango to render text, so has cool i18n capabilities.
|
||||
Supports UTF-8 window titles and such.
|
||||
|
||||
- There are simple animations for actions such as minimization,
|
||||
to help users see what is happening. Should probably
|
||||
have a few more of these and make them nicer.
|
||||
|
||||
- if you have the proper X setup, set the GDK_USE_XFT=1
|
||||
environment variable to get antialiased window titles.
|
||||
|
||||
- considers the panel when placing windows and maximizing
|
||||
them.
|
||||
|
||||
- handles the window manager selection from the ICCCM. Will exit if
|
||||
another WM claims it, and can claim it from another WM if you pass
|
||||
the --replace argument. So if you're running another
|
||||
ICCCM-compliant WM, you can run "mutter --replace" to replace it
|
||||
with Metacity.
|
||||
|
||||
- does basic colormap handling
|
||||
|
||||
- and much more! well, maybe not a lot more.
|
||||
|
||||
HOW TO ADD EXTERNAL FEATURES
|
||||
===
|
||||
|
||||
You can write a mutter "plugin" such as a pager, window list, icon
|
||||
box, task menu, or even things like "window matching" using the
|
||||
Extended Window Manager Hints. See http://www.freedesktop.org for the
|
||||
EWMH specification. An easy-to-use library called "libwnck" is
|
||||
available that uses the EWMH and is specifically designed for writing
|
||||
WM accessories.
|
||||
|
||||
You might be interested in existing accessories such as "Devil's Pie"
|
||||
by Ross Burton, which add features to Mutter (or other
|
||||
EWMH-compliant WMs).
|
||||
|
||||
MUTTER BUGS, NON-FEATURES, AND CAVEATS
|
||||
===
|
||||
|
||||
See bugzilla: http://bugzilla.gnome.org/query.cgi
|
||||
|
||||
FAQ
|
||||
===
|
||||
|
||||
Q: Will you add my feature?
|
||||
|
||||
A: If it makes sense to turn on unconditionally, or is genuinely a
|
||||
harmless preference that I would not be embarrassed to put in a
|
||||
simple, uncluttered, user-friendly configuration dialog.
|
||||
|
||||
If the only rationale for your feature is that other window
|
||||
managers have it, or that you are personally used to it, or
|
||||
something like that, then I will not be impressed. Metacity is
|
||||
firmly in the "choose good defaults" camp rather than the "offer 6
|
||||
equally broken ways to do it, and let the user pick one" camp.
|
||||
|
||||
This is part of a "no crackrock" policy, despite some exceptions
|
||||
I'm mildly embarrassed about. For example, multiple workspaces
|
||||
probably constitute crackrock, they confuse most users and really
|
||||
are not that useful if you have a decent tasklist and so on. But I
|
||||
am too used to them to turn them off. Or alternatively
|
||||
iconification/tasklist is crack, and workspaces/pager are good. But
|
||||
having both is certainly a bit wrong. Sloppy focus is probably
|
||||
crackrock too.
|
||||
|
||||
But don't think unlimited crack is OK just because I slipped up a
|
||||
little. No slippery slope here.
|
||||
|
||||
Don't let this discourage patches and fixes - I love those. ;-)
|
||||
Just be prepared to hear the above objections if your patch adds
|
||||
some crack-ridden configuration option.
|
||||
|
||||
http://pobox.com/~hp/free-software-ui.html
|
||||
http://pobox.com/~hp/features.html
|
||||
|
||||
Q: Will Mutter be part of GNOME?
|
||||
|
||||
A: It is not officially part of GNOME as of GNOME 2.27. We are
|
||||
hoping to have mutter officially included as of GNOME 2.28.
|
||||
|
||||
Q: Why does Mutter remember the workspace/position of some apps
|
||||
but not others across logout/login?
|
||||
|
||||
A: Mutter only stores sizes/positions for apps that are session
|
||||
managed. As far as I can determine, there is no way to attempt to
|
||||
remember workspace/position for non-session-aware apps without
|
||||
causing a lot of weird effects.
|
||||
|
||||
The reason is that you don't know which non-SM-aware apps were
|
||||
launched by the session. When you initially log in, Metacity sees a
|
||||
bunch of new windows appear. But it can't distinguish between
|
||||
windows that were stored in your session, or windows you just
|
||||
launched after logging in. If Metacity tried to guess that a window
|
||||
was from the session, it could e.g. end up maximizing a dialog, or
|
||||
put a window you just launched on another desktop or in a weird
|
||||
place. And in fact I see a lot of bugs like this in window managers
|
||||
that try to handle non-session-aware apps.
|
||||
|
||||
However, for session-aware apps, Mutter can tell that the
|
||||
application instance is from the session and thus restore it
|
||||
reliably, assuming the app properly restores the windows it had
|
||||
open on session save.
|
||||
|
||||
So the correct way to fix the situation is to make apps
|
||||
session-aware. libSM has come with X for years, it's very
|
||||
standardized, it's shared by GNOME and KDE - even twm is
|
||||
session-aware. So anyone who won't take a patch to add SM is more
|
||||
archaic than twm - and you should flame them. ;-)
|
||||
|
||||
Docs on session management:
|
||||
http://www.fifi.org/doc/xspecs/xsmp.txt.gz
|
||||
http://www.fifi.org/doc/xspecs/SMlib.txt.gz
|
||||
|
||||
See also the ICCCM section on SM. For GNOME apps, use the
|
||||
GnomeClient object. For a simple example of using libSM directly,
|
||||
twm/session.c in the twm source code is pretty easy to understand.
|
||||
|
||||
Q: How about adding viewports in addition to workspaces?
|
||||
|
||||
A: I could conceivably be convinced to use viewports _instead_ of
|
||||
workspaces, though currently I'm not thinking that. But I don't
|
||||
think it makes any sense to have both; it's just confusing. They
|
||||
are functionally equivalent.
|
||||
|
||||
You may think this means that you won't have certain keybindings,
|
||||
or something like that. This is a misconception. The only
|
||||
_fundamental_ difference between viewports and workspaces is that
|
||||
with viewports, windows can "overlap" and appear partially on
|
||||
one and partially on another. All other differences that
|
||||
traditionally exist in other window managers are accidental -
|
||||
the features commonly associated with viewports can be implemented
|
||||
for workspaces, and vice versa.
|
||||
|
||||
So I don't want to have two kinds of
|
||||
workspace/desktop/viewport/whatever, but I'm willing to add
|
||||
features traditionally associated with either kind if those
|
||||
features make sense.
|
||||
|
||||
Q: Why is the panel always on top?
|
||||
|
||||
A: Because it's a better user interface, and until we made this not
|
||||
configurable a bunch of apps were not getting fixed (the app
|
||||
authors were just saying "put your panel on the bottom" instead of
|
||||
properly supporting fullscreen mode, and such).
|
||||
|
||||
rationales.txt has the bugzilla URL for some flamefesting on this,
|
||||
if you want to go back and relive the glory.
|
||||
Read these and the bugzilla stuff before asking/commenting:
|
||||
http://pobox.com/~hp/free-software-ui.html
|
||||
http://pobox.com/~hp/features.html
|
||||
|
||||
Q: Why is there no edge flipping?
|
||||
|
||||
A: This one is also in rationales.txt. Because "ouija board" UI, where
|
||||
you just move the mouse around and the computer guesses what you
|
||||
mean, has a lot of issues. This includes mouse focus, shade-hover
|
||||
mode, edge flipping, autoraise, etc. Metacity has mouse focus and
|
||||
autoraise as a compromise, but these features are all confusing for
|
||||
many users, and cause problems with accessibility, fitt's law, and
|
||||
so on.
|
||||
|
||||
Read these and the bugzilla stuff before asking/commenting:
|
||||
http://pobox.com/~hp/free-software-ui.html
|
||||
http://pobox.com/~hp/features.html
|
||||
|
||||
Q: Why does wireframe move/resize suck?
|
||||
|
||||
A: You can turn it on with the reduced_resources setting.
|
||||
|
||||
But: it has low usability, and is a pain
|
||||
to implement, and there's no reason opaque move/resize should be a
|
||||
problem on any setup that can run a modern desktop worth a darn to
|
||||
begin with.
|
||||
|
||||
Read these and the bugzilla stuff before asking/commenting:
|
||||
http://pobox.com/~hp/free-software-ui.html
|
||||
http://pobox.com/~hp/features.html
|
||||
|
||||
The reason we had to add wireframe anyway was broken
|
||||
proprietary apps that can't handle lots of resize events.
|
||||
|
||||
Q: Why no XYZ?
|
||||
|
||||
A: You are probably getting the idea by now - check rationales.txt,
|
||||
query/search bugzilla, and read http://pobox.com/~hp/features.html
|
||||
and http://pobox.com/~hp/free-software-ui.html
|
||||
|
||||
Then sit down and answer the question for yourself. Is the feature
|
||||
good? What's the rationale for it? Answer "why" not just "why not."
|
||||
Justify in terms of users as a whole, not just users like
|
||||
yourself. How else can you solve the same problem? etc. If that
|
||||
leads you to a strong opinion, then please, post the rationale for
|
||||
discussion to an appropriate bugzilla bug, or to
|
||||
usability@gnome.org.
|
||||
|
||||
Please don't just "me too!" on bugzilla bugs, please don't think
|
||||
flames will get you anywhere, and please don't repeat rationale
|
||||
that's already been offered.
|
||||
|
||||
Q: Your dumb web pages you made me read talk about solving problems in
|
||||
fundamental ways instead of adding preferences or workarounds.
|
||||
What are some examples where metacity has done this?
|
||||
|
||||
A: There are quite a few, though many opportunities remain. Sometimes
|
||||
the real fix involves application changes. The metacity approach is
|
||||
that it's OK to require apps to change, though there are also
|
||||
plenty of workarounds in metacity for battles considered too hard
|
||||
to fight.
|
||||
|
||||
Here are some examples:
|
||||
|
||||
- fullscreen mode was introduced to allow position constraints,
|
||||
panel-on-top, and other such things to apply to normal windows
|
||||
while still allowing video players etc. to "just work"
|
||||
|
||||
- "whether to include minimized windows in Alt+Tab" was solved
|
||||
by putting minimized windows at the *end* of the tab order.
|
||||
|
||||
- Whether to pop up a feedback display during Alt+Tab was solved by
|
||||
having both Alt+Tab and Alt+Esc
|
||||
|
||||
- Whether to have a "kill" feature was solved by automatically
|
||||
detecting and offering to kill stuck apps. Better, metacity
|
||||
actually does "kill -9" on the process, it doesn't just
|
||||
disconnect the process from the X server. You'll appreciate this
|
||||
if you ever did a "kill" on Netscape 4, and watched it keep
|
||||
eating 100% CPU even though the X server had booted it.
|
||||
|
||||
- The workspaces vs. viewports mess was avoided by adding
|
||||
directional navigation and such to workspaces, see discussion
|
||||
earlier in this file.
|
||||
|
||||
- Instead of configurable placement algorithms, there's just one
|
||||
that works fairly well most of the time.
|
||||
|
||||
- To avoid excess CPU use during opaque move/resize, we rate limit
|
||||
the updates to the application window's size.
|
||||
|
||||
- Instead of configurable "show size of window while resizing,"
|
||||
it's only shown for windows where it matters, such as terminals.
|
||||
(Only use-case given for all windows is for web designers
|
||||
choosing their web browser size, but there are web sites and
|
||||
desktop backgrounds that do this for you.)
|
||||
|
||||
- Using startup notification, applications open on the workspace
|
||||
where you launched them, not the active workspace when their
|
||||
window is opened.
|
||||
|
||||
- and much more.
|
||||
|
||||
Q: I think mutter sucks.
|
||||
|
||||
A: Feel free to use any WM you like. The reason metacity follows the
|
||||
ICCCM and EWMH specifications is that it makes metacity a modular,
|
||||
interchangeable part in the desktop. libwnck-based apps such as the
|
||||
GNOME window list will work just fine with any EWMH-compliant WM.
|
||||
|
||||
Q: Did you spend a lot of time on this?
|
||||
|
||||
A: Originally the answer was no. Sadly the answer is now yes.
|
||||
|
||||
Q: How can you claim that you are anti-crack, while still
|
||||
writing a window manager?
|
||||
|
||||
A: I have no comment on that.
|
@@ -5,7 +5,7 @@ srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
PKG_NAME="mutter"
|
||||
REQUIRED_AUTOMAKE_VERSION=1.13
|
||||
REQUIRED_AUTOMAKE_VERSION=1.10
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -d $srcdir/src) || {
|
||||
|
10
configure.ac
10
configure.ac
@@ -2,8 +2,8 @@ AC_PREREQ(2.50)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [11])
|
||||
m4_define([mutter_micro_version], [90])
|
||||
m4_define([mutter_minor_version], [12])
|
||||
m4_define([mutter_micro_version], [0])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -142,11 +142,6 @@ AM_GLIB_GNU_GETTEXT
|
||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
|
||||
PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
|
||||
|
||||
saved_LIBS="$LIBS"
|
||||
LIBS="$LIBS $MUTTER_LAUNCH"
|
||||
AC_CHECK_FUNCS([sd_session_get_vt])
|
||||
LIBS="$saved_LIBS"
|
||||
|
||||
# Unconditionally use this dir to avoid a circular dep with gnomecc
|
||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
||||
AC_SUBST(GNOME_KEYBINDINGS_KEYSDIR)
|
||||
@@ -458,7 +453,6 @@ doc/reference/meta-docs.sgml
|
||||
src/Makefile
|
||||
src/libmutter-wayland.pc
|
||||
src/compositor/plugins/Makefile
|
||||
protocol/Makefile
|
||||
po/Makefile.in
|
||||
])
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
SUBDIRS = man reference
|
||||
|
||||
EXTRA_DIST=theme-format.txt dialogs.txt code-overview.txt \
|
||||
how-to-get-focus-right.txt
|
||||
how-to-get-focus-right.txt rationales.txt
|
||||
|
@@ -16,11 +16,11 @@ src/core/monitor.c
|
||||
src/core/mutter.c
|
||||
src/core/prefs.c
|
||||
src/core/screen.c
|
||||
src/core/session.c
|
||||
src/x11/session.c
|
||||
src/core/util.c
|
||||
src/core/window.c
|
||||
src/core/window-props.c
|
||||
src/core/xprops.c
|
||||
src/x11/window-props.c
|
||||
src/x11/xprops.c
|
||||
src/mutter-wayland.desktop.in
|
||||
src/org.gnome.mutter.gschema.xml.in
|
||||
src/org.gnome.mutter.wayland.gschema.xml.in
|
||||
|
@@ -1,7 +0,0 @@
|
||||
NULL =
|
||||
|
||||
EXTRA_DIST = \
|
||||
gtk-shell.xml \
|
||||
xdg-shell.xml \
|
||||
xserver.xml \
|
||||
$(NULL)
|
@@ -29,11 +29,7 @@ INCLUDES= \
|
||||
-DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) \
|
||||
-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||
-DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\" \
|
||||
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"
|
||||
|
||||
INCLUDES += \
|
||||
-I$(srcdir)/wayland \
|
||||
-I$(builddir)/wayland \
|
||||
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
|
||||
-DXWAYLAND_PATH='"@XWAYLAND_PATH@"'
|
||||
|
||||
mutter_built_sources = \
|
||||
@@ -41,16 +37,20 @@ mutter_built_sources = \
|
||||
$(dbus_xrandr_built_sources) \
|
||||
mutter-enum-types.h \
|
||||
mutter-enum-types.c \
|
||||
wayland/gtk-shell-protocol.c \
|
||||
wayland/gtk-shell-server-protocol.h \
|
||||
wayland/xdg-shell-protocol.c \
|
||||
wayland/xdg-shell-server-protocol.h \
|
||||
wayland/xserver-protocol.c \
|
||||
wayland/xserver-server-protocol.h
|
||||
gtk-shell-protocol.c \
|
||||
gtk-shell-server-protocol.h \
|
||||
xdg-shell-protocol.c \
|
||||
xdg-shell-server-protocol.h \
|
||||
xserver-protocol.c \
|
||||
xserver-server-protocol.h
|
||||
|
||||
wayland_protocols = \
|
||||
wayland/protocol/gtk-shell.xml \
|
||||
wayland/protocol/xdg-shell.xml \
|
||||
wayland/protocol/xserver.xml
|
||||
|
||||
libmutter_wayland_la_SOURCES = \
|
||||
core/async-getprop.c \
|
||||
core/async-getprop.h \
|
||||
core/above-tab-keycode.c \
|
||||
core/barrier.c \
|
||||
meta/barrier.h \
|
||||
core/bell.c \
|
||||
@@ -105,7 +105,6 @@ libmutter_wayland_la_SOURCES = \
|
||||
meta/meta-shadow-factory.h \
|
||||
meta/meta-window-actor.h \
|
||||
meta/compositor-mutter.h \
|
||||
core/above-tab-keycode.c \
|
||||
core/constraints.c \
|
||||
core/constraints.h \
|
||||
core/core.c \
|
||||
@@ -117,19 +116,14 @@ libmutter_wayland_la_SOURCES = \
|
||||
core/edge-resistance.h \
|
||||
core/edid-parse.c \
|
||||
core/edid.h \
|
||||
core/events.c \
|
||||
core/events.h \
|
||||
core/errors.c \
|
||||
meta/errors.h \
|
||||
core/frame.c \
|
||||
core/frame.h \
|
||||
ui/gradient.c \
|
||||
meta/gradient.h \
|
||||
core/group-private.h \
|
||||
core/group-props.c \
|
||||
core/group-props.h \
|
||||
core/group.c \
|
||||
meta/group.h \
|
||||
core/iconcache.c \
|
||||
core/iconcache.h \
|
||||
core/keybindings.c \
|
||||
core/keybindings-private.h \
|
||||
core/main.c \
|
||||
@@ -152,8 +146,6 @@ libmutter_wayland_la_SOURCES = \
|
||||
core/screen-private.h \
|
||||
meta/screen.h \
|
||||
meta/types.h \
|
||||
core/session.c \
|
||||
core/session.h \
|
||||
core/stack.c \
|
||||
core/stack.h \
|
||||
core/stack-tracker.c \
|
||||
@@ -161,17 +153,11 @@ libmutter_wayland_la_SOURCES = \
|
||||
core/util.c \
|
||||
meta/util.h \
|
||||
core/util-private.h \
|
||||
core/window-props.c \
|
||||
core/window-props.h \
|
||||
core/window-x11.c \
|
||||
core/window-x11.h \
|
||||
core/window.c \
|
||||
core/window-private.h \
|
||||
meta/window.h \
|
||||
core/workspace.c \
|
||||
core/workspace-private.h \
|
||||
core/xprops.c \
|
||||
core/xprops.h \
|
||||
meta/common.h \
|
||||
core/core.h \
|
||||
ui/ui.h \
|
||||
@@ -188,6 +174,24 @@ libmutter_wayland_la_SOURCES = \
|
||||
meta/theme.h \
|
||||
ui/theme-private.h \
|
||||
ui/ui.c \
|
||||
x11/iconcache.c \
|
||||
x11/iconcache.h \
|
||||
x11/async-getprop.c \
|
||||
x11/async-getprop.h \
|
||||
x11/group-private.h \
|
||||
x11/group-props.c \
|
||||
x11/group-props.h \
|
||||
x11/group.c \
|
||||
meta/group.h \
|
||||
x11/session.c \
|
||||
x11/session.h \
|
||||
x11/window-props.c \
|
||||
x11/window-props.h \
|
||||
x11/window-x11.c \
|
||||
x11/window-x11.h \
|
||||
x11/window-x11-private.h \
|
||||
x11/xprops.c \
|
||||
x11/xprops.h \
|
||||
wayland/meta-wayland.c \
|
||||
wayland/meta-wayland.h \
|
||||
wayland/meta-wayland-private.h \
|
||||
@@ -208,7 +212,9 @@ libmutter_wayland_la_SOURCES = \
|
||||
wayland/meta-wayland-types.h \
|
||||
wayland/meta-wayland-versions.h \
|
||||
wayland/meta-weston-launch.c \
|
||||
wayland/meta-weston-launch.h
|
||||
wayland/meta-weston-launch.h \
|
||||
wayland/window-wayland.c \
|
||||
wayland/window-wayland.h
|
||||
|
||||
nodist_libmutter_wayland_la_SOURCES = \
|
||||
$(mutter_built_sources)
|
||||
@@ -309,7 +315,7 @@ endif
|
||||
|
||||
testboxes_SOURCES = core/testboxes.c
|
||||
testgradient_SOURCES = ui/testgradient.c
|
||||
testasyncgetprop_SOURCES = core/testasyncgetprop.c
|
||||
testasyncgetprop_SOURCES = x11/testasyncgetprop.c
|
||||
|
||||
noinst_PROGRAMS=testboxes testgradient testasyncgetprop
|
||||
|
||||
@@ -360,6 +366,7 @@ EXTRA_DIST=$(desktopfiles_files) \
|
||||
$(desktopfiles_in_files) \
|
||||
$(wmproperties_in_files) \
|
||||
$(xml_in_files) \
|
||||
$(wayland_protocols) \
|
||||
org.gnome.mutter.gschema.xml.in \
|
||||
org.gnome.mutter.wayland.gschema.xml.in \
|
||||
mutter-schemas.convert \
|
||||
@@ -409,9 +416,7 @@ $(dbus_idle_built_sources) : Makefile.am idle-monitor.xml
|
||||
--c-generate-object-manager \
|
||||
$(srcdir)/idle-monitor.xml
|
||||
|
||||
wayland/%-protocol.c : $(top_builddir)/protocol/%.xml
|
||||
mkdir -p wayland
|
||||
%-protocol.c : $(srcdir)/wayland/protocol/%.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
|
||||
wayland/%-server-protocol.h : $(top_builddir)/protocol/%.xml
|
||||
mkdir -p wayland
|
||||
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@
|
||||
|
@@ -19,16 +19,10 @@ struct _MetaCompositor
|
||||
|
||||
guint repaint_func_id;
|
||||
|
||||
ClutterActor *shadow_src;
|
||||
|
||||
MetaPlugin *modal_plugin;
|
||||
|
||||
gint64 server_time_query_time;
|
||||
gint64 server_time_offset;
|
||||
|
||||
guint server_time_is_monotonic_time : 1;
|
||||
guint show_redraw : 1;
|
||||
guint debug : 1;
|
||||
guint no_mipmaps : 1;
|
||||
};
|
||||
|
||||
@@ -36,10 +30,9 @@ struct _MetaCompScreen
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
ClutterActor *stage, *window_group, *top_window_group, *overlay_group;
|
||||
ClutterActor *stage, *window_group, *top_window_group;
|
||||
ClutterActor *background_actor;
|
||||
GList *windows;
|
||||
GHashTable *windows_by_xid;
|
||||
Window output;
|
||||
|
||||
CoglOnscreen *onscreen;
|
||||
@@ -70,6 +63,4 @@ void meta_end_modal_for_plugin (MetaScreen *screen,
|
||||
gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
|
||||
gint64 monotonic_time);
|
||||
|
||||
void meta_check_end_modal (MetaScreen *screen);
|
||||
|
||||
#endif /* META_COMPOSITOR_PRIVATE_H */
|
||||
|
@@ -65,7 +65,6 @@
|
||||
#include <meta/window.h>
|
||||
#include "compositor-private.h"
|
||||
#include <meta/compositor-mutter.h>
|
||||
#include "xprops.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/main.h>
|
||||
#include <meta/meta-background-actor.h>
|
||||
@@ -77,14 +76,16 @@
|
||||
#include "display-private.h" /* for meta_display_lookup_x_window() */
|
||||
#include "util-private.h"
|
||||
#include "frame.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-keyboard.h"
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
/* #define DEBUG_TRACE g_print */
|
||||
#define DEBUG_TRACE(X)
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
static gboolean
|
||||
is_modal (MetaDisplay *display)
|
||||
{
|
||||
return display->grab_op == META_GRAB_OP_COMPOSITOR;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
composite_at_least_version (MetaDisplay *display, int maj, int min)
|
||||
@@ -109,13 +110,8 @@ meta_finish_workspace_switch (MetaCompScreen *info)
|
||||
for (l = info->windows; l; l = l->next)
|
||||
meta_window_actor_sync_visibility (l->data);
|
||||
|
||||
/*
|
||||
* Fix up stacking order in case the plugin messed it up.
|
||||
*/
|
||||
/* Fix up stacking order. */
|
||||
sync_actor_stacking (info);
|
||||
|
||||
/* printf ("... FINISHED DESKTOP SWITCH\n"); */
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -141,33 +137,12 @@ meta_compositor_destroy (MetaCompositor *compositor)
|
||||
clutter_threads_remove_repaint_func (compositor->repaint_func_id);
|
||||
}
|
||||
|
||||
static void
|
||||
add_win (MetaWindow *window)
|
||||
{
|
||||
MetaScreen *screen = meta_window_get_screen (window);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
g_return_if_fail (info != NULL);
|
||||
|
||||
meta_window_actor_new (window);
|
||||
|
||||
sync_actor_stacking (info);
|
||||
}
|
||||
|
||||
static void
|
||||
process_damage (MetaCompositor *compositor,
|
||||
XDamageNotifyEvent *event,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaWindowActor *window_actor;
|
||||
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
if (window_actor == NULL)
|
||||
return;
|
||||
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_process_x11_damage (window_actor, event);
|
||||
}
|
||||
|
||||
@@ -372,7 +347,6 @@ begin_modal_x11 (MetaScreen *screen,
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
Window grab_window = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
|
||||
Cursor cursor = None;
|
||||
int result;
|
||||
gboolean pointer_grabbed = FALSE;
|
||||
gboolean keyboard_grabbed = FALSE;
|
||||
@@ -392,7 +366,7 @@ begin_modal_x11 (MetaScreen *screen,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
grab_window,
|
||||
timestamp,
|
||||
cursor,
|
||||
None,
|
||||
XIGrabModeAsync, XIGrabModeAsync,
|
||||
False, /* owner_events */
|
||||
&mask);
|
||||
@@ -436,45 +410,6 @@ begin_modal_x11 (MetaScreen *screen,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
begin_modal_wayland (MetaScreen *screen,
|
||||
MetaPlugin *plugin,
|
||||
MetaModalOptions options,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
gboolean pointer_grabbed = FALSE;
|
||||
gboolean keyboard_grabbed = FALSE;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0)
|
||||
{
|
||||
if (!meta_wayland_pointer_begin_modal (&compositor->seat->pointer))
|
||||
goto fail;
|
||||
|
||||
pointer_grabbed = TRUE;
|
||||
}
|
||||
if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
|
||||
{
|
||||
if (!meta_wayland_keyboard_begin_modal (&compositor->seat->keyboard,
|
||||
timestamp))
|
||||
goto fail;
|
||||
|
||||
keyboard_grabbed = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
if (pointer_grabbed)
|
||||
meta_wayland_pointer_end_modal (&compositor->seat->pointer);
|
||||
if (keyboard_grabbed)
|
||||
meta_wayland_keyboard_end_modal (&compositor->seat->keyboard, timestamp);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_begin_modal_for_plugin (MetaScreen *screen,
|
||||
MetaPlugin *plugin,
|
||||
@@ -485,19 +420,14 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
|
||||
* are significant differences in how we handle grabs that make it difficult to
|
||||
* merge the two.
|
||||
*/
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
gboolean ok;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
|
||||
if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE)
|
||||
if (is_modal (display) || display->grab_op != META_GRAB_OP_NONE)
|
||||
return FALSE;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
ok = begin_modal_wayland (screen, plugin, options, timestamp);
|
||||
else
|
||||
ok = begin_modal_x11 (screen, plugin, options, timestamp);
|
||||
if (!ok)
|
||||
return FALSE;
|
||||
if (!meta_is_wayland_compositor ())
|
||||
if (!begin_modal_x11 (screen, plugin, options, timestamp))
|
||||
return FALSE;
|
||||
|
||||
display->grab_op = META_GRAB_OP_COMPOSITOR;
|
||||
display->grab_window = NULL;
|
||||
@@ -505,7 +435,8 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
|
||||
display->grab_have_pointer = TRUE;
|
||||
display->grab_have_keyboard = TRUE;
|
||||
|
||||
compositor->modal_plugin = plugin;
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -515,25 +446,10 @@ meta_end_modal_for_plugin (MetaScreen *screen,
|
||||
MetaPlugin *plugin,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
|
||||
g_return_if_fail (compositor->modal_plugin == plugin);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
meta_wayland_pointer_end_modal (&compositor->seat->pointer);
|
||||
meta_wayland_keyboard_end_modal (&compositor->seat->keyboard,
|
||||
timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
|
||||
}
|
||||
g_return_if_fail (is_modal (display));
|
||||
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->grab_window = NULL;
|
||||
@@ -541,25 +457,14 @@ meta_end_modal_for_plugin (MetaScreen *screen,
|
||||
display->grab_have_pointer = FALSE;
|
||||
display->grab_have_keyboard = FALSE;
|
||||
|
||||
compositor->modal_plugin = NULL;
|
||||
}
|
||||
|
||||
/* This is used when reloading plugins to make sure we don't have
|
||||
* a left-over modal grab for this screen.
|
||||
*/
|
||||
void
|
||||
meta_check_end_modal (MetaScreen *screen)
|
||||
{
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
|
||||
if (compositor->modal_plugin &&
|
||||
meta_plugin_get_screen (compositor->modal_plugin) == screen)
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
meta_end_modal_for_plugin (screen,
|
||||
compositor->modal_plugin,
|
||||
|
||||
CurrentTime);
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
}
|
||||
else
|
||||
{
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,18 +667,25 @@ meta_compositor_unmanage_screen (MetaCompositor *compositor,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Shapes the cow so that the given window is exposed,
|
||||
* when metaWindow is NULL it clears the shape again
|
||||
/**
|
||||
* meta_shape_cow_for_window:
|
||||
* @screen: A #MetaScreen
|
||||
* @window: (allow-none): A #MetaWindow to shape the COW for
|
||||
*
|
||||
* Sets an bounding shape on the COW so that the given window
|
||||
* is exposed. If @window is %NULL it clears the shape again.
|
||||
*
|
||||
* Used so we can unredirect windows, by shaping away the part
|
||||
* of the COW, letting the raw window be seen through below.
|
||||
*/
|
||||
static void
|
||||
meta_shape_cow_for_window (MetaScreen *screen,
|
||||
MetaWindow *metaWindow)
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (meta_screen_get_display (screen));
|
||||
|
||||
if (metaWindow == NULL)
|
||||
if (window == NULL)
|
||||
XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None);
|
||||
else
|
||||
{
|
||||
@@ -782,7 +694,7 @@ meta_shape_cow_for_window (MetaScreen *screen,
|
||||
int width, height;
|
||||
MetaRectangle rect;
|
||||
|
||||
meta_window_get_frame_rect (metaWindow, &rect);
|
||||
meta_window_get_frame_rect (window, &rect);
|
||||
|
||||
window_bounds.x = rect.x;
|
||||
window_bounds.y = rect.y;
|
||||
@@ -833,11 +745,12 @@ meta_compositor_add_window (MetaCompositor *compositor,
|
||||
{
|
||||
MetaScreen *screen = meta_window_get_screen (window);
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_add_window\n");
|
||||
meta_error_trap_push (display);
|
||||
|
||||
add_win (window);
|
||||
meta_window_actor_new (window);
|
||||
sync_actor_stacking (info);
|
||||
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
@@ -846,17 +759,9 @@ void
|
||||
meta_compositor_remove_window (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaWindowActor *window_actor = NULL;
|
||||
MetaScreen *screen;
|
||||
MetaCompScreen *info;
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_remove_window\n");
|
||||
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
screen = meta_window_get_screen (window);
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
MetaScreen *screen = meta_window_get_screen (window);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (info->unredirected_window == window)
|
||||
set_unredirected_window (info, NULL);
|
||||
@@ -869,13 +774,7 @@ meta_compositor_set_updates_frozen (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean updates_frozen)
|
||||
{
|
||||
MetaWindowActor *window_actor;
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_set_updates_frozen\n");
|
||||
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_set_updates_frozen (window_actor, updates_frozen);
|
||||
}
|
||||
|
||||
@@ -884,13 +783,7 @@ meta_compositor_queue_frame_drawn (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean no_delay_frame)
|
||||
{
|
||||
MetaWindowActor *window_actor;
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_queue_frame_drawn\n");
|
||||
window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_queue_frame_drawn (window_actor, no_delay_frame);
|
||||
}
|
||||
|
||||
@@ -953,29 +846,6 @@ meta_compositor_window_surface_changed (MetaCompositor *compositor,
|
||||
meta_window_actor_update_surface (window_actor);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
grab_op_is_clicking (MetaGrabOp grab_op)
|
||||
{
|
||||
switch (grab_op)
|
||||
{
|
||||
case META_GRAB_OP_CLICKING_MINIMIZE:
|
||||
case META_GRAB_OP_CLICKING_MAXIMIZE:
|
||||
case META_GRAB_OP_CLICKING_UNMAXIMIZE:
|
||||
case META_GRAB_OP_CLICKING_DELETE:
|
||||
case META_GRAB_OP_CLICKING_MENU:
|
||||
case META_GRAB_OP_CLICKING_SHADE:
|
||||
case META_GRAB_OP_CLICKING_UNSHADE:
|
||||
case META_GRAB_OP_CLICKING_ABOVE:
|
||||
case META_GRAB_OP_CLICKING_UNABOVE:
|
||||
case META_GRAB_OP_CLICKING_STICK:
|
||||
case META_GRAB_OP_CLICKING_UNSTICK:
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_is_passive_button_grab (MetaDisplay *display,
|
||||
XIDeviceEvent *device_event)
|
||||
@@ -1031,7 +901,7 @@ maybe_spoof_event_as_stage_event (MetaCompScreen *info,
|
||||
/* If this is a window frame, and we think GTK+ needs to handle the event,
|
||||
let GTK+ handle it without mangling */
|
||||
if (window && window->frame && device_event->event == window->frame->xwindow &&
|
||||
(grab_op_is_clicking (display->grab_op) ||
|
||||
(meta_grab_op_is_clicking (display->grab_op) ||
|
||||
(display->grab_op == META_GRAB_OP_NONE && !event_is_passive_button_grab (display, device_event))))
|
||||
break;
|
||||
|
||||
@@ -1070,9 +940,9 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (compositor->modal_plugin && is_grabbed_event (compositor->display, event))
|
||||
if (is_modal (display) && is_grabbed_event (compositor->display, event))
|
||||
{
|
||||
_meta_plugin_xevent_filter (compositor->modal_plugin, event);
|
||||
meta_plugin_manager_xevent_filter (info->plugin_mgr, event);
|
||||
|
||||
/* We always consume events even if the plugin says it didn't handle them;
|
||||
* exclusive is exclusive */
|
||||
@@ -1083,10 +953,7 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
maybe_spoof_event_as_stage_event (info, window, event);
|
||||
|
||||
if (meta_plugin_manager_xevent_filter (info->plugin_mgr, event))
|
||||
{
|
||||
DEBUG_TRACE ("meta_compositor_process_event (filtered,window==NULL)\n");
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
if (!meta_is_wayland_compositor () &&
|
||||
event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
|
||||
@@ -1100,7 +967,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
window = meta_display_lookup_x_window (compositor->display, xwin);
|
||||
}
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
|
||||
process_damage (compositor, (XDamageNotifyEvent *) event, window);
|
||||
}
|
||||
|
||||
@@ -1122,11 +988,7 @@ meta_compositor_filter_keybinding (MetaCompositor *compositor,
|
||||
MetaKeyBinding *binding)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (info->plugin_mgr)
|
||||
return meta_plugin_manager_filter_keybinding (info->plugin_mgr, binding);
|
||||
|
||||
return FALSE;
|
||||
return meta_plugin_manager_filter_keybinding (info->plugin_mgr, binding);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1135,11 +997,7 @@ meta_compositor_show_window (MetaCompositor *compositor,
|
||||
MetaCompEffect effect)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
DEBUG_TRACE ("meta_compositor_show_window\n");
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
meta_window_actor_show (window_actor, effect);
|
||||
meta_window_actor_show (window_actor, effect);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1148,10 +1006,6 @@ meta_compositor_hide_window (MetaCompositor *compositor,
|
||||
MetaCompEffect effect)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
DEBUG_TRACE ("meta_compositor_hide_window\n");
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
meta_window_actor_hide (window_actor, effect);
|
||||
}
|
||||
|
||||
@@ -1162,10 +1016,6 @@ meta_compositor_maximize_window (MetaCompositor *compositor,
|
||||
MetaRectangle *new_rect)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
DEBUG_TRACE ("meta_compositor_maximize_window\n");
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
meta_window_actor_maximize (window_actor, old_rect, new_rect);
|
||||
}
|
||||
|
||||
@@ -1176,10 +1026,6 @@ meta_compositor_unmaximize_window (MetaCompositor *compositor,
|
||||
MetaRectangle *new_rect)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
DEBUG_TRACE ("meta_compositor_unmaximize_window\n");
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
meta_window_actor_unmaximize (window_actor, old_rect, new_rect);
|
||||
}
|
||||
|
||||
@@ -1197,18 +1043,14 @@ meta_compositor_switch_workspace (MetaCompositor *compositor,
|
||||
to_indx = meta_workspace_index (to);
|
||||
from_indx = meta_workspace_index (from);
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_switch_workspace\n");
|
||||
|
||||
if (!info) /* During startup before manage_screen() */
|
||||
return;
|
||||
|
||||
info->switch_workspace_in_progress++;
|
||||
|
||||
if (!info->plugin_mgr ||
|
||||
!meta_plugin_manager_switch_workspace (info->plugin_mgr,
|
||||
from_indx,
|
||||
to_indx,
|
||||
direction))
|
||||
if (!meta_plugin_manager_switch_workspace (info->plugin_mgr,
|
||||
from_indx, to_indx,
|
||||
direction))
|
||||
{
|
||||
info->switch_workspace_in_progress--;
|
||||
|
||||
@@ -1317,8 +1159,6 @@ meta_compositor_sync_stack (MetaCompositor *compositor,
|
||||
GList *old_stack;
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_sync_stack\n");
|
||||
|
||||
/* This is painful because hidden windows that we are in the process
|
||||
* of animating out of existence. They'll be at the bottom of the
|
||||
* stack of X windows, but we want to leave them in their old position
|
||||
@@ -1407,15 +1247,6 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||
gboolean did_placement)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
MetaScreen *screen = meta_window_get_screen (window);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_sync_window_geometry\n");
|
||||
g_return_if_fail (info);
|
||||
|
||||
if (!window_actor)
|
||||
return;
|
||||
|
||||
meta_window_actor_sync_actor_geometry (window_actor, did_placement);
|
||||
}
|
||||
|
||||
@@ -1447,7 +1278,6 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor,
|
||||
Display *xdisplay;
|
||||
Window xwin;
|
||||
|
||||
DEBUG_TRACE ("meta_compositor_sync_screen_size\n");
|
||||
g_return_if_fail (info);
|
||||
|
||||
xdisplay = meta_display_get_xdisplay (display);
|
||||
@@ -1751,10 +1581,6 @@ meta_compositor_show_tile_preview (MetaCompositor *compositor,
|
||||
int tile_monitor_number)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (!info->plugin_mgr)
|
||||
return;
|
||||
|
||||
meta_plugin_manager_show_tile_preview (info->plugin_mgr,
|
||||
window, tile_rect, tile_monitor_number);
|
||||
}
|
||||
@@ -1764,9 +1590,5 @@ meta_compositor_hide_tile_preview (MetaCompositor *compositor,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (!info->plugin_mgr)
|
||||
return;
|
||||
|
||||
meta_plugin_manager_hide_tile_preview (info->plugin_mgr);
|
||||
}
|
||||
|
@@ -100,7 +100,9 @@ meta_plugin_manager_new (MetaScreen *screen)
|
||||
|
||||
plugin_mgr = g_new0 (MetaPluginManager, 1);
|
||||
plugin_mgr->screen = screen;
|
||||
plugin_mgr->plugin = plugin = g_object_new (plugin_type, "screen", screen, NULL);
|
||||
plugin_mgr->plugin = plugin = g_object_new (plugin_type, NULL);
|
||||
|
||||
_meta_plugin_set_screen (plugin, screen);
|
||||
|
||||
klass = META_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
@@ -165,8 +167,6 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
|
||||
retval = TRUE;
|
||||
meta_plugin_manager_kill_window_effects (plugin_mgr,
|
||||
actor);
|
||||
|
||||
_meta_plugin_effect_started (plugin);
|
||||
klass->minimize (plugin, actor);
|
||||
}
|
||||
break;
|
||||
@@ -176,8 +176,6 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
|
||||
retval = TRUE;
|
||||
meta_plugin_manager_kill_window_effects (plugin_mgr,
|
||||
actor);
|
||||
|
||||
_meta_plugin_effect_started (plugin);
|
||||
klass->map (plugin, actor);
|
||||
}
|
||||
break;
|
||||
@@ -185,7 +183,6 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
|
||||
if (klass->destroy)
|
||||
{
|
||||
retval = TRUE;
|
||||
_meta_plugin_effect_started (plugin);
|
||||
klass->destroy (plugin, actor);
|
||||
}
|
||||
break;
|
||||
@@ -230,8 +227,6 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
|
||||
retval = TRUE;
|
||||
meta_plugin_manager_kill_window_effects (plugin_mgr,
|
||||
actor);
|
||||
|
||||
_meta_plugin_effect_started (plugin);
|
||||
klass->maximize (plugin, actor,
|
||||
target_x, target_y,
|
||||
target_width, target_height);
|
||||
@@ -243,8 +238,6 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
|
||||
retval = TRUE;
|
||||
meta_plugin_manager_kill_window_effects (plugin_mgr,
|
||||
actor);
|
||||
|
||||
_meta_plugin_effect_started (plugin);
|
||||
klass->unmaximize (plugin, actor,
|
||||
target_x, target_y,
|
||||
target_width, target_height);
|
||||
@@ -283,8 +276,6 @@ meta_plugin_manager_switch_workspace (MetaPluginManager *plugin_mgr,
|
||||
{
|
||||
retval = TRUE;
|
||||
meta_plugin_manager_kill_switch_workspace (plugin_mgr);
|
||||
|
||||
_meta_plugin_effect_started (plugin);
|
||||
klass->switch_workspace (plugin, from, to, direction);
|
||||
}
|
||||
|
||||
|
@@ -47,91 +47,15 @@ G_DEFINE_ABSTRACT_TYPE (MetaPlugin, meta_plugin, G_TYPE_OBJECT);
|
||||
#define META_PLUGIN_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_PLUGIN, MetaPluginPrivate))
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_SCREEN,
|
||||
PROP_DEBUG_MODE,
|
||||
};
|
||||
|
||||
struct _MetaPluginPrivate
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
gint running;
|
||||
gboolean debug : 1;
|
||||
MetaScreen *screen;
|
||||
};
|
||||
|
||||
static void
|
||||
meta_plugin_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaPluginPrivate *priv = META_PLUGIN (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SCREEN:
|
||||
priv->screen = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_DEBUG_MODE:
|
||||
priv->debug = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_plugin_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaPluginPrivate *priv = META_PLUGIN (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SCREEN:
|
||||
g_value_set_object (value, priv->screen);
|
||||
break;
|
||||
case PROP_DEBUG_MODE:
|
||||
g_value_set_boolean (value, priv->debug);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
meta_plugin_class_init (MetaPluginClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = meta_plugin_set_property;
|
||||
gobject_class->get_property = meta_plugin_get_property;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_SCREEN,
|
||||
g_param_spec_object ("screen",
|
||||
"MetaScreen",
|
||||
"MetaScreen",
|
||||
META_TYPE_SCREEN,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_DEBUG_MODE,
|
||||
g_param_spec_boolean ("debug-mode",
|
||||
"Debug Mode",
|
||||
"Debug Mode",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (MetaPluginPrivate));
|
||||
g_type_class_add_private (klass, sizeof (MetaPluginPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -140,22 +64,6 @@ meta_plugin_init (MetaPlugin *self)
|
||||
self->priv = META_PLUGIN_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_plugin_running (MetaPlugin *plugin)
|
||||
{
|
||||
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
|
||||
|
||||
return (priv->running > 0);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_plugin_debug_mode (MetaPlugin *plugin)
|
||||
{
|
||||
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
|
||||
|
||||
return priv->debug;
|
||||
}
|
||||
|
||||
const MetaPluginInfo *
|
||||
meta_plugin_get_info (MetaPlugin *plugin)
|
||||
{
|
||||
@@ -167,21 +75,6 @@ meta_plugin_get_info (MetaPlugin *plugin)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* _meta_plugin_effect_started:
|
||||
* @plugin: the plugin
|
||||
*
|
||||
* Mark that an effect has started for the plugin. This is called
|
||||
* internally by MetaPluginManager.
|
||||
*/
|
||||
void
|
||||
_meta_plugin_effect_started (MetaPlugin *plugin)
|
||||
{
|
||||
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
|
||||
|
||||
priv->running++;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_meta_plugin_xevent_filter (MetaPlugin *plugin,
|
||||
XEvent *xev)
|
||||
@@ -208,15 +101,8 @@ void
|
||||
meta_plugin_switch_workspace_completed (MetaPlugin *plugin)
|
||||
{
|
||||
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
|
||||
|
||||
MetaScreen *screen = priv->screen;
|
||||
|
||||
if (priv->running-- < 0)
|
||||
{
|
||||
g_warning ("Error in running effect accounting, adjusting.");
|
||||
priv->running = 0;
|
||||
}
|
||||
|
||||
meta_switch_workspace_completed (screen);
|
||||
}
|
||||
|
||||
@@ -225,26 +111,6 @@ meta_plugin_window_effect_completed (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor,
|
||||
unsigned long event)
|
||||
{
|
||||
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
|
||||
|
||||
if (priv->running-- < 0)
|
||||
{
|
||||
g_warning ("Error in running effect accounting, adjusting.");
|
||||
priv->running = 0;
|
||||
}
|
||||
|
||||
if (!actor)
|
||||
{
|
||||
const MetaPluginInfo *info;
|
||||
const gchar *name = NULL;
|
||||
|
||||
if (plugin && (info = meta_plugin_get_info (plugin)))
|
||||
name = info->name;
|
||||
|
||||
g_warning ("Plugin [%s] passed NULL for actor!",
|
||||
name ? name : "unknown");
|
||||
}
|
||||
|
||||
meta_window_actor_effect_completed (actor, event);
|
||||
}
|
||||
|
||||
@@ -339,9 +205,7 @@ meta_plugin_end_modal (MetaPlugin *plugin,
|
||||
* meta_plugin_get_screen:
|
||||
* @plugin: a #MetaPlugin
|
||||
*
|
||||
* Gets the #MetaScreen corresponding to a plugin. Each plugin instance
|
||||
* is associated with exactly one screen; if Metacity is managing
|
||||
* multiple screens, multiple plugin instances will be created.
|
||||
* Gets the #MetaScreen corresponding to a plugin.
|
||||
*
|
||||
* Return value: (transfer none): the #MetaScreen for the plugin
|
||||
*/
|
||||
@@ -353,6 +217,15 @@ meta_plugin_get_screen (MetaPlugin *plugin)
|
||||
return priv->screen;
|
||||
}
|
||||
|
||||
void
|
||||
_meta_plugin_set_screen (MetaPlugin *plugin,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
|
||||
|
||||
priv->screen = screen;
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_complete_display_change (MetaPlugin *plugin,
|
||||
gboolean ok)
|
||||
|
@@ -28,17 +28,31 @@
|
||||
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include "meta-shaped-texture-private.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
struct _MetaSurfaceActorWaylandPrivate
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
MetaWaylandBuffer *buffer;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
};
|
||||
typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaSurfaceActorWayland, meta_surface_actor_wayland, META_TYPE_SURFACE_ACTOR)
|
||||
|
||||
static void
|
||||
meta_surface_actor_handle_buffer_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = wl_container_of (listener, priv, buffer_destroy_listener);
|
||||
|
||||
/* If the buffer is destroyed while we're attached to it,
|
||||
* we want to unset priv->buffer so we don't access freed
|
||||
* memory. Keep the texture set however so the user doesn't
|
||||
* see the window disappear. */
|
||||
priv->buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor,
|
||||
int x, int y, int width, int height)
|
||||
@@ -46,16 +60,19 @@ meta_surface_actor_wayland_process_damage (MetaSurfaceActor *actor,
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
|
||||
|
||||
struct wl_resource *resource = priv->buffer->resource;
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource);
|
||||
|
||||
if (shm_buffer)
|
||||
if (priv->buffer)
|
||||
{
|
||||
CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture);
|
||||
cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL);
|
||||
}
|
||||
struct wl_resource *resource = priv->buffer->resource;
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (resource);
|
||||
|
||||
meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height);
|
||||
if (shm_buffer)
|
||||
{
|
||||
CoglTexture2D *texture = COGL_TEXTURE_2D (priv->buffer->texture);
|
||||
cogl_wayland_texture_set_region_from_shm_buffer (texture, x, y, width, height, shm_buffer, x, y, 0, NULL);
|
||||
}
|
||||
|
||||
meta_surface_actor_update_area (META_SURFACE_ACTOR (self), x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -66,8 +83,21 @@ meta_surface_actor_wayland_pre_paint (MetaSurfaceActor *actor)
|
||||
static gboolean
|
||||
meta_surface_actor_wayland_is_argb32 (MetaSurfaceActor *actor)
|
||||
{
|
||||
/* XXX -- look at the SHM buffer format. */
|
||||
return TRUE;
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (actor);
|
||||
CoglTexture *texture = meta_shaped_texture_get_texture (stex);
|
||||
|
||||
switch (cogl_texture_get_components (texture))
|
||||
{
|
||||
case COGL_TEXTURE_COMPONENTS_A:
|
||||
case COGL_TEXTURE_COMPONENTS_RGBA:
|
||||
return TRUE;
|
||||
case COGL_TEXTURE_COMPONENTS_RG:
|
||||
case COGL_TEXTURE_COMPONENTS_RGB:
|
||||
case COGL_TEXTURE_COMPONENTS_DEPTH:
|
||||
return FALSE;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -126,6 +156,9 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
|
||||
static void
|
||||
meta_surface_actor_wayland_init (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
|
||||
|
||||
priv->buffer_destroy_listener.notify = meta_surface_actor_handle_buffer_destroy;
|
||||
}
|
||||
|
||||
MetaSurfaceActor *
|
||||
@@ -148,10 +181,16 @@ meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
|
||||
if (priv->buffer)
|
||||
wl_list_remove (&priv->buffer_destroy_listener.link);
|
||||
|
||||
priv->buffer = buffer;
|
||||
|
||||
if (buffer)
|
||||
meta_shaped_texture_set_texture (stex, buffer->texture);
|
||||
if (priv->buffer)
|
||||
{
|
||||
wl_signal_add (&priv->buffer->destroy_signal, &priv->buffer_destroy_listener);
|
||||
meta_shaped_texture_set_texture (stex, priv->buffer->texture);
|
||||
}
|
||||
else
|
||||
meta_shaped_texture_set_texture (stex, NULL);
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "meta-surface-actor.h"
|
||||
|
||||
#include "meta-wayland.h"
|
||||
#include "wayland/meta-wayland.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#include "frame.h"
|
||||
#include <meta/window.h>
|
||||
#include <meta/meta-shaped-texture.h>
|
||||
#include "xprops.h"
|
||||
|
||||
#include "compositor-private.h"
|
||||
#include "meta-shaped-texture-private.h"
|
||||
@@ -30,11 +29,12 @@
|
||||
#include "region-utils.h"
|
||||
#include "monitor-private.h"
|
||||
#include "meta-cullable.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
#include "meta-surface-actor.h"
|
||||
#include "meta-surface-actor-x11.h"
|
||||
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
struct _MetaWindowActorPrivate
|
||||
{
|
||||
MetaWindow *window;
|
||||
@@ -714,7 +714,7 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
/* Leaving out shadows for maximized and fullscreen windows is an effeciency
|
||||
* win and also prevents the unsightly effect of the shadow of maximized
|
||||
* window appearing on an adjacent window */
|
||||
if ((meta_window_get_maximized (priv->window) == (META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL)) ||
|
||||
if ((meta_window_get_maximized (priv->window) == META_MAXIMIZE_BOTH) ||
|
||||
meta_window_is_fullscreen (priv->window))
|
||||
return FALSE;
|
||||
|
||||
@@ -968,9 +968,6 @@ start_simple_effect (MetaWindowActor *self,
|
||||
gint *counter = NULL;
|
||||
gboolean use_freeze_thaw = FALSE;
|
||||
|
||||
if (!info->plugin_mgr)
|
||||
return FALSE;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case META_PLUGIN_MINIMIZE:
|
||||
@@ -1299,8 +1296,7 @@ meta_window_actor_maximize (MetaWindowActor *self,
|
||||
self->priv->maximize_in_progress++;
|
||||
meta_window_actor_freeze (self);
|
||||
|
||||
if (!info->plugin_mgr ||
|
||||
!meta_plugin_manager_event_maximize (info->plugin_mgr,
|
||||
if (!meta_plugin_manager_event_maximize (info->plugin_mgr,
|
||||
self,
|
||||
META_PLUGIN_MAXIMIZE,
|
||||
new_rect->x, new_rect->y,
|
||||
@@ -1328,8 +1324,7 @@ meta_window_actor_unmaximize (MetaWindowActor *self,
|
||||
self->priv->unmaximize_in_progress++;
|
||||
meta_window_actor_freeze (self);
|
||||
|
||||
if (!info->plugin_mgr ||
|
||||
!meta_plugin_manager_event_maximize (info->plugin_mgr,
|
||||
if (!meta_plugin_manager_event_maximize (info->plugin_mgr,
|
||||
self,
|
||||
META_PLUGIN_UNMAXIMIZE,
|
||||
new_rect->x, new_rect->y,
|
||||
|
@@ -58,88 +58,6 @@
|
||||
#include <canberra-gtk.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* bell_flash_screen:
|
||||
* @display: The display which owns the screen (rather redundant)
|
||||
* @screen: The screen to flash
|
||||
*
|
||||
* Flashes one entire screen. This is done by making a window the size of the
|
||||
* whole screen (or reusing the old one, if it's still around), mapping it,
|
||||
* painting it white and then black, and then unmapping it. We set saveunder so
|
||||
* that all the windows behind it come back immediately.
|
||||
*
|
||||
* Unlike frame flashes, we don't do fullscreen flashes with a timeout; rather,
|
||||
* we do them in one go, because we don't have to rely on the theme code
|
||||
* redrawing the frame for us in order to do the flash.
|
||||
*/
|
||||
/*
|
||||
* Bug: The way I read it, this appears not to do the flash
|
||||
* the first time we flash a particular display. Am I wrong?
|
||||
*
|
||||
* Bug: This appears to destroy our current XSync status.
|
||||
*/
|
||||
static void
|
||||
bell_flash_screen (MetaDisplay *display,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
Window root = screen->xroot;
|
||||
int width = screen->rect.width;
|
||||
int height = screen->rect.height;
|
||||
|
||||
if (screen->flash_window == None)
|
||||
{
|
||||
Visual *visual = (Visual *)CopyFromParent;
|
||||
XSetWindowAttributes xswa;
|
||||
int depth = CopyFromParent;
|
||||
xswa.save_under = True;
|
||||
xswa.override_redirect = True;
|
||||
/*
|
||||
* TODO: use XGetVisualInfo and determine which is an
|
||||
* overlay, if one is present, and use the Overlay visual
|
||||
* for this window (for performance reasons).
|
||||
* Not sure how to tell this yet...
|
||||
*/
|
||||
screen->flash_window = XCreateWindow (display->xdisplay, root,
|
||||
0, 0, width, height,
|
||||
0, depth,
|
||||
InputOutput,
|
||||
visual,
|
||||
/* note: XSun doesn't like SaveUnder here */
|
||||
CWSaveUnder | CWOverrideRedirect,
|
||||
&xswa);
|
||||
XSelectInput (display->xdisplay, screen->flash_window, ExposureMask);
|
||||
XMapWindow (display->xdisplay, screen->flash_window);
|
||||
XSync (display->xdisplay, False);
|
||||
XFlush (display->xdisplay);
|
||||
XUnmapWindow (display->xdisplay, screen->flash_window);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* just draw something in the window */
|
||||
GC gc = XCreateGC (display->xdisplay, screen->flash_window, 0, NULL);
|
||||
XMapWindow (display->xdisplay, screen->flash_window);
|
||||
XSetForeground (display->xdisplay, gc,
|
||||
WhitePixel (display->xdisplay,
|
||||
XScreenNumberOfScreen (screen->xscreen)));
|
||||
XFillRectangle (display->xdisplay, screen->flash_window, gc,
|
||||
0, 0, width, height);
|
||||
XSetForeground (display->xdisplay, gc,
|
||||
BlackPixel (display->xdisplay,
|
||||
XScreenNumberOfScreen (screen->xscreen)));
|
||||
XFillRectangle (display->xdisplay, screen->flash_window, gc,
|
||||
0, 0, width, height);
|
||||
XFlush (display->xdisplay);
|
||||
XSync (display->xdisplay, False);
|
||||
XUnmapWindow (display->xdisplay, screen->flash_window);
|
||||
XFreeGC (display->xdisplay, gc);
|
||||
}
|
||||
|
||||
if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK &&
|
||||
!display->mouse_mode)
|
||||
meta_display_increment_focus_sentinel (display);
|
||||
XFlush (display->xdisplay);
|
||||
}
|
||||
|
||||
/**
|
||||
* bell_flash_fullscreen:
|
||||
* @display: The display the event came in on
|
||||
@@ -164,12 +82,7 @@ bell_flash_fullscreen (MetaDisplay *display,
|
||||
{
|
||||
screen = meta_display_screen_for_xwindow (display, xkb_bell_ev->window);
|
||||
if (screen)
|
||||
{
|
||||
if (display->compositor)
|
||||
meta_compositor_flash_screen (display->compositor, screen);
|
||||
else
|
||||
bell_flash_screen (display, screen);
|
||||
}
|
||||
meta_compositor_flash_screen (display->compositor, screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -177,10 +90,7 @@ bell_flash_fullscreen (MetaDisplay *display,
|
||||
while (screen_list)
|
||||
{
|
||||
screen = (MetaScreen *) screen_list->data;
|
||||
if (display->compositor)
|
||||
meta_compositor_flash_screen (display->compositor, screen);
|
||||
else
|
||||
bell_flash_screen (display, screen);
|
||||
meta_compositor_flash_screen (display->compositor, screen);
|
||||
screen_list = screen_list->next;
|
||||
}
|
||||
}
|
||||
|
@@ -425,8 +425,9 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
* the monitor.
|
||||
*/
|
||||
if (meta_prefs_get_force_fullscreen() &&
|
||||
window->client_type != META_WINDOW_CLIENT_TYPE_WAYLAND &&
|
||||
!window->hide_titlebar_when_maximized &&
|
||||
window->decorated &&
|
||||
(window->decorated || !meta_window_is_client_decorated (window)) &&
|
||||
meta_rectangle_equal (new, &monitor_info->rect) &&
|
||||
window->has_fullscreen_func &&
|
||||
!window->fullscreen)
|
||||
@@ -491,12 +492,17 @@ place_window_if_needed(MetaWindow *window,
|
||||
!window->minimized &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
MetaRectangle orig_rect;
|
||||
MetaRectangle placed_rect;
|
||||
MetaWorkspace *cur_workspace;
|
||||
const MetaMonitorInfo *monitor_info;
|
||||
|
||||
meta_window_get_frame_rect (window, &placed_rect);
|
||||
meta_window_place (window, info->orig.x, info->orig.y,
|
||||
|
||||
orig_rect = info->orig;
|
||||
extend_by_frame (window, &orig_rect);
|
||||
|
||||
meta_window_place (window, orig_rect.x, orig_rect.y,
|
||||
&placed_rect.x, &placed_rect.y);
|
||||
did_placement = TRUE;
|
||||
|
||||
|
@@ -27,16 +27,6 @@
|
||||
#include "window-private.h"
|
||||
#include "frame.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
||||
META_DO_GRAVITY_ADJUST = 1 << 1,
|
||||
META_IS_USER_ACTION = 1 << 2,
|
||||
META_IS_MOVE_ACTION = 1 << 3,
|
||||
META_IS_RESIZE_ACTION = 1 << 4,
|
||||
META_IS_WAYLAND_RESIZE = 1 << 5
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
void meta_window_constrain (MetaWindow *window,
|
||||
MetaMoveResizeFlags flags,
|
||||
int resize_gravity,
|
||||
|
@@ -328,8 +328,7 @@ meta_core_maximize (Display *xdisplay,
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
|
||||
meta_window_maximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -342,11 +341,9 @@ meta_core_toggle_maximize_vertically (Display *xdisplay,
|
||||
meta_window_raise (window);
|
||||
|
||||
if (META_WINDOW_MAXIMIZED_VERTICALLY (window))
|
||||
meta_window_unmaximize (window,
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL);
|
||||
else
|
||||
meta_window_maximize (window,
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
meta_window_maximize (window, META_MAXIMIZE_VERTICAL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -359,11 +356,9 @@ meta_core_toggle_maximize_horizontally (Display *xdisplay,
|
||||
meta_window_raise (window);
|
||||
|
||||
if (META_WINDOW_MAXIMIZED_HORIZONTALLY (window))
|
||||
meta_window_unmaximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL);
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL);
|
||||
else
|
||||
meta_window_maximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL);
|
||||
meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -376,11 +371,9 @@ meta_core_toggle_maximize (Display *xdisplay,
|
||||
meta_window_raise (window);
|
||||
|
||||
if (META_WINDOW_MAXIMIZED (window))
|
||||
meta_window_unmaximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||
else
|
||||
meta_window_maximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -392,8 +385,7 @@ meta_core_unmaximize (Display *xdisplay,
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
|
||||
meta_window_unmaximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -726,16 +718,6 @@ meta_core_set_screen_cursor (Display *xdisplay,
|
||||
meta_frame_set_screen_cursor (window->frame, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_increment_event_serial (Display *xdisplay)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
meta_display_increment_event_serial (display);
|
||||
}
|
||||
|
||||
void
|
||||
meta_invalidate_default_icons (void)
|
||||
{
|
||||
|
@@ -193,12 +193,6 @@ void meta_core_set_screen_cursor (Display *xdisplay,
|
||||
Window frame_on_screen,
|
||||
MetaCursor cursor);
|
||||
|
||||
/* Used because we ignore EnterNotify when a window is unmapped that
|
||||
* really shouldn't cause focus changes, by comparing the event serial
|
||||
* of the EnterNotify and the UnmapNotify.
|
||||
*/
|
||||
void meta_core_increment_event_serial (Display *display);
|
||||
|
||||
void meta_invalidate_default_icons (void);
|
||||
|
||||
void meta_core_add_old_event_mask (Display *xdisplay,
|
||||
|
@@ -37,7 +37,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "meta-wayland-surface.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
static void meta_window_present_delete_dialog (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
@@ -143,31 +143,7 @@ void
|
||||
meta_window_delete (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
meta_error_trap_push (window->display);
|
||||
if (window->delete_window)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Deleting %s with delete_window request\n",
|
||||
window->desc);
|
||||
meta_window_send_icccm_message (window,
|
||||
window->display->atom_WM_DELETE_WINDOW,
|
||||
timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Deleting %s with explicit kill\n",
|
||||
window->desc);
|
||||
XKillClient (window->display->xdisplay, window->xwindow);
|
||||
}
|
||||
meta_error_trap_pop (window->display);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_wayland_surface_delete (window->surface);
|
||||
}
|
||||
META_WINDOW_GET_CLASS (window)->delete (window, timestamp);
|
||||
|
||||
meta_window_check_alive (window, timestamp);
|
||||
|
||||
@@ -200,33 +176,10 @@ meta_window_delete (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
meta_window_kill (MetaWindow *window)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Killing %s brutally\n",
|
||||
window->desc);
|
||||
|
||||
if (!meta_window_is_remote (window) &&
|
||||
window->net_wm_pid > 0)
|
||||
{
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Killing %s with kill()\n",
|
||||
window->desc);
|
||||
|
||||
if (kill (window->net_wm_pid, 9) < 0)
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Failed to signal %s: %s\n",
|
||||
window->desc, strerror (errno));
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Disconnecting %s with XKillClient()\n",
|
||||
window->desc);
|
||||
meta_error_trap_push (window->display);
|
||||
XKillClient (window->display->xdisplay, window->xwindow);
|
||||
meta_error_trap_pop (window->display);
|
||||
META_WINDOW_GET_CLASS (window)->kill (window);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -261,8 +214,7 @@ meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
if (w->xtransient_for == window->xwindow &&
|
||||
w->res_class &&
|
||||
if (w->transient_for == window && w->res_class &&
|
||||
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
|
||||
{
|
||||
meta_window_activate (w, timestamp);
|
||||
|
@@ -145,8 +145,6 @@ struct _MetaDisplay
|
||||
* multiple events with the same serial.
|
||||
*/
|
||||
guint focused_by_us : 1;
|
||||
|
||||
guint static_gravity_works : 1;
|
||||
|
||||
/*< private-ish >*/
|
||||
guint error_trap_synced_at_last_pop : 1;
|
||||
@@ -456,6 +454,9 @@ int meta_resize_gravity_from_grab_op (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_moving (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_resizing (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_mouse (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_clicking (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_wayland (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_keyboard (MetaGrabOp op);
|
||||
|
||||
void meta_display_devirtualize_modifiers (MetaDisplay *display,
|
||||
MetaVirtualModifier modifiers,
|
||||
@@ -488,4 +489,16 @@ void meta_display_set_input_focus_xwindow (MetaDisplay *display,
|
||||
Window window,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_display_sync_wayland_input_focus (MetaDisplay *display);
|
||||
void meta_display_update_focus_window (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
Window xwindow,
|
||||
gulong serial,
|
||||
gboolean focused_by_us);
|
||||
|
||||
void meta_display_sanity_check_timestamps (MetaDisplay *display,
|
||||
guint32 timestamp);
|
||||
gboolean meta_display_timestamp_too_old (MetaDisplay *display,
|
||||
guint32 *timestamp);
|
||||
|
||||
#endif
|
||||
|
2417
src/core/display.c
2417
src/core/display.c
File diff suppressed because it is too large
Load Diff
2263
src/core/events.c
Normal file
2263
src/core/events.c
Normal file
File diff suppressed because it is too large
Load Diff
32
src/core/events.h
Normal file
32
src/core/events.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
|
||||
* Copyright (C) 2003, 2004 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <meta/display.h>
|
||||
|
||||
#ifndef META_EVENTS_H
|
||||
#define META_EVENTS_H
|
||||
|
||||
void meta_display_init_events (MetaDisplay *display);
|
||||
void meta_display_free_events (MetaDisplay *display);
|
||||
|
||||
#endif
|
||||
|
@@ -35,8 +35,7 @@
|
||||
ButtonPressMask | ButtonReleaseMask | \
|
||||
PointerMotionMask | PointerMotionHintMask | \
|
||||
EnterWindowMask | LeaveWindowMask | \
|
||||
FocusChangeMask | \
|
||||
ColormapChangeMask)
|
||||
FocusChangeMask)
|
||||
|
||||
void
|
||||
meta_window_ensure_frame (MetaWindow *window)
|
||||
|
@@ -41,7 +41,6 @@
|
||||
#include "screen-private.h"
|
||||
#include <meta/prefs.h>
|
||||
#include "util-private.h"
|
||||
#include "meta-wayland.h"
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <string.h>
|
||||
@@ -52,6 +51,8 @@
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
|
||||
#include "wayland/meta-wayland.h"
|
||||
|
||||
#define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings"
|
||||
#define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings"
|
||||
#define SCHEMA_MUTTER_WAYLAND_KEYBINDINGS "org.gnome.mutter.wayland.keybindings"
|
||||
@@ -1679,8 +1680,13 @@ process_event (MetaDisplay *display,
|
||||
event->hardware_keycode,
|
||||
event->modifier_state);
|
||||
if (!binding ||
|
||||
(!window && binding->flags & META_KEY_BINDING_PER_WINDOW) ||
|
||||
meta_compositor_filter_keybinding (display->compositor, screen, binding))
|
||||
(!window && binding->flags & META_KEY_BINDING_PER_WINDOW))
|
||||
goto not_found;
|
||||
|
||||
/* If the compositor filtered out the keybindings, that
|
||||
* means they don't want the binding to trigger, so we do
|
||||
* the same thing as if the binding didn't exist. */
|
||||
if (meta_compositor_filter_keybinding (display->compositor, screen, binding))
|
||||
goto not_found;
|
||||
|
||||
if (binding->handler == NULL)
|
||||
@@ -1975,9 +1981,7 @@ process_mouse_move_resize_grab (MetaDisplay *display,
|
||||
* moveresize now to get the position back to the original.
|
||||
*/
|
||||
if (window->shaken_loose || window->tile_mode == META_TILE_MAXIMIZED)
|
||||
meta_window_maximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL |
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
else if (window->tile_mode != META_TILE_NONE)
|
||||
meta_window_tile (window);
|
||||
else
|
||||
@@ -2038,9 +2042,7 @@ process_keyboard_move_grab (MetaDisplay *display,
|
||||
* now to get the position back to the original.
|
||||
*/
|
||||
if (window->shaken_loose)
|
||||
meta_window_maximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL |
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
else
|
||||
meta_window_move_resize (display->grab_window,
|
||||
TRUE,
|
||||
@@ -2901,11 +2903,9 @@ handle_toggle_tiled (MetaDisplay *display,
|
||||
: META_TILE_NONE;
|
||||
|
||||
if (window->saved_maximize)
|
||||
meta_window_maximize (window, META_MAXIMIZE_VERTICAL |
|
||||
META_MAXIMIZE_HORIZONTAL);
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
else
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL |
|
||||
META_MAXIMIZE_HORIZONTAL);
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
else if (meta_window_can_tile_side_by_side (window))
|
||||
{
|
||||
@@ -2931,13 +2931,9 @@ handle_toggle_maximized (MetaDisplay *display,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (META_WINDOW_MAXIMIZED (window))
|
||||
meta_window_unmaximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL |
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||
else if (window->has_maximize_func)
|
||||
meta_window_maximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL |
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2949,9 +2945,7 @@ handle_maximize (MetaDisplay *display,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->has_maximize_func)
|
||||
meta_window_maximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL |
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
meta_window_maximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2963,9 +2957,7 @@ handle_unmaximize (MetaDisplay *display,
|
||||
gpointer dummy)
|
||||
{
|
||||
if (window->maximized_vertically || window->maximized_horizontally)
|
||||
meta_window_unmaximize (window,
|
||||
META_MAXIMIZE_HORIZONTAL |
|
||||
META_MAXIMIZE_VERTICAL);
|
||||
meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3916,6 +3908,7 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
|
||||
g_object_unref (common_keybindings);
|
||||
g_object_unref (mutter_keybindings);
|
||||
g_object_unref (mutter_wayland_keybindings);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -42,7 +42,7 @@
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _SVID_SOURCE /* for putenv() and some signal-related functions */
|
||||
#define _XOPEN_SOURCE /* for putenv() and some signal-related functions */
|
||||
|
||||
#include <config.h>
|
||||
#include <meta/main.h>
|
||||
@@ -50,10 +50,8 @@
|
||||
#include "display-private.h"
|
||||
#include <meta/errors.h>
|
||||
#include "ui.h"
|
||||
#include "session.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/compositor.h>
|
||||
#include "meta-wayland.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <glib-unix.h>
|
||||
@@ -79,6 +77,10 @@
|
||||
#include <girepository.h>
|
||||
#endif
|
||||
|
||||
#include "x11/session.h"
|
||||
|
||||
#include "wayland/meta-wayland.h"
|
||||
|
||||
/*
|
||||
* The exit code we'll return to our parent process when we eventually die.
|
||||
*/
|
||||
@@ -190,6 +192,7 @@ static gboolean opt_replace_wm;
|
||||
static gboolean opt_disable_sm;
|
||||
static gboolean opt_sync;
|
||||
static gboolean opt_wayland;
|
||||
static gboolean opt_display_server;
|
||||
|
||||
static GOptionEntry meta_options[] = {
|
||||
{
|
||||
@@ -233,6 +236,11 @@ static GOptionEntry meta_options[] = {
|
||||
N_("Run as a wayland compositor"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"display-server", 0, 0, G_OPTION_ARG_NONE,
|
||||
&opt_display_server,
|
||||
N_("Run as a full display server, rather than nested")
|
||||
},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -401,8 +409,7 @@ meta_init (void)
|
||||
if (g_getenv ("MUTTER_DEBUG"))
|
||||
meta_set_debugging (TRUE);
|
||||
|
||||
/* We consider running from mutter-launch equivalent to running from bare metal. */
|
||||
if (getenv ("WESTON_LAUNCHER_SOCK"))
|
||||
if (opt_display_server)
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
|
||||
|
||||
meta_set_is_wayland_compositor (opt_wayland);
|
||||
@@ -497,6 +504,32 @@ meta_register_with_session (void)
|
||||
g_free (opt_client_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_activate_session:
|
||||
*
|
||||
* Tells mutter to activate the session. When mutter is a
|
||||
* Wayland compositor, this tells logind to switch over to
|
||||
* the new session.
|
||||
*/
|
||||
gboolean
|
||||
meta_activate_session (void)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
GError *error = NULL;
|
||||
|
||||
if (!meta_wayland_compositor_activate_session (compositor, &error))
|
||||
{
|
||||
g_warning ("Could not activate session: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_run: (skip)
|
||||
*
|
||||
|
@@ -43,4 +43,7 @@ void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||
int new_x,
|
||||
int new_y);
|
||||
void meta_cursor_tracker_paint (MetaCursorTracker *tracker);
|
||||
|
||||
void meta_cursor_tracker_force_update (MetaCursorTracker *tracker);
|
||||
|
||||
#endif
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include <gbm.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
@@ -46,9 +47,10 @@
|
||||
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "screen-private.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include "monitor-private.h"
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X 7
|
||||
#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y 4
|
||||
|
||||
@@ -569,6 +571,9 @@ make_wayland_cursor_tracker (MetaScreen *screen)
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
compositor->seat->cursor_tracker = self;
|
||||
meta_cursor_tracker_update_position (self,
|
||||
wl_fixed_to_int (compositor->seat->pointer.x),
|
||||
wl_fixed_to_int (compositor->seat->pointer.y));
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL)
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
|
||||
@@ -1074,12 +1079,13 @@ get_pointer_position_gdk (int *x,
|
||||
GdkScreen *gscreen;
|
||||
|
||||
gmanager = gdk_display_get_device_manager (gdk_display_get_default ());
|
||||
gdevice = gdk_device_manager_get_client_pointer (gmanager);
|
||||
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
|
||||
|
||||
gdk_device_get_position (gdevice, &gscreen, x, y);
|
||||
gdk_device_get_state (gdevice,
|
||||
gdk_screen_get_root_window (gscreen),
|
||||
NULL, (GdkModifierType*)mods);
|
||||
if (mods)
|
||||
gdk_device_get_state (gdevice,
|
||||
gdk_screen_get_root_window (gscreen),
|
||||
NULL, (GdkModifierType*)mods);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1095,9 +1101,12 @@ get_pointer_position_clutter (int *x,
|
||||
cdevice = clutter_device_manager_get_core_device (cmanager, CLUTTER_POINTER_DEVICE);
|
||||
|
||||
clutter_input_device_get_coords (cdevice, NULL, &point);
|
||||
*x = point.x;
|
||||
*y = point.y;
|
||||
*mods = clutter_input_device_get_modifier_state (cdevice);
|
||||
if (x)
|
||||
*x = point.x;
|
||||
if (y)
|
||||
*y = point.y;
|
||||
if (mods)
|
||||
*mods = clutter_input_device_get_modifier_state (cdevice);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1139,3 +1148,12 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
|
||||
tracker->screen->xroot);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_force_update (MetaCursorTracker *tracker)
|
||||
{
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
update_hw_cursor (tracker);
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
@@ -344,7 +344,7 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
|
||||
/* denied_focus_and_not_transient is only set when focus_window != NULL */
|
||||
|
||||
if (window->denied_focus_and_not_transient &&
|
||||
window->wm_state_modal && /* FIXME: Maybe do this for all transients? */
|
||||
window->type == META_WINDOW_MODAL_DIALOG &&
|
||||
meta_window_same_application (window, focus_window) &&
|
||||
window_overlaps_focus_window (window))
|
||||
{
|
||||
@@ -610,7 +610,7 @@ meta_window_place (MetaWindow *window,
|
||||
meta_topic (META_DEBUG_PLACEMENT, "Placing window %s\n", window->desc);
|
||||
|
||||
windows = NULL;
|
||||
|
||||
|
||||
switch (window->type)
|
||||
{
|
||||
/* Run placement algorithm on these. */
|
||||
@@ -638,7 +638,7 @@ meta_window_place (MetaWindow *window,
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
goto done_no_constraints;
|
||||
}
|
||||
|
||||
|
||||
if (meta_prefs_get_disable_workarounds ())
|
||||
{
|
||||
switch (window->type)
|
||||
@@ -699,18 +699,11 @@ meta_window_place (MetaWindow *window,
|
||||
goto done_no_constraints;
|
||||
}
|
||||
}
|
||||
|
||||
if ((window->type == META_WINDOW_DIALOG ||
|
||||
window->type == META_WINDOW_MODAL_DIALOG) &&
|
||||
window->xtransient_for != None)
|
||||
{
|
||||
/* Center horizontally, at top of parent vertically */
|
||||
|
||||
MetaWindow *parent;
|
||||
|
||||
parent =
|
||||
meta_display_lookup_x_window (window->display,
|
||||
window->xtransient_for);
|
||||
if (window->type == META_WINDOW_DIALOG ||
|
||||
window->type == META_WINDOW_MODAL_DIALOG)
|
||||
{
|
||||
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||
|
||||
if (parent)
|
||||
{
|
||||
|
@@ -82,8 +82,6 @@ struct _MetaScreen
|
||||
MetaCursorTracker *cursor_tracker;
|
||||
MetaCursor current_cursor;
|
||||
|
||||
Window flash_window;
|
||||
|
||||
Window wm_sn_selection_window;
|
||||
Atom wm_sn_atom;
|
||||
guint32 wm_sn_timestamp;
|
||||
|
@@ -39,11 +39,9 @@
|
||||
#include "workspace-private.h"
|
||||
#include "keybindings-private.h"
|
||||
#include "stack.h"
|
||||
#include "xprops.h"
|
||||
#include <meta/compositor.h>
|
||||
#include "mutter-enum-types.h"
|
||||
#include "core.h"
|
||||
#include "meta-wayland.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
@@ -54,6 +52,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "x11/xprops.h"
|
||||
|
||||
static char* get_screen_name (MetaDisplay *display,
|
||||
int number);
|
||||
|
||||
@@ -690,7 +690,6 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->current_cursor = -1; /* invalid/unset */
|
||||
screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
|
||||
screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
|
||||
screen->flash_window = None;
|
||||
|
||||
screen->wm_sn_selection_window = new_wm_sn_owner;
|
||||
screen->wm_sn_atom = wm_sn_atom;
|
||||
@@ -809,11 +808,8 @@ meta_screen_free (MetaScreen *screen,
|
||||
|
||||
meta_display_grab (display);
|
||||
|
||||
if (screen->display->compositor)
|
||||
{
|
||||
meta_compositor_unmanage_screen (screen->display->compositor,
|
||||
screen);
|
||||
}
|
||||
meta_compositor_unmanage_screen (screen->display->compositor,
|
||||
screen);
|
||||
|
||||
meta_display_unmanage_windows_for_screen (display, screen, timestamp);
|
||||
|
||||
@@ -1514,38 +1510,19 @@ meta_screen_get_mouse_window (MetaScreen *screen,
|
||||
MetaWindow *not_this_one)
|
||||
{
|
||||
MetaWindow *window;
|
||||
Window root_return, child_return;
|
||||
double root_x_return, root_y_return;
|
||||
double win_x_return, win_y_return;
|
||||
XIButtonState buttons;
|
||||
XIModifierState mods;
|
||||
XIGroupState group;
|
||||
int x, y;
|
||||
|
||||
if (not_this_one)
|
||||
meta_topic (META_DEBUG_FOCUS,
|
||||
"Focusing mouse window excluding %s\n", not_this_one->desc);
|
||||
|
||||
meta_error_trap_push (screen->display);
|
||||
XIQueryPointer (screen->display->xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
screen->xroot,
|
||||
&root_return,
|
||||
&child_return,
|
||||
&root_x_return,
|
||||
&root_y_return,
|
||||
&win_x_return,
|
||||
&win_y_return,
|
||||
&buttons,
|
||||
&mods,
|
||||
&group);
|
||||
meta_error_trap_pop (screen->display);
|
||||
free (buttons.mask);
|
||||
meta_cursor_tracker_get_pointer (screen->cursor_tracker,
|
||||
&x, &y, NULL);
|
||||
|
||||
window = meta_stack_get_default_focus_window_at_point (screen->stack,
|
||||
screen->active_workspace,
|
||||
not_this_one,
|
||||
root_x_return,
|
||||
root_y_return);
|
||||
x, y);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -1827,28 +1804,11 @@ meta_screen_get_current_monitor (MetaScreen *screen)
|
||||
|
||||
if (screen->display->monitor_cache_invalidated)
|
||||
{
|
||||
Window root_return, child_return;
|
||||
double win_x_return, win_y_return;
|
||||
double root_x_return, root_y_return;
|
||||
XIButtonState buttons;
|
||||
XIModifierState mods;
|
||||
XIGroupState group;
|
||||
int x, y;
|
||||
|
||||
XIQueryPointer (screen->display->xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
screen->xroot,
|
||||
&root_return,
|
||||
&child_return,
|
||||
&root_x_return,
|
||||
&root_y_return,
|
||||
&win_x_return,
|
||||
&win_y_return,
|
||||
&buttons,
|
||||
&mods,
|
||||
&group);
|
||||
free (buttons.mask);
|
||||
|
||||
meta_screen_get_current_monitor_for_pos (screen, root_x_return, root_y_return);
|
||||
meta_cursor_tracker_get_pointer (screen->cursor_tracker,
|
||||
&x, &y, NULL);
|
||||
meta_screen_get_current_monitor_for_pos (screen, x, y);
|
||||
}
|
||||
|
||||
return screen->last_monitor_index;
|
||||
@@ -2559,10 +2519,9 @@ on_monitors_changed (MetaMonitorManager *manager,
|
||||
&changes);
|
||||
}
|
||||
|
||||
if (screen->display->compositor)
|
||||
meta_compositor_sync_screen_size (screen->display->compositor,
|
||||
screen,
|
||||
screen->rect.width, screen->rect.height);
|
||||
meta_compositor_sync_screen_size (screen->display->compositor,
|
||||
screen,
|
||||
screen->rect.width, screen->rect.height);
|
||||
|
||||
/* Queue a resize on all the windows */
|
||||
meta_screen_foreach_window (screen, meta_screen_resize_func, 0);
|
||||
|
@@ -1245,10 +1245,9 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
|
||||
meta_windows = g_list_prepend (meta_windows, window->wayland.meta_window);
|
||||
}
|
||||
|
||||
if (tracker->screen->display->compositor)
|
||||
meta_compositor_sync_stack (tracker->screen->display->compositor,
|
||||
tracker->screen,
|
||||
meta_windows);
|
||||
meta_compositor_sync_stack (tracker->screen->display->compositor,
|
||||
tracker->screen,
|
||||
meta_windows);
|
||||
g_list_free (meta_windows);
|
||||
|
||||
meta_screen_restacked (tracker->screen);
|
||||
|
@@ -36,6 +36,8 @@
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#include "x11/group-private.h"
|
||||
|
||||
#define WINDOW_HAS_TRANSIENT_TYPE(w) \
|
||||
(w->type == META_WINDOW_DIALOG || \
|
||||
w->type == META_WINDOW_MODAL_DIALOG || \
|
||||
@@ -1705,8 +1707,8 @@ get_default_focus_window (MetaStack *stack,
|
||||
MetaWindow *topmost_in_group;
|
||||
MetaWindow *topmost_overall;
|
||||
MetaGroup *not_this_one_group;
|
||||
GList *link;
|
||||
|
||||
GList *l;
|
||||
|
||||
transient_parent = NULL;
|
||||
topmost_in_group = NULL;
|
||||
topmost_overall = NULL;
|
||||
@@ -1718,49 +1720,49 @@ get_default_focus_window (MetaStack *stack,
|
||||
stack_ensure_sorted (stack);
|
||||
|
||||
/* top of this layer is at the front of the list */
|
||||
link = stack->sorted;
|
||||
|
||||
while (link)
|
||||
for (l = stack->sorted; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *window = link->data;
|
||||
MetaWindow *window = l->data;
|
||||
|
||||
if (window &&
|
||||
window != not_this_one &&
|
||||
(window->unmaps_pending == 0) &&
|
||||
!window->minimized &&
|
||||
(window->input || window->take_focus) &&
|
||||
(workspace == NULL ||
|
||||
meta_window_located_on_workspace (window, workspace)))
|
||||
if (!window)
|
||||
continue;
|
||||
|
||||
if (window == not_this_one)
|
||||
continue;
|
||||
|
||||
if (window->unmaps_pending > 0)
|
||||
continue;
|
||||
|
||||
if (window->minimized)
|
||||
continue;
|
||||
|
||||
if (!(window->input || window->take_focus))
|
||||
continue;
|
||||
|
||||
if (workspace != NULL && !meta_window_located_on_workspace (window, workspace))
|
||||
continue;
|
||||
|
||||
if (must_be_at_point && !window_contains_point (window, root_x, root_y))
|
||||
continue;
|
||||
|
||||
if (not_this_one != NULL)
|
||||
{
|
||||
if (not_this_one != NULL)
|
||||
{
|
||||
if (transient_parent == NULL &&
|
||||
not_this_one->xtransient_for != None &&
|
||||
not_this_one->xtransient_for == window->xwindow &&
|
||||
(!must_be_at_point ||
|
||||
window_contains_point (window, root_x, root_y)))
|
||||
transient_parent = window;
|
||||
if (transient_parent == NULL &&
|
||||
meta_window_get_transient_for (not_this_one) == window)
|
||||
transient_parent = window;
|
||||
|
||||
if (topmost_in_group == NULL &&
|
||||
not_this_one_group != NULL &&
|
||||
not_this_one_group == meta_window_get_group (window) &&
|
||||
(!must_be_at_point ||
|
||||
window_contains_point (window, root_x, root_y)))
|
||||
topmost_in_group = window;
|
||||
}
|
||||
|
||||
if (topmost_overall == NULL &&
|
||||
window->type != META_WINDOW_DOCK &&
|
||||
(!must_be_at_point ||
|
||||
window_contains_point (window, root_x, root_y)))
|
||||
topmost_overall = window;
|
||||
|
||||
/* We could try to bail out early here for efficiency in
|
||||
* some cases, but it's just not worth the code.
|
||||
*/
|
||||
if (topmost_in_group == NULL &&
|
||||
not_this_one_group != NULL &&
|
||||
not_this_one_group == meta_window_get_group (window))
|
||||
topmost_in_group = window;
|
||||
}
|
||||
|
||||
link = link->next;
|
||||
if (topmost_overall == NULL && window->type != META_WINDOW_DOCK)
|
||||
topmost_overall = window;
|
||||
|
||||
/* We could try to bail out early here for efficiency in
|
||||
* some cases, but it's just not worth the code.
|
||||
*/
|
||||
}
|
||||
|
||||
if (transient_parent)
|
||||
|
@@ -38,12 +38,15 @@
|
||||
#include "screen-private.h"
|
||||
#include <meta/util.h>
|
||||
#include "stack.h"
|
||||
#include "iconcache.h"
|
||||
#include <X11/Xutil.h>
|
||||
#include <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include "meta-wayland-types.h"
|
||||
|
||||
#include "x11/iconcache.h"
|
||||
#include "x11/group-private.h"
|
||||
|
||||
#include "wayland/meta-wayland-types.h"
|
||||
|
||||
typedef struct _MetaWindowQueue MetaWindowQueue;
|
||||
|
||||
@@ -62,13 +65,28 @@ typedef enum {
|
||||
|
||||
#define NUMBER_OF_QUEUES 3
|
||||
|
||||
|
||||
typedef enum {
|
||||
_NET_WM_BYPASS_COMPOSITOR_HINT_AUTO = 0,
|
||||
_NET_WM_BYPASS_COMPOSITOR_HINT_ON = 1,
|
||||
_NET_WM_BYPASS_COMPOSITOR_HINT_OFF = 2,
|
||||
} MetaBypassCompositorHintValue;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_IS_CONFIGURE_REQUEST = 1 << 0,
|
||||
META_DO_GRAVITY_ADJUST = 1 << 1,
|
||||
META_IS_USER_ACTION = 1 << 2,
|
||||
META_IS_MOVE_ACTION = 1 << 3,
|
||||
META_IS_RESIZE_ACTION = 1 << 4,
|
||||
META_IS_WAYLAND_RESIZE = 1 << 5
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_MOVE_RESIZE_RESULT_MOVED = 1 << 0,
|
||||
META_MOVE_RESIZE_RESULT_RESIZED = 1 << 1,
|
||||
META_MOVE_RESIZE_RESULT_FRAME_SHAPE_CHANGED = 1 << 2,
|
||||
} MetaMoveResizeResultFlags;
|
||||
|
||||
struct _MetaWindow
|
||||
{
|
||||
@@ -85,19 +103,16 @@ struct _MetaWindow
|
||||
MetaFrame *frame;
|
||||
int depth;
|
||||
Visual *xvisual;
|
||||
Colormap colormap;
|
||||
char *desc; /* used in debug spew */
|
||||
char *title;
|
||||
|
||||
char *icon_name;
|
||||
GdkPixbuf *icon;
|
||||
GdkPixbuf *mini_icon;
|
||||
MetaIconCache icon_cache;
|
||||
Pixmap wm_hints_pixmap;
|
||||
Pixmap wm_hints_mask;
|
||||
|
||||
|
||||
MetaWindowType type;
|
||||
Atom type_atom;
|
||||
|
||||
/* NOTE these five are not in UTF-8, we just treat them as random
|
||||
* binary data
|
||||
@@ -159,8 +174,8 @@ struct _MetaWindow
|
||||
/* Whether we're fullscreen */
|
||||
guint fullscreen : 1;
|
||||
|
||||
/* Whether the urgent flag of WM_HINTS is set */
|
||||
guint wm_hints_urgent : 1;
|
||||
/* Whether the window is marked as urgent */
|
||||
guint urgent : 1;
|
||||
|
||||
/* Whether we have to fullscreen after placement */
|
||||
guint fullscreen_after_placement : 1;
|
||||
@@ -262,13 +277,6 @@ struct _MetaWindow
|
||||
guint has_move_func : 1;
|
||||
guint has_resize_func : 1;
|
||||
guint has_fullscreen_func : 1;
|
||||
|
||||
/* Weird "_NET_WM_STATE_MODAL" flag */
|
||||
guint wm_state_modal : 1;
|
||||
|
||||
/* TRUE if the client forced these on */
|
||||
guint wm_state_skip_taskbar : 1;
|
||||
guint wm_state_skip_pager : 1;
|
||||
|
||||
/* Computed whether to skip taskbar or not */
|
||||
guint skip_taskbar : 1;
|
||||
@@ -322,15 +330,6 @@ struct _MetaWindow
|
||||
|
||||
/* Transient parent is a root window */
|
||||
guint transient_parent_is_root_window : 1;
|
||||
|
||||
/* Info on which props we got our attributes from */
|
||||
guint using_net_wm_name : 1; /* vs. plain wm_name */
|
||||
guint using_net_wm_visible_name : 1; /* tracked so we can clear it */
|
||||
guint using_net_wm_icon_name : 1; /* vs. plain wm_icon_name */
|
||||
guint using_net_wm_visible_icon_name : 1; /* tracked so we can clear it */
|
||||
|
||||
/* icon props have changed */
|
||||
guint need_reread_icon : 1;
|
||||
|
||||
/* if TRUE, window was maximized at start of current grab op */
|
||||
guint shaken_loose : 1;
|
||||
@@ -408,6 +407,12 @@ struct _MetaWindow
|
||||
*/
|
||||
MetaRectangle rect;
|
||||
|
||||
/* The size and position we want the window to be (i.e. what we last asked
|
||||
* the client to configure).
|
||||
* This is only used for wayland clients.
|
||||
*/
|
||||
MetaRectangle expected_rect;
|
||||
|
||||
gboolean has_custom_frame_extents;
|
||||
GtkBorder custom_frame_extents;
|
||||
|
||||
@@ -425,8 +430,6 @@ struct _MetaWindow
|
||||
* gives the position and size of the client window (i.e. ignoring
|
||||
* the frame).
|
||||
*
|
||||
* Position valid if user_has_moved, size valid if user_has_resized
|
||||
*
|
||||
* Position always in root coords, unlike window->rect.
|
||||
*/
|
||||
MetaRectangle user_rect;
|
||||
@@ -465,10 +468,24 @@ struct _MetaWindowClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*workspace_changed) (MetaWindow *window, int old_workspace);
|
||||
void (*focus) (MetaWindow *window);
|
||||
void (*raised) (MetaWindow *window);
|
||||
void (*unmanaged) (MetaWindow *window);
|
||||
void (*manage) (MetaWindow *window);
|
||||
void (*unmanage) (MetaWindow *window);
|
||||
void (*ping) (MetaWindow *window,
|
||||
guint32 serial);
|
||||
void (*delete) (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void (*kill) (MetaWindow *window);
|
||||
void (*focus) (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void (*move_resize_internal) (MetaWindow *window,
|
||||
int gravity,
|
||||
MetaRectangle requested_rect,
|
||||
MetaRectangle constrained_rect,
|
||||
MetaMoveResizeFlags flags,
|
||||
MetaMoveResizeResultFlags *result);
|
||||
void (*get_default_skip_hints) (MetaWindow *window,
|
||||
gboolean *skip_taskbar_out,
|
||||
gboolean *skip_pager_out);
|
||||
};
|
||||
|
||||
/* These differ from window->has_foo_func in that they consider
|
||||
@@ -561,9 +578,6 @@ void meta_window_change_workspace (MetaWindow *window,
|
||||
/* Return whether the window should be currently mapped */
|
||||
gboolean meta_window_should_be_showing (MetaWindow *window);
|
||||
|
||||
/* See warning in window.c about this function */
|
||||
gboolean __window_is_terminal (MetaWindow *window);
|
||||
|
||||
void meta_window_update_struts (MetaWindow *window);
|
||||
|
||||
/* this gets root coords */
|
||||
@@ -597,12 +611,6 @@ void meta_window_get_geometry (MetaWindow *window,
|
||||
|
||||
void meta_window_update_unfocused_button_grabs (MetaWindow *window);
|
||||
|
||||
/* Sends a client message */
|
||||
void meta_window_send_icccm_message (MetaWindow *window,
|
||||
Atom atom,
|
||||
guint32 timestamp);
|
||||
|
||||
|
||||
void meta_window_move_resize_request(MetaWindow *window,
|
||||
guint value_mask,
|
||||
int gravity,
|
||||
@@ -628,12 +636,6 @@ void meta_window_show_menu (MetaWindow *window,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
|
||||
gboolean meta_window_titlebar_is_onscreen (MetaWindow *window);
|
||||
void meta_window_shove_titlebar_onscreen (MetaWindow *window);
|
||||
|
||||
void meta_window_set_gravity (MetaWindow *window,
|
||||
int gravity);
|
||||
|
||||
#ifdef HAVE_XSYNC
|
||||
void meta_window_update_sync_request_counter (MetaWindow *window,
|
||||
gint64 new_counter_value);
|
||||
@@ -678,9 +680,8 @@ void meta_window_update_layer (MetaWindow *window);
|
||||
|
||||
void meta_window_recalc_features (MetaWindow *window);
|
||||
|
||||
/* recalc_window_type is x11 only, wayland does its thing and then calls type_changed */
|
||||
void meta_window_recalc_window_type (MetaWindow *window);
|
||||
void meta_window_type_changed (MetaWindow *window);
|
||||
void meta_window_set_type (MetaWindow *window,
|
||||
MetaWindowType type);
|
||||
|
||||
void meta_window_frame_size_changed (MetaWindow *window);
|
||||
|
||||
@@ -745,4 +746,16 @@ void meta_window_activate_full (MetaWindow *window,
|
||||
MetaClientType source_indication,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
gboolean meta_window_is_client_decorated (MetaWindow *window);
|
||||
|
||||
void meta_window_update_monitor (MetaWindow *window);
|
||||
|
||||
void meta_window_set_urgent (MetaWindow *window,
|
||||
gboolean urgent);
|
||||
|
||||
void meta_window_update_resize (MetaWindow *window,
|
||||
gboolean snap,
|
||||
int x, int y,
|
||||
gboolean force);
|
||||
|
||||
#endif
|
||||
|
1745
src/core/window.c
1745
src/core/window.c
File diff suppressed because it is too large
Load Diff
@@ -91,7 +91,6 @@ item(hotplug_mode_update)
|
||||
item(_NET_WM_SYNC_REQUEST)
|
||||
item(_NET_WM_SYNC_REQUEST_COUNTER)
|
||||
item(_NET_WM_VISIBLE_NAME)
|
||||
item(_NET_WM_VISIBLE_ICON_NAME)
|
||||
item(_NET_SUPPORTING_WM_CHECK)
|
||||
|
||||
/* But I suppose it's quite reasonable not to advertise using
|
||||
@@ -132,7 +131,6 @@ item(_NET_CLIENT_LIST)
|
||||
item(_NET_CLIENT_LIST_STACKING)
|
||||
item(_NET_WM_STATE_SKIP_TASKBAR)
|
||||
item(_NET_WM_STATE_SKIP_PAGER)
|
||||
item(_NET_WM_ICON_NAME)
|
||||
item(_NET_WM_ICON)
|
||||
item(_NET_WM_ICON_GEOMETRY)
|
||||
item(_NET_WM_MOVERESIZE)
|
||||
|
@@ -163,13 +163,6 @@ typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu,
|
||||
* @META_GRAB_OP_KEYBOARD_RESIZING_NE: Resizing NE with keyboard
|
||||
* @META_GRAB_OP_KEYBOARD_RESIZING_SW: Resizing SW with keyboard
|
||||
* @META_GRAB_OP_KEYBOARD_RESIZING_NW: Resizing NS with keyboard
|
||||
* @META_GRAB_OP_KEYBOARD_TABBING_NORMAL: Tabbing
|
||||
* @META_GRAB_OP_KEYBOARD_TABBING_DOCK: Tabbing through docks
|
||||
* @META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL: Escaping
|
||||
* @META_GRAB_OP_KEYBOARD_ESCAPING_DOCK: Escaping through docks
|
||||
* @META_GRAB_OP_KEYBOARD_ESCAPING_GROUP: Escaping through groups
|
||||
* @META_GRAB_OP_KEYBOARD_TABBING_GROUP: Tabbing through groups
|
||||
* @META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING: Switch to another workspace
|
||||
* @META_GRAB_OP_CLICKING_MINIMIZE: Clicked minimize button
|
||||
* @META_GRAB_OP_CLICKING_MAXIMIZE: Clicked maximize button
|
||||
* @META_GRAB_OP_CLICKING_UNMAXIMIZE: Clicked unmaximize button
|
||||
@@ -228,7 +221,10 @@ typedef enum
|
||||
META_GRAB_OP_CLICKING_UNSTICK,
|
||||
|
||||
/* Special grab op when the compositor asked for a grab */
|
||||
META_GRAB_OP_COMPOSITOR
|
||||
META_GRAB_OP_COMPOSITOR,
|
||||
|
||||
/* For when a client takes a popup grab */
|
||||
META_GRAB_OP_WAYLAND_CLIENT,
|
||||
} MetaGrabOp;
|
||||
|
||||
/**
|
||||
|
@@ -163,10 +163,6 @@ void meta_display_set_input_focus_window (MetaDisplay *display,
|
||||
gboolean focus_frame,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_display_request_take_focus (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
|
||||
/* meta_display_focus_the_no_focus_window is called when the
|
||||
* designated no_focus_window should be focused, but is otherwise the
|
||||
* same as meta_display_set_input_focus_window
|
||||
@@ -178,8 +174,6 @@ void meta_display_focus_the_no_focus_window (MetaDisplay *display,
|
||||
GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display,
|
||||
GSList *windows);
|
||||
|
||||
Window meta_display_get_leader_window (MetaDisplay *display);
|
||||
|
||||
void meta_display_add_ignored_crossing_serial (MetaDisplay *display,
|
||||
unsigned long serial);
|
||||
|
||||
|
@@ -28,6 +28,7 @@ GOptionContext *meta_get_option_context (void);
|
||||
void meta_init (void);
|
||||
int meta_run (void);
|
||||
void meta_register_with_session (void);
|
||||
gboolean meta_activate_session (void);
|
||||
gboolean meta_get_replace_current_wm (void); /* Actually defined in util.c */
|
||||
|
||||
void meta_set_wm_name (const char *wm_name);
|
||||
|
@@ -254,9 +254,6 @@ struct _MetaPluginInfo
|
||||
|
||||
GType meta_plugin_get_type (void);
|
||||
|
||||
gboolean meta_plugin_running (MetaPlugin *plugin);
|
||||
gboolean meta_plugin_debug_mode (MetaPlugin *plugin);
|
||||
|
||||
const MetaPluginInfo * meta_plugin_get_info (MetaPlugin *plugin);
|
||||
|
||||
/**
|
||||
@@ -408,8 +405,7 @@ meta_plugin_end_modal (MetaPlugin *plugin,
|
||||
|
||||
MetaScreen *meta_plugin_get_screen (MetaPlugin *plugin);
|
||||
|
||||
void
|
||||
_meta_plugin_effect_started (MetaPlugin *plugin);
|
||||
void _meta_plugin_set_screen (MetaPlugin *plugin, MetaScreen *screen);
|
||||
|
||||
/* XXX: Putting this in here so it's in the public header. */
|
||||
void meta_plugin_manager_set_plugin_type (GType gtype);
|
||||
|
@@ -72,11 +72,13 @@ typedef enum
|
||||
* MetaMaximizeFlags:
|
||||
* @META_MAXIMIZE_HORIZONTAL: Horizontal
|
||||
* @META_MAXIMIZE_VERTICAL: Vertical
|
||||
* @META_MAXIMIZE_BOTH: Both
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_MAXIMIZE_HORIZONTAL = 1 << 0,
|
||||
META_MAXIMIZE_VERTICAL = 1 << 1
|
||||
META_MAXIMIZE_VERTICAL = 1 << 1,
|
||||
META_MAXIMIZE_BOTH = (1 << 0 | 1 << 1),
|
||||
} MetaMaximizeFlags;
|
||||
|
||||
/**
|
||||
@@ -123,7 +125,6 @@ MetaScreen *meta_window_get_screen (MetaWindow *window);
|
||||
MetaDisplay *meta_window_get_display (MetaWindow *window);
|
||||
Window meta_window_get_xwindow (MetaWindow *window);
|
||||
MetaWindowType meta_window_get_window_type (MetaWindow *window);
|
||||
Atom meta_window_get_window_type_atom (MetaWindow *window);
|
||||
MetaWorkspace *meta_window_get_workspace (MetaWindow *window);
|
||||
int meta_window_get_monitor (MetaWindow *window);
|
||||
gboolean meta_window_is_on_all_workspaces (MetaWindow *window);
|
||||
@@ -163,7 +164,6 @@ void meta_window_change_workspace (MetaWindow *window,
|
||||
MetaWorkspace *workspace);
|
||||
GObject *meta_window_get_compositor_private (MetaWindow *window);
|
||||
void meta_window_set_compositor_private (MetaWindow *window, GObject *priv);
|
||||
void meta_window_configure_notify (MetaWindow *window, XConfigureEvent *event);
|
||||
const char *meta_window_get_role (MetaWindow *window);
|
||||
MetaStackLayer meta_window_get_layer (MetaWindow *window);
|
||||
MetaWindow* meta_window_find_root_ancestor (MetaWindow *window);
|
||||
@@ -203,7 +203,6 @@ void meta_window_raise (MetaWindow *window);
|
||||
void meta_window_lower (MetaWindow *window);
|
||||
const char *meta_window_get_title (MetaWindow *window);
|
||||
MetaWindow *meta_window_get_transient_for (MetaWindow *window);
|
||||
Window meta_window_get_transient_for_as_xid (MetaWindow *window);
|
||||
void meta_window_delete (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
guint meta_window_get_stable_sequence (MetaWindow *window);
|
||||
@@ -211,7 +210,6 @@ guint32 meta_window_get_user_time (MetaWindow *window);
|
||||
int meta_window_get_pid (MetaWindow *window);
|
||||
const char *meta_window_get_client_machine (MetaWindow *window);
|
||||
gboolean meta_window_is_remote (MetaWindow *window);
|
||||
gboolean meta_window_is_modal (MetaWindow *window);
|
||||
gboolean meta_window_is_attached_dialog (MetaWindow *window);
|
||||
const char *meta_window_get_mutter_hints (MetaWindow *window);
|
||||
|
||||
@@ -252,6 +250,16 @@ void meta_window_begin_grab_op (MetaWindow *window,
|
||||
gboolean frame_action,
|
||||
guint32 timestamp);
|
||||
|
||||
gboolean meta_window_can_maximize (MetaWindow *window);
|
||||
gboolean meta_window_can_minimize (MetaWindow *window);
|
||||
gboolean meta_window_can_shade (MetaWindow *window);
|
||||
gboolean meta_window_can_close (MetaWindow *window);
|
||||
gboolean meta_window_is_always_on_all_workspaces (MetaWindow *window);
|
||||
gboolean meta_window_is_above (MetaWindow *window);
|
||||
gboolean meta_window_allows_move (MetaWindow *window);
|
||||
gboolean meta_window_allows_resize (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_titlebar_is_onscreen (MetaWindow *window);
|
||||
void meta_window_shove_titlebar_onscreen (MetaWindow *window);
|
||||
|
||||
#endif
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
_Name=Mutter (wayland compositor)
|
||||
Exec=mutter-launch -- mutter --wayland
|
||||
Exec=mutter-launch -- mutter --wayland --display-server
|
||||
NoDisplay=true
|
||||
# name of loadable control center module
|
||||
X-GNOME-WMSettingsModule=metacity
|
||||
|
@@ -1,109 +0,0 @@
|
||||
#! /bin/bash
|
||||
|
||||
if test -z "$XNEST_DISPLAY"; then
|
||||
XNEST_DISPLAY=:8
|
||||
fi
|
||||
|
||||
if test -z "$CLIENT_DISPLAY"; then
|
||||
CLIENT_DISPLAY=:8
|
||||
fi
|
||||
|
||||
if test -z "$MUTTER_DISPLAY"; then
|
||||
export MUTTER_DISPLAY=$CLIENT_DISPLAY
|
||||
fi
|
||||
|
||||
if test -z "$SCREENS"; then
|
||||
SCREENS=1
|
||||
fi
|
||||
|
||||
MAX_SCREEN=`echo $SCREENS-1 | bc`
|
||||
|
||||
if test "$DEBUG" = none; then
|
||||
DEBUG=
|
||||
elif test -z "$DEBUG"; then
|
||||
DEBUG=
|
||||
fi
|
||||
|
||||
if test -z "$CLIENTS"; then
|
||||
CLIENTS=0
|
||||
fi
|
||||
|
||||
if test -z "$SM_CLIENTS"; then
|
||||
SM_CLIENTS=0
|
||||
fi
|
||||
|
||||
if test -n "$EVIL_TEST"; then
|
||||
TEST_CLIENT='./wm-tester/wm-tester --evil'
|
||||
fi
|
||||
|
||||
if test -n "$ICON_TEST"; then
|
||||
TEST_CLIENT='./wm-tester/wm-tester --icon-windows'
|
||||
fi
|
||||
|
||||
if test -n "$DEMO_TEST"; then
|
||||
TEST_CLIENT='./tools/mutter-window-demo'
|
||||
fi
|
||||
|
||||
if test -n "$XINERAMA"; then
|
||||
XINERAMA_FLAGS='+xinerama'
|
||||
fi
|
||||
|
||||
export EF_ALLOW_MALLOC_0=1
|
||||
|
||||
if test -z "$ONLY_WM"; then
|
||||
echo "Launching Xnest"
|
||||
Xnest -ac $XNEST_DISPLAY -scrns $SCREENS -geometry 640x480 -bw 15 $XINERAMA_FLAGS &
|
||||
## usleep 800000
|
||||
sleep 1
|
||||
|
||||
if test -n "$XMON_DIR"; then
|
||||
echo "Launching xmond"
|
||||
$XMON_DIR/xmonui | $XMON_DIR/xmond -server localhost:$XNEST_DISPLAY &
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
if test -n "$XSCOPE_DIR"; then
|
||||
## xscope doesn't like to die when it should, it backgrounds itself
|
||||
killall -9 xscope
|
||||
killall -9 xscope
|
||||
echo "Launching xscope"
|
||||
DISPLAY= $XSCOPE_DIR/xscope -o1 -i28 > xscoped-replies.txt &
|
||||
export MUTTER_DISPLAY=localhost:28
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
echo "Launching clients"
|
||||
if test -n "$TEST_CLIENT"; then
|
||||
for I in `seq 0 $MAX_SCREEN`; do
|
||||
DISPLAY=$CLIENT_DISPLAY.$I $TEST_CLIENT &
|
||||
done
|
||||
fi
|
||||
|
||||
if test $CLIENTS != 0; then
|
||||
for I in `seq 1 $CLIENTS`; do
|
||||
echo "Launching xterm $I"
|
||||
DISPLAY=$CLIENT_DISPLAY xterm -geometry 25x15 &
|
||||
done
|
||||
fi
|
||||
|
||||
if test $SM_CLIENTS != 0; then
|
||||
for I in `seq 1 $SM_CLIENTS`; do
|
||||
echo "Launching gnome-terminal $I"
|
||||
DISPLAY=$CLIENT_DISPLAY gnome-terminal --geometry 25x15 &
|
||||
done
|
||||
fi
|
||||
|
||||
if test -e ~/.Xmodmap; then
|
||||
DISPLAY=$CLIENT_DISPLAY xmodmap ~/.Xmodmap
|
||||
fi
|
||||
|
||||
usleep 50000
|
||||
|
||||
for I in `seq 0 $MAX_SCREEN`; do
|
||||
DISPLAY=$CLIENT_DISPLAY.$I xsetroot -solid royalblue3
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$ONLY_SETUP"; then
|
||||
MUTTER_VERBOSE=1 MUTTER_USE_LOGFILE=1 MUTTER_DEBUG_BUTTON_GRABS=1 exec $DEBUG ./mutter $OPTIONS
|
||||
fi
|
@@ -44,8 +44,6 @@
|
||||
static void meta_frames_destroy (GtkWidget *object);
|
||||
static void meta_frames_finalize (GObject *object);
|
||||
static void meta_frames_style_updated (GtkWidget *widget);
|
||||
static void meta_frames_map (GtkWidget *widget);
|
||||
static void meta_frames_unmap (GtkWidget *widget);
|
||||
|
||||
static void meta_frames_update_prelit_control (MetaFrames *frames,
|
||||
MetaUIFrame *frame,
|
||||
@@ -134,9 +132,6 @@ meta_frames_class_init (MetaFramesClass *class)
|
||||
|
||||
widget_class->style_updated = meta_frames_style_updated;
|
||||
|
||||
widget_class->map = meta_frames_map;
|
||||
widget_class->unmap = meta_frames_unmap;
|
||||
|
||||
widget_class->draw = meta_frames_draw;
|
||||
widget_class->destroy_event = meta_frames_destroy_event;
|
||||
widget_class->button_press_event = meta_frames_button_press_event;
|
||||
@@ -231,6 +226,7 @@ meta_frames_init (MetaFrames *frames)
|
||||
|
||||
frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, g_object_unref);
|
||||
|
||||
update_style_contexts (frames);
|
||||
|
||||
gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE);
|
||||
@@ -522,13 +518,26 @@ MetaFrames*
|
||||
meta_frames_new (int screen_number)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
MetaFrames *frames;
|
||||
|
||||
screen = gdk_display_get_screen (gdk_display_get_default (),
|
||||
screen_number);
|
||||
|
||||
return g_object_new (META_TYPE_FRAMES,
|
||||
"screen", screen,
|
||||
NULL);
|
||||
frames = g_object_new (META_TYPE_FRAMES,
|
||||
"screen", screen,
|
||||
"type", GTK_WINDOW_POPUP,
|
||||
NULL);
|
||||
|
||||
/* Put the window at an arbitrary offscreen location; the one place
|
||||
* it can't be is at -100x-100, since the meta_window_new() will
|
||||
* mistake it for a window created via meta_create_offscreen_window()
|
||||
* and ignore it, and we need this window to get frame-synchronization
|
||||
* messages so that GTK+'s style change handling works.
|
||||
*/
|
||||
gtk_window_move (GTK_WINDOW (frames), -200, -200);
|
||||
gtk_window_resize (GTK_WINDOW (frames), 1, 1);
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
/* In order to use a style with a window it has to be attached to that
|
||||
@@ -635,22 +644,6 @@ meta_frames_unmanage_window (MetaFrames *frames,
|
||||
meta_warning ("Frame 0x%lx not managed, can't unmanage\n", xwindow);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_frames_map (GtkWidget *widget)
|
||||
{
|
||||
/* We override the parent map function to a no-op because we don't
|
||||
* want to actually show the GDK window. But GTK needs to think that
|
||||
* the widget is mapped or it won't deliver the events we care about.
|
||||
*/
|
||||
gtk_widget_set_mapped (widget, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_frames_unmap (GtkWidget *widget)
|
||||
{
|
||||
gtk_widget_set_mapped (widget, FALSE);
|
||||
}
|
||||
|
||||
static MetaUIFrame*
|
||||
meta_frames_lookup_window (MetaFrames *frames,
|
||||
Window xwindow)
|
||||
|
@@ -295,9 +295,12 @@ meta_ui_new (Display *xdisplay,
|
||||
g_assert (gdisplay == gdk_display_get_default ());
|
||||
|
||||
ui->frames = meta_frames_new (XScreenNumberOfScreen (screen));
|
||||
/* This does not actually show any widget. MetaFrames has been hacked so
|
||||
* that showing it doesn't actually do anything. But we need the flags
|
||||
* set for GTK to deliver events properly. */
|
||||
/* GTK+ needs the frame-sync protocol to work in order to properly
|
||||
* handle style changes. This means that the dummy widget we create
|
||||
* to get the style for title bars actually needs to be mapped
|
||||
* and fully tracked as a MetaWindow. Horrible, but mostly harmless -
|
||||
* the window is a 1x1 overide redirect window positioned offscreen.
|
||||
*/
|
||||
gtk_widget_show (GTK_WIDGET (ui->frames));
|
||||
|
||||
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);
|
||||
|
@@ -48,7 +48,7 @@ data_offer_accept (struct wl_client *client,
|
||||
* this be a wl_data_device request? */
|
||||
|
||||
if (offer->source)
|
||||
offer->source->accept (offer->source, serial, mime_type);
|
||||
wl_data_source_send_target (offer->source->resource, mime_type);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -58,9 +58,9 @@ data_offer_receive (struct wl_client *client, struct wl_resource *resource,
|
||||
MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
|
||||
|
||||
if (offer->source)
|
||||
offer->source->send (offer->source, mime_type, fd);
|
||||
else
|
||||
close (fd);
|
||||
wl_data_source_send_send (offer->source->resource, mime_type, fd);
|
||||
|
||||
close (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -82,7 +82,8 @@ destroy_data_offer (struct wl_resource *resource)
|
||||
|
||||
if (offer->source)
|
||||
wl_list_remove (&offer->source_destroy_listener.link);
|
||||
free (offer);
|
||||
|
||||
g_slice_free (MetaWaylandDataOffer, offer);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -99,13 +100,9 @@ static struct wl_resource *
|
||||
meta_wayland_data_source_send_offer (MetaWaylandDataSource *source,
|
||||
struct wl_resource *target)
|
||||
{
|
||||
MetaWaylandDataOffer *offer;
|
||||
MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer);
|
||||
char **p;
|
||||
|
||||
offer = malloc (sizeof *offer);
|
||||
if (offer == NULL)
|
||||
return NULL;
|
||||
|
||||
offer->source = source;
|
||||
offer->source_destroy_listener.notify = destroy_offer_data_source;
|
||||
|
||||
@@ -178,8 +175,7 @@ destroy_drag_focus (struct wl_listener *listener, void *data)
|
||||
|
||||
static void
|
||||
drag_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event)
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
|
||||
MetaWaylandSeat *seat = drag_grab->seat;
|
||||
@@ -260,7 +256,7 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
|
||||
if (drag_grab->drag_data_source)
|
||||
wl_list_remove (&drag_grab->drag_data_source_listener.link);
|
||||
|
||||
drag_grab_focus (&drag_grab->generic, NULL, NULL);
|
||||
drag_grab_focus (&drag_grab->generic, NULL);
|
||||
|
||||
meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
|
||||
g_slice_free (MetaWaylandDragGrab, drag_grab);
|
||||
@@ -318,8 +314,12 @@ data_device_start_drag (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
MetaWaylandDragGrab *drag_grab;
|
||||
/* FIXME: Check that client has implicit grab on the origin
|
||||
* surface that matches the given time. */
|
||||
|
||||
if ((seat->pointer.button_count == 0 ||
|
||||
seat->pointer.grab_serial != serial ||
|
||||
!seat->pointer.focus_surface ||
|
||||
seat->pointer.focus_surface != wl_resource_get_user_data (origin_resource)))
|
||||
return;
|
||||
|
||||
/* FIXME: Check that the data source type array isn't empty. */
|
||||
|
||||
@@ -332,6 +332,7 @@ data_device_start_drag (struct wl_client *client,
|
||||
drag_grab->generic.pointer = &seat->pointer;
|
||||
|
||||
drag_grab->drag_client = client;
|
||||
drag_grab->seat = seat;
|
||||
|
||||
if (source_resource)
|
||||
{
|
||||
@@ -375,7 +376,7 @@ destroy_selection_data_source (struct wl_listener *listener, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
meta_wayland_seat_set_selection (MetaWaylandSeat *seat,
|
||||
MetaWaylandDataSource *source,
|
||||
guint32 serial)
|
||||
@@ -389,7 +390,7 @@ meta_wayland_seat_set_selection (MetaWaylandSeat *seat,
|
||||
|
||||
if (seat->selection_data_source)
|
||||
{
|
||||
seat->selection_data_source->cancel (seat->selection_data_source);
|
||||
wl_data_source_send_cancelled (seat->selection_data_source->resource);
|
||||
wl_list_remove (&seat->selection_data_source_listener.link);
|
||||
seat->selection_data_source = NULL;
|
||||
}
|
||||
@@ -449,47 +450,21 @@ static const struct wl_data_device_interface data_device_interface = {
|
||||
static void
|
||||
destroy_data_source (struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandDataSource *source = wl_container_of (resource, source, resource);
|
||||
MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
|
||||
char **p;
|
||||
|
||||
wl_array_for_each (p, &source->mime_types) free (*p);
|
||||
|
||||
wl_array_release (&source->mime_types);
|
||||
}
|
||||
|
||||
static void
|
||||
client_source_accept (MetaWaylandDataSource *source,
|
||||
guint32 time, const char *mime_type)
|
||||
{
|
||||
wl_data_source_send_target (source->resource, mime_type);
|
||||
}
|
||||
|
||||
static void
|
||||
client_source_send (MetaWaylandDataSource *source,
|
||||
const char *mime_type, int32_t fd)
|
||||
{
|
||||
wl_data_source_send_send (source->resource, mime_type, fd);
|
||||
close (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
client_source_cancel (MetaWaylandDataSource *source)
|
||||
{
|
||||
wl_data_source_send_cancelled (source->resource);
|
||||
g_slice_free (MetaWaylandDataSource, source);
|
||||
}
|
||||
|
||||
static void
|
||||
create_data_source (struct wl_client *client,
|
||||
struct wl_resource *resource, guint32 id)
|
||||
{
|
||||
MetaWaylandDataSource *source;
|
||||
|
||||
source = malloc (sizeof *source);
|
||||
if (source == NULL)
|
||||
{
|
||||
wl_resource_post_no_memory (resource);
|
||||
return;
|
||||
}
|
||||
MetaWaylandDataSource *source = g_slice_new0 (MetaWaylandDataSource);
|
||||
|
||||
source->resource = wl_resource_create (client, &wl_data_source_interface,
|
||||
MIN (META_WL_DATA_SOURCE_VERSION,
|
||||
@@ -497,10 +472,6 @@ create_data_source (struct wl_client *client,
|
||||
wl_resource_set_implementation (source->resource, &data_source_interface,
|
||||
source, destroy_data_source);
|
||||
|
||||
source->accept = client_source_accept;
|
||||
source->send = client_source_send;
|
||||
source->cancel = client_source_cancel;
|
||||
|
||||
wl_array_init (&source->mime_types);
|
||||
}
|
||||
|
||||
|
@@ -33,10 +33,4 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandSeat *seat);
|
||||
int
|
||||
meta_wayland_data_device_manager_init (struct wl_display *display);
|
||||
|
||||
void
|
||||
meta_wayland_seat_set_selection (MetaWaylandSeat *seat,
|
||||
MetaWaylandDataSource *source,
|
||||
uint32_t serial);
|
||||
|
||||
|
||||
#endif /* __META_WAYLAND_DATA_DEVICE_H__ */
|
||||
|
@@ -138,23 +138,11 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
|
||||
return;
|
||||
}
|
||||
|
||||
if (xkb_info->keymap)
|
||||
xkb_keymap_unref (xkb_info->keymap);
|
||||
xkb_keymap_unref (xkb_info->keymap);
|
||||
xkb_info->keymap = keymap;
|
||||
|
||||
xkb_info->shift_mod =
|
||||
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_SHIFT);
|
||||
xkb_info->caps_mod =
|
||||
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_CAPS);
|
||||
xkb_info->ctrl_mod =
|
||||
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_CTRL);
|
||||
xkb_info->alt_mod =
|
||||
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_ALT);
|
||||
xkb_info->mod2_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod2");
|
||||
xkb_info->mod3_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod3");
|
||||
xkb_info->super_mod =
|
||||
xkb_map_mod_get_index (xkb_info->keymap, XKB_MOD_NAME_LOGO);
|
||||
xkb_info->mod5_mod = xkb_map_mod_get_index (xkb_info->keymap, "Mod5");
|
||||
xkb_state_unref (xkb_info->state);
|
||||
xkb_info->state = xkb_state_new (keymap);
|
||||
|
||||
keymap_str = xkb_map_get_as_string (xkb_info->keymap);
|
||||
if (keymap_str == NULL)
|
||||
@@ -295,31 +283,6 @@ static const MetaWaylandKeyboardGrabInterface
|
||||
default_grab_modifiers,
|
||||
};
|
||||
|
||||
static gboolean
|
||||
modal_key (MetaWaylandKeyboardGrab *grab,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
/* FALSE means: let the event through to clutter */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
modal_modifiers (MetaWaylandKeyboardGrab *grab,
|
||||
uint32_t serial,
|
||||
uint32_t mods_depressed,
|
||||
uint32_t mods_latched,
|
||||
uint32_t mods_locked,
|
||||
uint32_t group)
|
||||
{
|
||||
}
|
||||
|
||||
static MetaWaylandKeyboardGrabInterface modal_grab = {
|
||||
modal_key,
|
||||
modal_modifiers,
|
||||
};
|
||||
|
||||
gboolean
|
||||
meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_display *display)
|
||||
@@ -355,8 +318,8 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
static void
|
||||
meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
|
||||
{
|
||||
if (xkb_info->keymap)
|
||||
xkb_map_unref (xkb_info->keymap);
|
||||
xkb_keymap_unref (xkb_info->keymap);
|
||||
xkb_state_unref (xkb_info->state);
|
||||
|
||||
if (xkb_info->keymap_area)
|
||||
munmap (xkb_info->keymap_area, xkb_info->keymap_size);
|
||||
@@ -364,47 +327,7 @@ meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
|
||||
close (xkb_info->keymap_fd);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
state_equal (MetaWaylandXkbState *one,
|
||||
MetaWaylandXkbState *two)
|
||||
{
|
||||
return one->mods_depressed == two->mods_depressed &&
|
||||
one->mods_latched == two->mods_latched &&
|
||||
one->mods_locked == two->mods_locked &&
|
||||
one->group == two->group;
|
||||
}
|
||||
|
||||
static void
|
||||
set_modifiers (MetaWaylandKeyboard *keyboard,
|
||||
guint32 serial,
|
||||
ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandKeyboardGrab *grab = keyboard->grab;
|
||||
MetaWaylandXkbState new_state;
|
||||
guint effective_state;
|
||||
|
||||
clutter_event_get_state_full (event,
|
||||
NULL,
|
||||
&new_state.mods_depressed,
|
||||
&new_state.mods_latched,
|
||||
&new_state.mods_locked,
|
||||
&effective_state);
|
||||
new_state.group = (effective_state >> 13) & 0x3;
|
||||
|
||||
if (state_equal (&keyboard->modifier_state, &new_state))
|
||||
return;
|
||||
|
||||
keyboard->modifier_state = new_state;
|
||||
|
||||
grab->interface->modifiers (grab,
|
||||
serial,
|
||||
new_state.mods_depressed,
|
||||
new_state.mods_latched,
|
||||
new_state.mods_locked,
|
||||
new_state.group);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_pressed_keys (MetaWaylandKeyboard *keyboard,
|
||||
uint32_t evdev_code,
|
||||
gboolean is_press)
|
||||
@@ -415,13 +338,10 @@ update_pressed_keys (MetaWaylandKeyboard *keyboard,
|
||||
keyboard->keys.size);
|
||||
uint32_t *k;
|
||||
|
||||
/* We want to ignore events that are sent because of auto-repeat. In
|
||||
the Clutter event stream these appear as a single key press
|
||||
event. We can detect that because the key will already have been
|
||||
pressed */
|
||||
/* Make sure we don't already have this key. */
|
||||
for (k = keyboard->keys.data; k < end; k++)
|
||||
if (*k == evdev_code)
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
/* Otherwise add the key to the list of pressed keys */
|
||||
k = wl_array_add (&keyboard->keys, sizeof (*k));
|
||||
@@ -439,18 +359,44 @@ update_pressed_keys (MetaWaylandKeyboard *keyboard,
|
||||
{
|
||||
*k = *(end - 1);
|
||||
keyboard->keys.size -= sizeof (*k);
|
||||
|
||||
goto found;
|
||||
return;
|
||||
}
|
||||
|
||||
g_warning ("unexpected key release event for key 0x%x", evdev_code);
|
||||
return FALSE;
|
||||
|
||||
found:
|
||||
(void) 0;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
static guint
|
||||
evdev_code (const ClutterKeyEvent *event)
|
||||
{
|
||||
/* clutter-xkb-utils.c adds a fixed offset of 8 to go into XKB's
|
||||
* range, so we do the reverse here. */
|
||||
return event->hardware_keycode - 8;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard,
|
||||
const ClutterKeyEvent *event)
|
||||
{
|
||||
MetaWaylandKeyboardGrab *grab = keyboard->grab;
|
||||
gboolean is_press = event->type == CLUTTER_KEY_PRESS;
|
||||
struct xkb_state *state = keyboard->xkb_info.state;
|
||||
enum xkb_state_component changed_state;
|
||||
|
||||
update_pressed_keys (keyboard, evdev_code (event), is_press);
|
||||
|
||||
changed_state = xkb_state_update_key (state,
|
||||
event->hardware_keycode,
|
||||
is_press ? XKB_KEY_DOWN : XKB_KEY_UP);
|
||||
if (changed_state == 0)
|
||||
return;
|
||||
|
||||
grab->interface->modifiers (grab,
|
||||
wl_display_next_serial (keyboard->display),
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED),
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED),
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
|
||||
xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -458,34 +404,20 @@ meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||
const ClutterKeyEvent *event)
|
||||
{
|
||||
gboolean is_press = event->type == CLUTTER_KEY_PRESS;
|
||||
guint xkb_keycode, evdev_code;
|
||||
uint32_t serial;
|
||||
gboolean autorepeat;
|
||||
gboolean handled;
|
||||
|
||||
xkb_keycode = event->hardware_keycode;
|
||||
if (event->device == NULL ||
|
||||
!clutter_input_device_keycode_to_evdev (event->device,
|
||||
xkb_keycode, &evdev_code))
|
||||
evdev_code = xkb_keycode - 8; /* What everyone is doing in practice... */
|
||||
|
||||
autorepeat = update_pressed_keys (keyboard, evdev_code, is_press);
|
||||
|
||||
meta_verbose ("Handling key %s%s event code %d\n",
|
||||
is_press ? "press" : "release",
|
||||
autorepeat ? " (autorepeat)" : "",
|
||||
xkb_keycode);
|
||||
|
||||
if (autorepeat)
|
||||
/* Synthetic key events are for autorepeat. Ignore those, as
|
||||
* autorepeat in Wayland is done on the client side. */
|
||||
if (event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC)
|
||||
return FALSE;
|
||||
|
||||
serial = wl_display_next_serial (keyboard->display);
|
||||
|
||||
set_modifiers (keyboard, serial, (ClutterEvent*)event);
|
||||
meta_verbose ("Handling key %s event code %d\n",
|
||||
is_press ? "press" : "release",
|
||||
event->hardware_keycode);
|
||||
|
||||
handled = keyboard->grab->interface->key (keyboard->grab,
|
||||
event->time,
|
||||
evdev_code,
|
||||
evdev_code (event),
|
||||
is_press);
|
||||
|
||||
if (handled)
|
||||
@@ -533,28 +465,16 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (keyboard->focus_resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
struct xkb_state *state = keyboard->xkb_info.state;
|
||||
uint32_t serial = wl_display_next_serial (display);
|
||||
|
||||
/* If we're in a modal grab, the client is focused but doesn't see
|
||||
modifiers or pressed keys (and fix that up when we exit the modal) */
|
||||
if (keyboard->grab->interface == &modal_grab)
|
||||
{
|
||||
struct wl_array empty;
|
||||
wl_array_init (&empty);
|
||||
|
||||
wl_keyboard_send_modifiers (keyboard->focus_resource, serial, 0, 0, 0, 0);
|
||||
wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource, &empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_keyboard_send_modifiers (keyboard->focus_resource, serial,
|
||||
keyboard->modifier_state.mods_depressed,
|
||||
keyboard->modifier_state.mods_latched,
|
||||
keyboard->modifier_state.mods_locked,
|
||||
keyboard->modifier_state.group);
|
||||
wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource,
|
||||
&keyboard->keys);
|
||||
}
|
||||
wl_keyboard_send_modifiers (keyboard->focus_resource, serial,
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_DEPRESSED),
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_LATCHED),
|
||||
xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED),
|
||||
xkb_state_serialize_layout (state, XKB_STATE_LAYOUT_EFFECTIVE));
|
||||
wl_keyboard_send_enter (keyboard->focus_resource, serial, keyboard->focus_surface->resource,
|
||||
&keyboard->keys);
|
||||
|
||||
wl_resource_add_destroy_listener (keyboard->focus_resource, &keyboard->focus_resource_listener);
|
||||
keyboard->focus_serial = serial;
|
||||
@@ -588,85 +508,6 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard)
|
||||
wl_array_release (&keyboard->keys);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWaylandKeyboardGrab *grab;
|
||||
uint32_t *end = (void *) ((char *) keyboard->keys.data +
|
||||
keyboard->keys.size);
|
||||
uint32_t *k;
|
||||
uint32_t serial;
|
||||
|
||||
meta_verbose ("Asked to acquire modal keyboard grab, timestamp %d\n", timestamp);
|
||||
|
||||
if (keyboard->grab != &keyboard->default_grab)
|
||||
return FALSE;
|
||||
|
||||
if (keyboard->focus_surface)
|
||||
{
|
||||
/* Fake key release events for the focused app */
|
||||
serial = wl_display_next_serial (keyboard->display);
|
||||
keyboard->grab->interface->modifiers (keyboard->grab,
|
||||
serial,
|
||||
0, 0, 0, 0);
|
||||
|
||||
for (k = keyboard->keys.data; k < end; k++)
|
||||
{
|
||||
keyboard->grab->interface->key (keyboard->grab,
|
||||
timestamp,
|
||||
*k, 0);
|
||||
}
|
||||
}
|
||||
|
||||
grab = g_slice_new0 (MetaWaylandKeyboardGrab);
|
||||
grab->interface = &modal_grab;
|
||||
meta_wayland_keyboard_start_grab (keyboard, grab);
|
||||
|
||||
meta_verbose ("Acquired modal keyboard grab, timestamp %d\n", timestamp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWaylandKeyboardGrab *grab;
|
||||
uint32_t *end = (void *) ((char *) keyboard->keys.data +
|
||||
keyboard->keys.size);
|
||||
uint32_t *k;
|
||||
uint32_t serial;
|
||||
|
||||
grab = keyboard->grab;
|
||||
|
||||
g_assert (grab->interface == &modal_grab);
|
||||
|
||||
meta_wayland_keyboard_end_grab (keyboard);
|
||||
g_slice_free (MetaWaylandKeyboardGrab, grab);
|
||||
|
||||
if (keyboard->focus_surface)
|
||||
{
|
||||
/* Fake key press events for the focused app */
|
||||
serial = wl_display_next_serial (keyboard->display);
|
||||
keyboard->grab->interface->modifiers (keyboard->grab,
|
||||
serial,
|
||||
keyboard->modifier_state.mods_depressed,
|
||||
keyboard->modifier_state.mods_latched,
|
||||
keyboard->modifier_state.mods_locked,
|
||||
keyboard->modifier_state.group);
|
||||
|
||||
for (k = keyboard->keys.data; k < end; k++)
|
||||
{
|
||||
keyboard->grab->interface->key (keyboard->grab,
|
||||
timestamp,
|
||||
*k, 1);
|
||||
}
|
||||
}
|
||||
|
||||
meta_verbose ("Released modal keyboard grab, timestamp %d\n", timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_set_keymap_names (MetaWaylandKeyboard *keyboard,
|
||||
const char *rules,
|
||||
|
@@ -69,27 +69,12 @@ struct _MetaWaylandKeyboardGrab
|
||||
typedef struct
|
||||
{
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
int keymap_fd;
|
||||
size_t keymap_size;
|
||||
char *keymap_area;
|
||||
xkb_mod_index_t shift_mod;
|
||||
xkb_mod_index_t caps_mod;
|
||||
xkb_mod_index_t ctrl_mod;
|
||||
xkb_mod_index_t alt_mod;
|
||||
xkb_mod_index_t mod2_mod;
|
||||
xkb_mod_index_t mod3_mod;
|
||||
xkb_mod_index_t super_mod;
|
||||
xkb_mod_index_t mod5_mod;
|
||||
} MetaWaylandXkbInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t mods_depressed;
|
||||
uint32_t mods_latched;
|
||||
uint32_t mods_locked;
|
||||
uint32_t group;
|
||||
} MetaWaylandXkbState;
|
||||
|
||||
struct _MetaWaylandKeyboard
|
||||
{
|
||||
struct wl_list resource_list;
|
||||
@@ -108,8 +93,6 @@ struct _MetaWaylandKeyboard
|
||||
|
||||
struct wl_array keys;
|
||||
|
||||
MetaWaylandXkbState modifier_state;
|
||||
|
||||
struct wl_display *display;
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
@@ -150,14 +133,11 @@ meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *device,
|
||||
void
|
||||
meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard);
|
||||
|
||||
gboolean
|
||||
meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard,
|
||||
guint32 timestamp);
|
||||
void
|
||||
meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard,
|
||||
guint32 timestamp);
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard);
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_update (MetaWaylandKeyboard *keyboard,
|
||||
const ClutterKeyEvent *event);
|
||||
|
||||
#endif /* __META_WAYLAND_KEYBOARD_H__ */
|
||||
|
@@ -78,8 +78,7 @@ pointer_handle_focus_resource_destroy (struct wl_listener *listener, void *data)
|
||||
|
||||
static void
|
||||
default_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event)
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandPointer *pointer = grab->pointer;
|
||||
|
||||
@@ -385,7 +384,7 @@ meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
||||
grab->pointer = pointer;
|
||||
|
||||
if (pointer->current)
|
||||
interface->focus (pointer->grab, pointer->current, NULL);
|
||||
interface->focus (pointer->grab, pointer->current);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -395,62 +394,7 @@ meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer)
|
||||
|
||||
pointer->grab = &pointer->default_grab;
|
||||
interface = pointer->grab->interface;
|
||||
interface->focus (pointer->grab, pointer->current, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
modal_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
modal_motion (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
modal_button (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
}
|
||||
|
||||
static MetaWaylandPointerGrabInterface modal_grab = {
|
||||
modal_focus,
|
||||
modal_motion,
|
||||
modal_button
|
||||
};
|
||||
|
||||
gboolean
|
||||
meta_wayland_pointer_begin_modal (MetaWaylandPointer *pointer)
|
||||
{
|
||||
MetaWaylandPointerGrab *grab;
|
||||
|
||||
if (pointer->grab != &pointer->default_grab)
|
||||
return FALSE;
|
||||
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
|
||||
grab = g_slice_new0 (MetaWaylandPointerGrab);
|
||||
grab->interface = &modal_grab;
|
||||
meta_wayland_pointer_start_grab (pointer, grab);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer)
|
||||
{
|
||||
MetaWaylandPointerGrab *grab;
|
||||
|
||||
grab = pointer->grab;
|
||||
|
||||
g_assert (grab->interface == &modal_grab);
|
||||
|
||||
meta_wayland_pointer_end_grab (pointer);
|
||||
g_slice_free (MetaWaylandPointerGrab, grab);
|
||||
interface->focus (pointer->grab, pointer->current);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@@ -470,15 +414,14 @@ typedef struct {
|
||||
|
||||
static void
|
||||
popup_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event)
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandPopupGrab *popup_grab = (MetaWaylandPopupGrab*)grab;
|
||||
|
||||
/* Popup grabs are in owner-events mode (ie, events for the same client
|
||||
are reported as normal) */
|
||||
if (surface && wl_resource_get_client (surface->resource) == popup_grab->grab_client)
|
||||
default_grab_focus (grab, surface, event);
|
||||
default_grab_focus (grab, surface);
|
||||
else
|
||||
meta_wayland_pointer_set_focus (grab->pointer, NULL);
|
||||
}
|
||||
@@ -533,6 +476,12 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer)
|
||||
g_slice_free (MetaWaylandPopup, popup);
|
||||
}
|
||||
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
meta_display_end_grab_op (display,
|
||||
meta_display_get_current_time_roundtrip (display));
|
||||
}
|
||||
|
||||
meta_wayland_pointer_end_grab (pointer);
|
||||
g_slice_free (MetaWaylandPopupGrab, popup_grab);
|
||||
}
|
||||
@@ -572,6 +521,8 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
|
||||
if (pointer->grab == &pointer->default_grab)
|
||||
{
|
||||
MetaWindow *window = surface->window;
|
||||
|
||||
grab = g_slice_new0 (MetaWaylandPopupGrab);
|
||||
grab->generic.interface = &popup_grab_interface;
|
||||
grab->generic.pointer = pointer;
|
||||
@@ -579,6 +530,19 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
wl_list_init (&grab->all_popups);
|
||||
|
||||
meta_wayland_pointer_start_grab (pointer, (MetaWaylandPointerGrab*)grab);
|
||||
|
||||
meta_display_begin_grab_op (window->display,
|
||||
window->screen,
|
||||
window,
|
||||
META_GRAB_OP_WAYLAND_CLIENT,
|
||||
FALSE, /* pointer_already_grabbed */
|
||||
FALSE, /* frame_action */
|
||||
1, /* button. XXX? */
|
||||
0, /* modmask */
|
||||
meta_display_get_current_time_roundtrip (window->display),
|
||||
wl_fixed_to_int (pointer->grab_x),
|
||||
wl_fixed_to_int (pointer->grab_y));
|
||||
|
||||
}
|
||||
else
|
||||
grab = (MetaWaylandPopupGrab*)pointer->grab;
|
||||
@@ -593,7 +557,6 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
wl_resource_add_destroy_listener (surface->wl_shell_surface.resource, &popup->surface_destroy_listener);
|
||||
|
||||
wl_list_insert (&grab->all_popups, &popup->link);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -620,3 +583,16 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||
*sx = wl_fixed_from_double (xf);
|
||||
*sy = wl_fixed_from_double (yf);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_update_current_focus (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
pointer->current = surface;
|
||||
if (surface != pointer->focus_surface)
|
||||
{
|
||||
const MetaWaylandPointerGrabInterface *interface =
|
||||
pointer->grab->interface;
|
||||
interface->focus (pointer->grab, surface);
|
||||
}
|
||||
}
|
||||
|
@@ -29,8 +29,7 @@
|
||||
struct _MetaWaylandPointerGrabInterface
|
||||
{
|
||||
void (*focus) (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event);
|
||||
MetaWaylandSurface *surface);
|
||||
void (*motion) (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event);
|
||||
void (*button) (MetaWaylandPointerGrab *grab,
|
||||
@@ -85,11 +84,6 @@ meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
||||
void
|
||||
meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer);
|
||||
|
||||
gboolean
|
||||
meta_wayland_pointer_begin_modal (MetaWaylandPointer *pointer);
|
||||
void
|
||||
meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer);
|
||||
|
||||
gboolean
|
||||
meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *popup);
|
||||
@@ -100,4 +94,8 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||
wl_fixed_t *x,
|
||||
wl_fixed_t *y);
|
||||
|
||||
void
|
||||
meta_wayland_pointer_update_current_focus (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
#endif /* __META_WAYLAND_POINTER_H__ */
|
||||
|
@@ -276,42 +276,53 @@ static void
|
||||
handle_scroll_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
enum wl_pointer_axis axis;
|
||||
wl_fixed_t value;
|
||||
wl_fixed_t x_value = 0, y_value = 0;
|
||||
|
||||
notify_motion (seat, event);
|
||||
|
||||
if (!seat->pointer.focus_resource)
|
||||
return;
|
||||
|
||||
if (clutter_event_is_pointer_emulated (event))
|
||||
return;
|
||||
|
||||
switch (clutter_event_get_scroll_direction (event))
|
||||
{
|
||||
case CLUTTER_SCROLL_UP:
|
||||
axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
|
||||
value = -DEFAULT_AXIS_STEP_DISTANCE;
|
||||
y_value = -DEFAULT_AXIS_STEP_DISTANCE;
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL_DOWN:
|
||||
axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
|
||||
value = DEFAULT_AXIS_STEP_DISTANCE;
|
||||
y_value = DEFAULT_AXIS_STEP_DISTANCE;
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL_LEFT:
|
||||
axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
|
||||
value = -DEFAULT_AXIS_STEP_DISTANCE;
|
||||
x_value = -DEFAULT_AXIS_STEP_DISTANCE;
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL_RIGHT:
|
||||
axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
|
||||
value = DEFAULT_AXIS_STEP_DISTANCE;
|
||||
x_value = DEFAULT_AXIS_STEP_DISTANCE;
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL_SMOOTH:
|
||||
{
|
||||
double dx, dy;
|
||||
clutter_event_get_scroll_delta (event, &dx, &dy);
|
||||
x_value = wl_fixed_from_double (dx);
|
||||
y_value = wl_fixed_from_double (dy);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (seat->pointer.focus_resource)
|
||||
wl_pointer_send_axis (seat->pointer.focus_resource,
|
||||
clutter_event_get_time (event),
|
||||
axis,
|
||||
value);
|
||||
if (x_value)
|
||||
wl_pointer_send_axis (seat->pointer.focus_resource, clutter_event_get_time (event),
|
||||
WL_POINTER_AXIS_HORIZONTAL_SCROLL, x_value);
|
||||
if (y_value)
|
||||
wl_pointer_send_axis (seat->pointer.focus_resource, clutter_event_get_time (event),
|
||||
WL_POINTER_AXIS_VERTICAL_SCROLL, y_value);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -336,7 +347,7 @@ count_buttons (const ClutterEvent *event)
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
meta_wayland_seat_update_pointer (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
@@ -359,6 +370,27 @@ meta_wayland_seat_update_pointer (MetaWaylandSeat *seat,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_seat_update (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_MOTION:
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
case CLUTTER_SCROLL:
|
||||
meta_wayland_seat_update_pointer (seat, event);
|
||||
break;
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
meta_wayland_keyboard_update (&seat->keyboard, (const ClutterKeyEvent *) event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
@@ -402,6 +434,13 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
ClutterActor *actor = NULL;
|
||||
MetaWaylandPointer *pointer = &seat->pointer;
|
||||
MetaWaylandSurface *surface = NULL;
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (meta_grab_op_is_wayland (display->grab_op))
|
||||
{
|
||||
meta_wayland_pointer_update_current_focus (pointer, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (for_event)
|
||||
{
|
||||
@@ -424,14 +463,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
if (META_IS_SURFACE_ACTOR_WAYLAND (actor))
|
||||
surface = meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor));
|
||||
|
||||
pointer->current = surface;
|
||||
if (surface != pointer->focus_surface)
|
||||
{
|
||||
const MetaWaylandPointerGrabInterface *interface =
|
||||
pointer->grab->interface;
|
||||
interface->focus (pointer->grab,
|
||||
surface, for_event);
|
||||
}
|
||||
meta_wayland_pointer_update_current_focus (pointer, surface);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -43,12 +43,6 @@ struct _MetaWaylandDataSource
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
struct wl_array mime_types;
|
||||
|
||||
void (*accept) (MetaWaylandDataSource * source,
|
||||
uint32_t serial, const char *mime_type);
|
||||
void (*send) (MetaWaylandDataSource * source,
|
||||
const char *mime_type, int32_t fd);
|
||||
void (*cancel) (MetaWaylandDataSource * source);
|
||||
};
|
||||
|
||||
struct _MetaWaylandSeat
|
||||
@@ -77,8 +71,8 @@ MetaWaylandSeat *
|
||||
meta_wayland_seat_new (struct wl_display *display);
|
||||
|
||||
void
|
||||
meta_wayland_seat_update_pointer (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event);
|
||||
meta_wayland_seat_update (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event);
|
||||
|
||||
gboolean
|
||||
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
|
@@ -74,16 +74,6 @@ typedef struct
|
||||
struct wl_listener sibling_destroy_listener;
|
||||
} MetaWaylandSubsurfacePlacementOp;
|
||||
|
||||
static void
|
||||
surface_handle_buffer_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_container_of (listener, surface, buffer_destroy_listener);
|
||||
|
||||
wl_resource_post_error (surface->resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"Destroyed buffer while it was attached to the surface");
|
||||
surface->buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
surface_set_buffer (MetaWaylandSurface *surface,
|
||||
MetaWaylandBuffer *buffer)
|
||||
@@ -106,6 +96,14 @@ surface_set_buffer (MetaWaylandSurface *surface,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
surface_handle_buffer_destroy (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_container_of (listener, surface, buffer_destroy_listener);
|
||||
|
||||
surface_set_buffer (surface, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_process_damage (MetaWaylandSurface *surface,
|
||||
cairo_region_t *region)
|
||||
@@ -336,22 +334,6 @@ toplevel_surface_commit (MetaWaylandSurface *surface,
|
||||
|
||||
if (pending->frame_extents_changed)
|
||||
meta_window_set_custom_frame_extents (surface->window, &pending->frame_extents);
|
||||
|
||||
if (pending->maximized.changed)
|
||||
{
|
||||
if (pending->maximized.value)
|
||||
meta_window_maximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
|
||||
else
|
||||
meta_window_unmaximize (surface->window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
|
||||
}
|
||||
|
||||
if (pending->fullscreen.changed)
|
||||
{
|
||||
if (pending->fullscreen.value)
|
||||
meta_window_make_fullscreen (surface->window);
|
||||
else
|
||||
meta_window_unmake_fullscreen (surface->window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -377,8 +359,6 @@ double_buffered_state_init (MetaWaylandDoubleBufferedState *state)
|
||||
wl_list_init (&state->frame_callback_list);
|
||||
|
||||
state->frame_extents_changed = FALSE;
|
||||
state->maximized.changed = FALSE;
|
||||
state->fullscreen.changed = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -861,44 +841,44 @@ xdg_surface_set_output (struct wl_client *client,
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_surface_set_fullscreen (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
xdg_surface_request_change_state (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t state_type,
|
||||
uint32_t value,
|
||||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
surface->pending.fullscreen.changed = TRUE;
|
||||
surface->pending.fullscreen.value = TRUE;
|
||||
surface->state_changed_serial = serial;
|
||||
|
||||
switch (state_type)
|
||||
{
|
||||
case XDG_SURFACE_STATE_MAXIMIZED:
|
||||
if (value)
|
||||
meta_window_maximize (surface->window, META_MAXIMIZE_BOTH);
|
||||
else
|
||||
meta_window_unmaximize (surface->window, META_MAXIMIZE_BOTH);
|
||||
break;
|
||||
case XDG_SURFACE_STATE_FULLSCREEN:
|
||||
if (value)
|
||||
meta_window_make_fullscreen (surface->window);
|
||||
else
|
||||
meta_window_unmake_fullscreen (surface->window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_surface_unset_fullscreen (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
xdg_surface_ack_change_state (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t state_type,
|
||||
uint32_t value,
|
||||
uint32_t serial)
|
||||
{
|
||||
MetaWaylandSurfaceExtension *xdg_surface = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface = wl_container_of (xdg_surface, surface, xdg_surface);
|
||||
|
||||
surface->pending.fullscreen.changed = TRUE;
|
||||
surface->pending.fullscreen.value = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_surface_set_maximized (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
surface->pending.maximized.changed = TRUE;
|
||||
surface->pending.maximized.value = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_surface_unset_maximized (struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
|
||||
|
||||
surface->pending.maximized.changed = TRUE;
|
||||
surface->pending.maximized.value = FALSE;
|
||||
/* Do nothing for now. In the future, we'd imagine that
|
||||
* we'd ignore attaches when we have a state pending that
|
||||
* we haven't had the client ACK'd, to prevent a race
|
||||
* condition when we have an in-flight attach when the
|
||||
* client gets the new state. */
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -919,10 +899,8 @@ static const struct xdg_surface_interface meta_wayland_xdg_surface_interface = {
|
||||
xdg_surface_move,
|
||||
xdg_surface_resize,
|
||||
xdg_surface_set_output,
|
||||
xdg_surface_set_fullscreen,
|
||||
xdg_surface_unset_fullscreen,
|
||||
xdg_surface_set_maximized,
|
||||
xdg_surface_unset_maximized,
|
||||
xdg_surface_request_change_state,
|
||||
xdg_surface_ack_change_state,
|
||||
xdg_surface_set_minimized,
|
||||
};
|
||||
|
||||
@@ -1011,8 +989,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
|
||||
surface->window->placed = TRUE;
|
||||
meta_window_set_transient_for (surface->window, parent_surf->window);
|
||||
|
||||
surface->window->type = META_WINDOW_DROPDOWN_MENU;
|
||||
meta_window_type_changed (surface->window);
|
||||
meta_window_set_type (surface->window, META_WINDOW_DROPDOWN_MENU);
|
||||
|
||||
meta_wayland_pointer_start_popup_grab (&seat->pointer, surface);
|
||||
}
|
||||
@@ -1174,9 +1151,9 @@ wl_shell_surface_set_state (MetaWaylandSurface *surface,
|
||||
meta_window_unmake_fullscreen (surface->window);
|
||||
|
||||
if (state == SURFACE_STATE_MAXIMIZED)
|
||||
meta_window_maximize (surface->window, META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL);
|
||||
meta_window_maximize (surface->window, META_MAXIMIZE_BOTH);
|
||||
else
|
||||
meta_window_unmaximize (surface->window, META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL);
|
||||
meta_window_unmaximize (surface->window, META_MAXIMIZE_BOTH);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1465,8 +1442,6 @@ subsurface_parent_surface_committed (MetaWaylandSurface *surface)
|
||||
|
||||
if (surface->sub.synchronous)
|
||||
commit_double_buffered_state (surface, pending_surface_state);
|
||||
|
||||
double_buffered_state_reset (pending_surface_state);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1738,6 +1713,55 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
|
||||
0, new_width, new_height);
|
||||
}
|
||||
|
||||
static void
|
||||
send_change_state (MetaWaylandSurface *surface,
|
||||
uint32_t state_type,
|
||||
uint32_t value)
|
||||
{
|
||||
if (surface->xdg_surface.resource)
|
||||
{
|
||||
uint32_t serial;
|
||||
|
||||
if (surface->state_changed_serial != 0)
|
||||
{
|
||||
serial = surface->state_changed_serial;
|
||||
surface->state_changed_serial = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (surface->xdg_surface.resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
serial = wl_display_next_serial (display);
|
||||
}
|
||||
|
||||
xdg_surface_send_change_state (surface->xdg_surface.resource, state_type, value, serial);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_send_maximized (MetaWaylandSurface *surface)
|
||||
{
|
||||
send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_send_unmaximized (MetaWaylandSurface *surface)
|
||||
{
|
||||
send_change_state (surface, XDG_SURFACE_STATE_MAXIMIZED, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_send_fullscreened (MetaWaylandSurface *surface)
|
||||
{
|
||||
send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_send_unfullscreened (MetaWaylandSurface *surface)
|
||||
{
|
||||
send_change_state (surface, XDG_SURFACE_STATE_FULLSCREEN, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_activated (MetaWaylandSurface *surface)
|
||||
{
|
||||
|
@@ -41,12 +41,6 @@ struct _MetaWaylandBuffer
|
||||
uint32_t ref_count;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint changed : 1;
|
||||
guint value : 1;
|
||||
} MetaWaylandStateFlag;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* wl_surface.attach */
|
||||
@@ -67,9 +61,6 @@ typedef struct
|
||||
|
||||
gboolean frame_extents_changed;
|
||||
GtkBorder frame_extents;
|
||||
|
||||
MetaWaylandStateFlag fullscreen;
|
||||
MetaWaylandStateFlag maximized;
|
||||
} MetaWaylandDoubleBufferedState;
|
||||
|
||||
typedef struct
|
||||
@@ -107,6 +98,8 @@ struct _MetaWaylandSurface
|
||||
GSList *pending_placement_ops;
|
||||
} sub;
|
||||
|
||||
uint32_t state_changed_serial;
|
||||
|
||||
/* All the pending state, that wl_surface.commit will apply. */
|
||||
MetaWaylandDoubleBufferedState pending;
|
||||
};
|
||||
@@ -124,6 +117,10 @@ void meta_wayland_surface_window_unmanaged (MetaWaylandSurface *s
|
||||
void meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
|
||||
int width,
|
||||
int height);
|
||||
void meta_wayland_surface_send_maximized (MetaWaylandSurface *surface);
|
||||
void meta_wayland_surface_send_unmaximized (MetaWaylandSurface *surface);
|
||||
void meta_wayland_surface_send_fullscreened (MetaWaylandSurface *surface);
|
||||
void meta_wayland_surface_send_unfullscreened (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_activated (MetaWaylandSurface *surface);
|
||||
void meta_wayland_surface_deactivated (MetaWaylandSurface *surface);
|
||||
|
@@ -151,7 +151,6 @@ meta_wayland_buffer_unref (MetaWaylandBuffer *buffer)
|
||||
if (buffer->ref_count == 0)
|
||||
{
|
||||
g_clear_pointer (&buffer->texture, cogl_object_unref);
|
||||
g_assert (wl_resource_get_client (buffer->resource));
|
||||
wl_resource_queue_event (buffer->resource, WL_BUFFER_RELEASE);
|
||||
}
|
||||
}
|
||||
@@ -508,6 +507,15 @@ stage_destroy_cb (void)
|
||||
meta_quit (META_EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_wayland_compositor_update:
|
||||
* @compositor: the #MetaWaylandCompositor instance
|
||||
* @event: the #ClutterEvent used to update @seat's state
|
||||
*
|
||||
* This is used to update display server state like updating cursor
|
||||
* position and keeping track of buttons and keys pressed. It must be
|
||||
* called for all input events coming from the underlying devices.
|
||||
*/
|
||||
void
|
||||
meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
|
||||
const ClutterEvent *event)
|
||||
@@ -536,18 +544,18 @@ meta_wayland_compositor_update (MetaWaylandCompositor *compositor,
|
||||
meta_idle_monitor_reset_idletime (device_monitor);
|
||||
}
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_MOTION:
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
case CLUTTER_SCROLL:
|
||||
meta_wayland_seat_update_pointer (compositor->seat, event);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
meta_wayland_seat_update (compositor->seat, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_wayland_compositor_handle_event:
|
||||
* @compositor: the #MetaWaylandCompositor instance
|
||||
* @event: the #ClutterEvent to be sent
|
||||
*
|
||||
* This method sends events to the focused wayland client, if any.
|
||||
*
|
||||
* Return value: whether @event was sent to a wayland client.
|
||||
*/
|
||||
gboolean
|
||||
meta_wayland_compositor_handle_event (MetaWaylandCompositor *compositor,
|
||||
const ClutterEvent *event)
|
||||
@@ -643,6 +651,8 @@ meta_wayland_init (void)
|
||||
|
||||
clutter_wayland_set_compositor_display (compositor->wayland_display);
|
||||
|
||||
/* If we're running on bare metal, we're a display server,
|
||||
* so start talking to weston-launch. */
|
||||
#if defined(CLUTTER_WINDOWING_EGL)
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
|
||||
compositor->launcher = meta_launcher_new ();
|
||||
@@ -651,17 +661,6 @@ meta_wayland_init (void)
|
||||
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
|
||||
g_error ("Failed to initialize Clutter");
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL)
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (cogl_context));
|
||||
int drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
|
||||
meta_launcher_set_drm_fd (compositor->launcher, drm_fd, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
meta_monitor_manager_initialize ();
|
||||
monitors = meta_monitor_manager_get ();
|
||||
g_signal_connect (monitors, "monitors-changed",
|
||||
@@ -728,7 +727,22 @@ meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Ignoring VT switch keybinding, not running as VT manager");
|
||||
g_debug ("Ignoring VT switch keybinding, not running as display server");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor,
|
||||
GError **error)
|
||||
{
|
||||
if (compositor->launcher)
|
||||
{
|
||||
return meta_launcher_activate_vt (compositor->launcher, -1, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Ignoring activate_session, not running as display server");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@@ -46,6 +46,8 @@ void meta_wayland_compositor_paint_finished (MetaWaylandComp
|
||||
gboolean meta_wayland_compositor_activate_vt (MetaWaylandCompositor *compositor,
|
||||
int vt,
|
||||
GError **error);
|
||||
gboolean meta_wayland_compositor_activate_session (MetaWaylandCompositor *compositor,
|
||||
GError **error);
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <gio/gunixfdmessage.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/egl/clutter-egl.h>
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
|
||||
#include <glib.h>
|
||||
@@ -41,6 +42,8 @@
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "meta-weston-launch.h"
|
||||
|
||||
struct _MetaLauncher
|
||||
@@ -154,36 +157,11 @@ send_message_to_wl (MetaLauncher *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_launcher_set_drm_fd (MetaLauncher *self,
|
||||
int drm_fd,
|
||||
GError **error)
|
||||
{
|
||||
struct weston_launcher_message message;
|
||||
GSocketControlMessage *cmsg;
|
||||
gboolean ok;
|
||||
|
||||
message.opcode = WESTON_LAUNCHER_DRM_SET_FD;
|
||||
|
||||
cmsg = g_unix_fd_message_new ();
|
||||
if (g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (cmsg),
|
||||
drm_fd, error) == FALSE)
|
||||
{
|
||||
g_object_unref (cmsg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ok = send_message_to_wl (self, &message, sizeof message, cmsg, NULL, error);
|
||||
|
||||
g_object_unref (cmsg);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int
|
||||
meta_launcher_open_input_device (MetaLauncher *self,
|
||||
const char *name,
|
||||
int flags,
|
||||
GError **error)
|
||||
static int
|
||||
meta_launcher_open_device (MetaLauncher *self,
|
||||
const char *name,
|
||||
int flags,
|
||||
GError **error)
|
||||
{
|
||||
struct weston_launcher_open *message;
|
||||
GSocketControlMessage *cmsg;
|
||||
@@ -232,6 +210,17 @@ meta_launcher_enter (MetaLauncher *launcher)
|
||||
cogl_kms_display_queue_modes_reset (cogl_display);
|
||||
|
||||
clutter_evdev_reclaim_devices ();
|
||||
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
/* When we mode-switch back, we need to immediately queue a redraw
|
||||
* in case nothing else queued one for us, and force the cursor to
|
||||
* update. */
|
||||
|
||||
clutter_actor_queue_redraw (compositor->stage);
|
||||
meta_cursor_tracker_force_update (compositor->seat->cursor_tracker);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -248,7 +237,14 @@ on_evdev_device_open (const char *path,
|
||||
{
|
||||
MetaLauncher *launcher = user_data;
|
||||
|
||||
return meta_launcher_open_input_device (launcher, path, flags, error);
|
||||
return meta_launcher_open_device (launcher, path, flags, error);
|
||||
}
|
||||
|
||||
static void
|
||||
on_evdev_device_close (int fd,
|
||||
gpointer user_data)
|
||||
{
|
||||
close (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -354,8 +350,6 @@ meta_launcher_new (void)
|
||||
|
||||
self->weston_launch = g_socket_new_from_fd (launch_fd, NULL);
|
||||
|
||||
clutter_evdev_set_open_callback (on_evdev_device_open, self);
|
||||
|
||||
self->nested_context = g_main_context_new ();
|
||||
self->nested_loop = g_main_loop_new (self->nested_context, FALSE);
|
||||
|
||||
@@ -369,6 +363,22 @@ meta_launcher_new (void)
|
||||
g_source_attach (self->inner_source, self->nested_context);
|
||||
g_source_unref (self->inner_source);
|
||||
|
||||
clutter_evdev_set_device_callbacks (on_evdev_device_open,
|
||||
on_evdev_device_close,
|
||||
self);
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL)
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
|
||||
{
|
||||
GError *error = NULL;
|
||||
int fd = meta_launcher_open_device (self, "/dev/dri/card0", O_RDWR, &error);
|
||||
if (error)
|
||||
g_error ("Failed to open /dev/dri/card0: %s", error->message);
|
||||
|
||||
clutter_egl_set_kms_fd (fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -388,7 +398,7 @@ meta_launcher_free (MetaLauncher *launcher)
|
||||
|
||||
gboolean
|
||||
meta_launcher_activate_vt (MetaLauncher *launcher,
|
||||
int vt,
|
||||
signed char vt,
|
||||
GError **error)
|
||||
{
|
||||
struct weston_launcher_activate_vt message;
|
||||
|
@@ -29,18 +29,6 @@ MetaLauncher *meta_launcher_new (void);
|
||||
void meta_launcher_free (MetaLauncher *self);
|
||||
|
||||
gboolean meta_launcher_activate_vt (MetaLauncher *self,
|
||||
int number,
|
||||
signed char vt,
|
||||
GError **error);
|
||||
|
||||
gboolean meta_launcher_set_drm_fd (MetaLauncher *self,
|
||||
int drm_fd,
|
||||
GError **error);
|
||||
gboolean meta_launcher_set_master (MetaLauncher *self,
|
||||
gboolean master,
|
||||
GError **error);
|
||||
int meta_launcher_open_input_device (MetaLauncher *self,
|
||||
const char *name,
|
||||
int flags,
|
||||
GError **error);
|
||||
|
||||
#endif
|
||||
|
@@ -47,6 +47,13 @@ xserver_set_window_id (struct wl_client *client,
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
/* If the window has an existing surface, like if we're
|
||||
* undecorating or decorating the window, then we need
|
||||
* to detach the window from its old surface.
|
||||
*/
|
||||
if (window->surface)
|
||||
window->surface->window = NULL;
|
||||
|
||||
meta_wayland_surface_make_toplevel (surface);
|
||||
|
||||
surface->window = window;
|
||||
@@ -296,9 +303,6 @@ meta_xwayland_start (MetaXWaylandManager *manager,
|
||||
pid_t pid;
|
||||
char **env;
|
||||
char *fd_string;
|
||||
char *log_path;
|
||||
char *args[10];
|
||||
GError *error;
|
||||
|
||||
wl_global_create (wl_display, &xserver_interface,
|
||||
META_XSERVER_VERSION,
|
||||
@@ -357,47 +361,43 @@ meta_xwayland_start (MetaXWaylandManager *manager,
|
||||
g_free (fd_string);
|
||||
|
||||
manager->display_name = g_strdup_printf (":%d", manager->display_index);
|
||||
log_path = g_build_filename (g_get_user_cache_dir (), "xwayland.log", NULL);
|
||||
|
||||
args[0] = XWAYLAND_PATH;
|
||||
args[1] = manager->display_name;
|
||||
args[2] = "-wayland";
|
||||
args[3] = "-rootless";
|
||||
args[4] = "-noreset";
|
||||
args[5] = "-logfile";
|
||||
args[6] = log_path;
|
||||
args[7] = "-nolisten";
|
||||
args[8] = "all";
|
||||
args[9] = NULL;
|
||||
{
|
||||
GError *error = NULL;
|
||||
gchar *args[] = { XWAYLAND_PATH,
|
||||
manager->display_name,
|
||||
"-wayland",
|
||||
"-rootless",
|
||||
"-noreset",
|
||||
"-nolisten",
|
||||
"all",
|
||||
NULL };
|
||||
|
||||
error = NULL;
|
||||
if (g_spawn_async (NULL, /* cwd */
|
||||
args,
|
||||
env,
|
||||
G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
|
||||
G_SPAWN_DO_NOT_REAP_CHILD |
|
||||
G_SPAWN_STDOUT_TO_DEV_NULL |
|
||||
G_SPAWN_STDERR_TO_DEV_NULL,
|
||||
uncloexec,
|
||||
GINT_TO_POINTER (sp[1]),
|
||||
&pid,
|
||||
&error))
|
||||
{
|
||||
g_message ("forked X server, pid %d\n", pid);
|
||||
if (g_spawn_async (NULL, /* cwd */
|
||||
args,
|
||||
env,
|
||||
G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
|
||||
G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
uncloexec,
|
||||
GINT_TO_POINTER (sp[1]),
|
||||
&pid,
|
||||
&error))
|
||||
{
|
||||
g_message ("forked X server, pid %d\n", pid);
|
||||
|
||||
close (sp[1]);
|
||||
manager->client = wl_client_create (wl_display, sp[0]);
|
||||
close (sp[1]);
|
||||
manager->client = wl_client_create (wl_display, sp[0]);
|
||||
|
||||
manager->pid = pid;
|
||||
g_child_watch_add (pid, xserver_died, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_error ("Failed to fork for xwayland server: %s", error->message);
|
||||
}
|
||||
manager->pid = pid;
|
||||
g_child_watch_add (pid, xserver_died, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_error ("Failed to fork for xwayland server: %s", error->message);
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (env);
|
||||
g_free (log_path);
|
||||
|
||||
/* We need to run a mainloop until we know xwayland has a binding
|
||||
* for our xserver interface at which point we can assume it's
|
||||
|
@@ -40,19 +40,22 @@
|
||||
|
||||
<enum name="version">
|
||||
<description summary="latest protocol version">
|
||||
Use this enum to check the protocol version, and it will be updated
|
||||
automatically.
|
||||
The 'current' member of this enum gives the version of the
|
||||
protocol. Implementations can compare this to the version
|
||||
they implement using static_assert to ensure the protocol and
|
||||
implementation versions match.
|
||||
</description>
|
||||
<entry name="current" value="2" summary="Always the latest version"/>
|
||||
<entry name="current" value="3" summary="Always the latest version"/>
|
||||
</enum>
|
||||
|
||||
|
||||
<request name="use_unstable_version">
|
||||
<description summary="enable use of this unstable version">
|
||||
Use this request in order to enable use of this interface.
|
||||
|
||||
Understand and agree that one is using an unstable interface,
|
||||
that will likely change in the future, breaking the API.
|
||||
Negotiate the unstable version of the interface. This
|
||||
mechanism is in place to ensure client and server agree on the
|
||||
unstable versions of the protocol that they speak or exit
|
||||
cleanly if they don't agree. This request will go away once
|
||||
the xdg-shell protocol is stable.
|
||||
</description>
|
||||
<arg name="version" type="int"/>
|
||||
</request>
|
||||
@@ -275,113 +278,87 @@
|
||||
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||
</request>
|
||||
|
||||
<event name="request_set_fullscreen">
|
||||
<description summary="server requests that the client set fullscreen">
|
||||
Event sent from the compositor to the client requesting that the client
|
||||
goes to a fullscreen state. It's the client job to call set_fullscreen
|
||||
and really trigger the fullscreen state.
|
||||
<enum name="state">
|
||||
<description summary="types of state on the surface">
|
||||
The different state values used on the surface. This is designed for
|
||||
state values like maximized, fullscreen. It is paired with the
|
||||
request_change_state event to ensure that both the client and the
|
||||
compositor setting the state can be synchronized.
|
||||
|
||||
States set in this way are double-buffered. They will get applied on
|
||||
the next commit.
|
||||
|
||||
Desktop environments may extend this enum by taking up a range of
|
||||
values and documenting the range they chose in this description.
|
||||
They are not required to document the values for the range that they
|
||||
chose. Ideally, any good extensions from a desktop environment should
|
||||
make its way into standardization into this enum.
|
||||
|
||||
The current reserved ranges are:
|
||||
|
||||
0x0000 - 0x0FFF: xdg-shell core values, documented below.
|
||||
0x1000 - 0x1FFF: GNOME
|
||||
</description>
|
||||
</event>
|
||||
<entry name="maximized" value="1" summary="the surface is maximized">
|
||||
A non-zero value indicates the surface is maximized. Otherwise,
|
||||
the surface is unmaximized.
|
||||
</entry>
|
||||
<entry name="fullscreen" value="2" summary="the surface is fullscreen">
|
||||
A non-zero value indicates the surface is fullscreen. Otherwise,
|
||||
the surface is not fullscreen.
|
||||
</entry>
|
||||
</enum>
|
||||
|
||||
<event name="request_unset_fullscreen">
|
||||
<description summary="server requests that the client unset fullscreen">
|
||||
Event sent from the compositor to the client requesting that the client
|
||||
leaves the fullscreen state. It's the client job to call
|
||||
unset_fullscreen and really leave the fullscreen state.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<request name="set_fullscreen">
|
||||
<description summary="set the surface state as fullscreen">
|
||||
Set the surface as fullscreen.
|
||||
|
||||
After this request, the compositor should send a configure event
|
||||
informing the output size.
|
||||
|
||||
This request informs the compositor that the next attached buffer
|
||||
committed will be in a fullscreen state. The buffer size should be the
|
||||
same size as the size informed in the configure event, if the client
|
||||
doesn't want to leave any empty area.
|
||||
|
||||
In other words: the next attached buffer after set_maximized is the new
|
||||
maximized buffer. And the surface will be positioned at the maximized
|
||||
position on commit.
|
||||
|
||||
A simple way to synchronize and wait for the correct configure event is
|
||||
to use a wl_display.sync request right after the set_fullscreen
|
||||
request. When the sync callback returns, the last configure event
|
||||
received just before it will be the correct one, and should contain the
|
||||
right size for the surface to maximize.
|
||||
|
||||
Setting one state won't unset another state. Use
|
||||
xdg_surface.unset_fullscreen for unsetting it.
|
||||
<request name="request_change_state">
|
||||
<description summary="client requests to change a surface's state">
|
||||
This asks the compositor to change the state. If the compositor wants
|
||||
to change the state, it will send a change_state event with the same
|
||||
state_type, value, and serial, and the event flow continues as if it
|
||||
it was initiated by the compositor.
|
||||
|
||||
If the compositor does not want to change the state, it will send a
|
||||
change_state to the client with the old value of the state.
|
||||
</description>
|
||||
<arg name="state_type" type="uint" summary="the state to set"/>
|
||||
<arg name="value" type="uint" summary="the value to change the state to"/>
|
||||
<arg name="serial" type="uint" summary="an event serial">
|
||||
This serial is so the client can know which change_state event corresponds
|
||||
to which request_change_state request it sent out.
|
||||
</arg>
|
||||
</request>
|
||||
|
||||
<request name="unset_fullscreen">
|
||||
<description summary="unset the surface state as fullscreen">
|
||||
Unset the surface fullscreen state.
|
||||
|
||||
Same negotiation as set_fullscreen must be used.
|
||||
<event name="change_state">
|
||||
<description summary="compositor wants to change a surface's state">
|
||||
This event tells the client to change a surface's state. The client
|
||||
should respond with an ack_change_state request to the compositor to
|
||||
guarantee that the compositor knows that the client has seen it.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="request_set_maximized">
|
||||
<description summary="server requests that the client set maximized">
|
||||
Event sent from the compositor to the client requesting that the client
|
||||
goes to a maximized state. It's the client job to call set_maximized
|
||||
and really trigger the maximized state.
|
||||
</description>
|
||||
<arg name="state_type" type="uint" summary="the state to set"/>
|
||||
<arg name="value" type="uint" summary="the value to change the state to"/>
|
||||
<arg name="serial" type="uint" summary="a serial for the compositor's own tracking"/>
|
||||
</event>
|
||||
|
||||
<event name="request_unset_maximized">
|
||||
<description summary="server requests that the client unset maximized">
|
||||
Event sent from the compositor to the client requesting that the client
|
||||
leaves the maximized state. It's the client job to call unset_maximized
|
||||
and really leave the maximized state.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<request name="set_maximized">
|
||||
<description summary="set the surface state as maximized">
|
||||
Set the surface as maximized.
|
||||
|
||||
After this request, the compositor will send a configure event
|
||||
informing the output size minus panel and other MW decorations.
|
||||
|
||||
This request informs the compositor that the next attached buffer
|
||||
committed will be in a maximized state. The buffer size should be the
|
||||
same size as the size informed in the configure event, if the client
|
||||
doesn't want to leave any empty area.
|
||||
|
||||
In other words: the next attached buffer after set_maximized is the new
|
||||
maximized buffer. And the surface will be positioned at the maximized
|
||||
position on commit.
|
||||
|
||||
A simple way to synchronize and wait for the correct configure event is
|
||||
to use a wl_display.sync request right after the set_maximized request.
|
||||
When the sync callback returns, the last configure event received just
|
||||
before it will be the correct one, and should contain the right size
|
||||
for the surface to maximize.
|
||||
|
||||
Setting one state won't unset another state. Use
|
||||
xdg_surface.unset_maximized for unsetting it.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="unset_maximized">
|
||||
<description summary="unset the surface state as maximized">
|
||||
Unset the surface maximized state.
|
||||
|
||||
Same negotiation as set_maximized must be used.
|
||||
<request name="ack_change_state">
|
||||
<description summary="ack a change_state event">
|
||||
When a change_state event is received, a client should then ack it
|
||||
using the ack_change_state request to ensure that the compositor
|
||||
knows the client has seen the event.
|
||||
|
||||
By this point, the state is confirmed, and the next attach should
|
||||
contain the buffer drawn for the new state value.
|
||||
|
||||
The values here need to be the same as the values in the cooresponding
|
||||
change_state event.
|
||||
</description>
|
||||
<arg name="state_type" type="uint" summary="the state to set"/>
|
||||
<arg name="value" type="uint" summary="the value to change the state to"/>
|
||||
<arg name="serial" type="uint" summary="a serial to pass to change_state"/>
|
||||
</request>
|
||||
|
||||
<request name="set_minimized">
|
||||
<description summary="set the surface state as minimized">
|
||||
Set the surface minimized state.
|
||||
|
||||
Setting one state won't unset another state.
|
||||
<description summary="minimize the surface">
|
||||
Minimize the surface.
|
||||
</description>
|
||||
</request>
|
||||
|
@@ -80,6 +80,7 @@ struct weston_launch {
|
||||
struct termios terminal_attributes;
|
||||
int kb_mode;
|
||||
enum vt_state vt_state;
|
||||
unsigned vt;
|
||||
|
||||
int drm_fd;
|
||||
};
|
||||
@@ -164,69 +165,6 @@ setenv_fd(const char *env, int fd)
|
||||
setenv(env, buf, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
handle_setdrmfd(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
struct cmsghdr *cmsg;
|
||||
union cmsg_data *data;
|
||||
struct stat s;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_DRM_SET_FD;
|
||||
reply.ret = -1;
|
||||
|
||||
if (wl->drm_fd != -1) {
|
||||
error(0, 0, "DRM FD already set");
|
||||
reply.ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(msg);
|
||||
if (!cmsg ||
|
||||
cmsg->cmsg_level != SOL_SOCKET ||
|
||||
cmsg->cmsg_type != SCM_RIGHTS) {
|
||||
error(0, 0, "invalid control message");
|
||||
reply.ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
data = (union cmsg_data *) CMSG_DATA(cmsg);
|
||||
if (data->fd < 0) {
|
||||
error(0, 0, "missing drm fd in socket request");
|
||||
reply.ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (fstat(data->fd, &s) < 0) {
|
||||
reply.ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (major(s.st_rdev) != DRM_MAJOR) {
|
||||
fprintf(stderr, "FD is not for DRM\n");
|
||||
reply.ret = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wl->drm_fd = data->fd;
|
||||
reply.ret = drmSetMaster(data->fd);
|
||||
if (reply.ret < 0)
|
||||
reply.ret = -errno;
|
||||
|
||||
if (wl->verbose)
|
||||
fprintf(stderr, "mutter-launch: set drm FD, ret: %d, fd: %d\n",
|
||||
reply.ret, data->fd);
|
||||
|
||||
out:
|
||||
do {
|
||||
len = send(wl->sock[0], &reply, sizeof reply, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_confirm_vt_switch(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
@@ -274,6 +212,7 @@ handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
struct weston_launcher_activate_vt *message;
|
||||
unsigned vt;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
|
||||
reply.ret = -1;
|
||||
@@ -285,7 +224,13 @@ handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
|
||||
message = msg->msg_iov->iov_base;
|
||||
|
||||
reply.ret = ioctl(wl->tty, VT_ACTIVATE, message->vt);
|
||||
/* Negative values mean that we're activating our own VT */
|
||||
if (message->vt > 0)
|
||||
vt = message->vt;
|
||||
else
|
||||
vt = wl->vt;
|
||||
|
||||
reply.ret = ioctl(wl->tty, VT_ACTIVATE, vt);
|
||||
if (reply.ret < 0)
|
||||
reply.ret = -errno;
|
||||
|
||||
@@ -315,6 +260,7 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
struct iovec iov;
|
||||
struct weston_launcher_open *message;
|
||||
union cmsg_data *data;
|
||||
int dev_major;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_OPEN;
|
||||
reply.ret = -1;
|
||||
@@ -331,6 +277,22 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
goto err0;
|
||||
}
|
||||
|
||||
dev_major = major(s.st_rdev);
|
||||
|
||||
if (dev_major != INPUT_MAJOR &&
|
||||
dev_major != DRM_MAJOR) {
|
||||
fprintf(stderr, "Device %s is not an input or DRM device\n",
|
||||
message->path);
|
||||
reply.ret = -EPERM;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (dev_major == DRM_MAJOR && wl->drm_fd != -1) {
|
||||
fprintf(stderr, "Already have a DRM device open\n");
|
||||
reply.ret = -EPERM;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
fd = open(message->path, message->flags);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error opening device %s: %m\n",
|
||||
@@ -339,13 +301,8 @@ handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (major(s.st_rdev) != INPUT_MAJOR) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
fprintf(stderr, "Device %s is not an input device\n",
|
||||
message->path);
|
||||
reply.ret = -EPERM;
|
||||
goto err0;
|
||||
if (dev_major == DRM_MAJOR) {
|
||||
wl->drm_fd = fd;
|
||||
}
|
||||
|
||||
err0:
|
||||
@@ -413,9 +370,6 @@ handle_socket_msg(struct weston_launch *wl)
|
||||
case WESTON_LAUNCHER_OPEN:
|
||||
ret = handle_open(wl, &msg, len);
|
||||
break;
|
||||
case WESTON_LAUNCHER_DRM_SET_FD:
|
||||
ret = handle_setdrmfd(wl, &msg, len);
|
||||
break;
|
||||
case WESTON_LAUNCHER_CONFIRM_VT_SWITCH:
|
||||
ret = handle_confirm_vt_switch(wl, &msg, len);
|
||||
break;
|
||||
@@ -554,7 +508,7 @@ setup_tty(struct weston_launch *wl)
|
||||
struct stat buf;
|
||||
struct termios raw_attributes;
|
||||
struct vt_mode mode = { 0 };
|
||||
char *session, *tty;
|
||||
char *session;
|
||||
char path[PATH_MAX];
|
||||
int ok;
|
||||
|
||||
@@ -562,44 +516,13 @@ setup_tty(struct weston_launch *wl)
|
||||
if (ok < 0)
|
||||
error(1, -ok, "could not determine current session");
|
||||
|
||||
ok = sd_session_get_tty(session, &tty);
|
||||
if (ok == 0) {
|
||||
/* Old systemd only has the tty name in the TTY
|
||||
field, new one has the full char device path.
|
||||
|
||||
Check what we have and fix it properly.
|
||||
*/
|
||||
if (strncmp(tty, "/dev", strlen("/dev")) == 0) {
|
||||
strncpy(path, tty, PATH_MAX);
|
||||
path[PATH_MAX-1] = 0;
|
||||
} else {
|
||||
snprintf(path, PATH_MAX, "/dev/%s", tty);
|
||||
}
|
||||
|
||||
wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
free(tty);
|
||||
#ifdef HAVE_SD_SESSION_GET_VT
|
||||
} else if (ok == -ENOENT) {
|
||||
unsigned vt;
|
||||
|
||||
/* Negative errnos are cool, right?
|
||||
So cool that we can't distinguish "session not found"
|
||||
from "key does not exist in the session file"!
|
||||
Let's assume the latter, as we got the value
|
||||
from sd_pid_get_session()...
|
||||
*/
|
||||
|
||||
ok = sd_session_get_vt(session, &vt);
|
||||
if (ok < 0)
|
||||
error(1, -ok, "could not determine current TTY");
|
||||
|
||||
snprintf(path, PATH_MAX, "/dev/tty%u", vt);
|
||||
wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
free(tty);
|
||||
#endif
|
||||
} else
|
||||
ok = sd_session_get_vt(session, &wl->vt);
|
||||
if (ok < 0)
|
||||
error(1, -ok, "could not determine current TTY");
|
||||
|
||||
snprintf(path, PATH_MAX, "/dev/tty%u", wl->vt);
|
||||
wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
|
||||
if (wl->tty < 0)
|
||||
error(1, errno, "failed to open tty");
|
||||
|
||||
|
@@ -31,9 +31,8 @@ enum weston_launcher_message_type {
|
||||
|
||||
enum weston_launcher_opcode {
|
||||
WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_DRM_SET_FD = (2 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_ACTIVATE_VT = (3 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (4 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_ACTIVATE_VT = (2 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
};
|
||||
|
||||
enum weston_launcher_server_opcode {
|
||||
@@ -53,7 +52,7 @@ struct weston_launcher_open {
|
||||
|
||||
struct weston_launcher_activate_vt {
|
||||
struct weston_launcher_message header;
|
||||
int vt;
|
||||
signed char vt;
|
||||
};
|
||||
|
||||
struct weston_launcher_reply {
|
||||
|
214
src/wayland/window-wayland.c
Normal file
214
src/wayland/window-wayland.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "window-wayland.h"
|
||||
|
||||
#include "window-private.h"
|
||||
#include "boxes-private.h"
|
||||
#include "stack-tracker.h"
|
||||
#include "meta-wayland-surface.h"
|
||||
|
||||
struct _MetaWindowWayland
|
||||
{
|
||||
MetaWindow parent;
|
||||
};
|
||||
|
||||
struct _MetaWindowWaylandClass
|
||||
{
|
||||
MetaWindowClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW)
|
||||
|
||||
static void
|
||||
meta_window_wayland_manage (MetaWindow *window)
|
||||
{
|
||||
MetaDisplay *display = window->display;
|
||||
|
||||
meta_display_register_wayland_window (display, window);
|
||||
|
||||
{
|
||||
MetaStackWindow stack_window;
|
||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND;
|
||||
stack_window.wayland.meta_window = window;
|
||||
meta_stack_tracker_record_add (window->screen->stack_tracker,
|
||||
&stack_window,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_unmanage (MetaWindow *window)
|
||||
{
|
||||
{
|
||||
MetaStackWindow stack_window;
|
||||
stack_window.any.type = META_WINDOW_CLIENT_TYPE_WAYLAND;
|
||||
stack_window.wayland.meta_window = window;
|
||||
meta_stack_tracker_record_remove (window->screen->stack_tracker,
|
||||
&stack_window,
|
||||
0);
|
||||
}
|
||||
|
||||
meta_display_unregister_wayland_window (window->display, window);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_ping (MetaWindow *window,
|
||||
guint32 serial)
|
||||
{
|
||||
meta_wayland_surface_ping (window->surface, serial);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_delete (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
meta_wayland_surface_delete (window->surface);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_kill (MetaWindow *window)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_focus (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
meta_display_set_input_focus_window (window->display,
|
||||
window,
|
||||
FALSE,
|
||||
timestamp);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
int gravity,
|
||||
MetaRectangle requested_rect,
|
||||
MetaRectangle constrained_rect,
|
||||
MetaMoveResizeFlags flags,
|
||||
MetaMoveResizeResultFlags *result)
|
||||
{
|
||||
g_assert (window->frame == NULL);
|
||||
|
||||
/* For wayland clients, the size is completely determined by the client,
|
||||
* and while this allows to avoid some trickery with frames and the resulting
|
||||
* lagging, we also need to insist a bit when the constraints would apply
|
||||
* a different size than the client decides.
|
||||
*
|
||||
* Note that this is not generally a problem for normal toplevel windows (the
|
||||
* constraints don't see the size hints, or just change the position), but
|
||||
* it can be for maximized or fullscreen.
|
||||
*/
|
||||
|
||||
/* First, save where we would like the client to be. This is used by the next
|
||||
* attach to determine if the client is really moving/resizing or not.
|
||||
*/
|
||||
window->expected_rect = constrained_rect;
|
||||
|
||||
if (flags & META_IS_WAYLAND_RESIZE)
|
||||
{
|
||||
/* This is a call to wl_surface_commit(), ignore the constrained_rect and
|
||||
* update the real client size to match the buffer size.
|
||||
*/
|
||||
|
||||
window->rect.width = requested_rect.width;
|
||||
window->rect.height = requested_rect.height;
|
||||
}
|
||||
|
||||
if (constrained_rect.width != window->rect.width ||
|
||||
constrained_rect.height != window->rect.height)
|
||||
{
|
||||
/* We need to resize the client. Resizing is in two parts:
|
||||
* some of the movement happens immediately, and some happens as part
|
||||
* of the resizing (through dx/dy in wl_surface_attach).
|
||||
*
|
||||
* To do so, we need to compute the resize from the point of the view
|
||||
* of the client, and then adjust the immediate resize to match.
|
||||
*
|
||||
* dx/dy are the values we expect from the new attach(), while deltax/
|
||||
* deltay reflect the overall movement.
|
||||
*/
|
||||
MetaRectangle old_rect;
|
||||
MetaRectangle client_rect;
|
||||
int dx, dy;
|
||||
int deltax, deltay;
|
||||
|
||||
meta_window_get_client_root_coords (window, &old_rect);
|
||||
|
||||
meta_rectangle_resize_with_gravity (&old_rect,
|
||||
&client_rect,
|
||||
gravity,
|
||||
constrained_rect.width,
|
||||
constrained_rect.height);
|
||||
|
||||
deltax = constrained_rect.x - old_rect.x;
|
||||
deltay = constrained_rect.y - old_rect.y;
|
||||
dx = client_rect.x - constrained_rect.x;
|
||||
dy = client_rect.y - constrained_rect.y;
|
||||
|
||||
if (deltax != dx || deltay != dy)
|
||||
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
||||
|
||||
window->rect.x += (deltax - dx);
|
||||
window->rect.y += (deltay - dy);
|
||||
|
||||
*result |= META_MOVE_RESIZE_RESULT_RESIZED;
|
||||
meta_wayland_surface_configure_notify (window->surface,
|
||||
constrained_rect.width,
|
||||
constrained_rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No resize happening, we can just move the window and live with it. */
|
||||
if (window->rect.x != constrained_rect.x ||
|
||||
window->rect.y != constrained_rect.y)
|
||||
*result |= META_MOVE_RESIZE_RESULT_MOVED;
|
||||
|
||||
window->rect.x = constrained_rect.x;
|
||||
window->rect.y = constrained_rect.y;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_init (MetaWindowWayland *window_wayland)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
|
||||
{
|
||||
MetaWindowClass *window_class = META_WINDOW_CLASS (klass);
|
||||
|
||||
window_class->manage = meta_window_wayland_manage;
|
||||
window_class->unmanage = meta_window_wayland_unmanage;
|
||||
window_class->ping = meta_window_wayland_ping;
|
||||
window_class->delete = meta_window_wayland_delete;
|
||||
window_class->kill = meta_window_wayland_kill;
|
||||
window_class->focus = meta_window_wayland_focus;
|
||||
window_class->move_resize_internal = meta_window_wayland_move_resize_internal;
|
||||
}
|
44
src/wayland/window-wayland.h
Normal file
44
src/wayland/window-wayland.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#ifndef META_WINDOW_WAYLAND_H
|
||||
#define META_WINDOW_WAYLAND_H
|
||||
|
||||
#include <meta/window.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_WINDOW_WAYLAND (meta_window_wayland_get_type())
|
||||
#define META_WINDOW_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_WAYLAND, MetaWindowWayland))
|
||||
#define META_WINDOW_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_WAYLAND, MetaWindowWaylandClass))
|
||||
#define META_IS_WINDOW_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_WAYLAND))
|
||||
#define META_IS_WINDOW_WAYLAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_WAYLAND))
|
||||
#define META_WINDOW_WAYLAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_WAYLAND, MetaWindowWaylandClass))
|
||||
|
||||
GType meta_window_wayland_get_type (void);
|
||||
|
||||
typedef struct _MetaWindowWayland MetaWindowWayland;
|
||||
typedef struct _MetaWindowWaylandClass MetaWindowWaylandClass;
|
||||
|
||||
#endif
|
@@ -35,11 +35,12 @@
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _SVID_SOURCE /* for gethostname() */
|
||||
#define _XOPEN_SOURCE 500 /* for gethostname() */
|
||||
|
||||
#include <config.h>
|
||||
#include "window-props.h"
|
||||
#include "window-x11.h"
|
||||
#include "window-x11-private.h"
|
||||
#include <meta/errors.h>
|
||||
#include "xprops.h"
|
||||
#include "frame.h"
|
||||
@@ -428,9 +429,8 @@ reload_net_wm_user_time_window (MetaWindow *window,
|
||||
/**
|
||||
* set_title_text:
|
||||
*
|
||||
* Called by set_window_title() and set_icon_title() to set the value of
|
||||
* @target to @title. It required and @atom is set, it will update the
|
||||
* appropriate property.
|
||||
* Called by set_window_title() to set the value of @target to @title.
|
||||
* If required and @atom is set, it will update the appropriate property.
|
||||
*
|
||||
* Returns: %TRUE if a new title was set.
|
||||
*/
|
||||
@@ -488,15 +488,18 @@ static void
|
||||
set_window_title (MetaWindow *window,
|
||||
const char *title)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
char *new_title = NULL;
|
||||
|
||||
|
||||
gboolean modified =
|
||||
set_title_text (window,
|
||||
window->using_net_wm_visible_name,
|
||||
priv->using_net_wm_visible_name,
|
||||
title,
|
||||
window->display->atom__NET_WM_VISIBLE_NAME,
|
||||
&new_title);
|
||||
window->using_net_wm_visible_name = modified;
|
||||
priv->using_net_wm_visible_name = modified;
|
||||
|
||||
meta_window_set_title (window, new_title);
|
||||
|
||||
@@ -508,10 +511,13 @@ reload_net_wm_name (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
set_window_title (window, value->v.str);
|
||||
window->using_net_wm_name = TRUE;
|
||||
priv->using_net_wm_name = TRUE;
|
||||
|
||||
meta_verbose ("Using _NET_WM_NAME for new title of %s: \"%s\"\n",
|
||||
window->desc, window->title);
|
||||
@@ -519,7 +525,7 @@ reload_net_wm_name (MetaWindow *window,
|
||||
else
|
||||
{
|
||||
set_window_title (window, NULL);
|
||||
window->using_net_wm_name = FALSE;
|
||||
priv->using_net_wm_name = FALSE;
|
||||
if (!initial)
|
||||
meta_window_reload_property (window, XA_WM_NAME, FALSE);
|
||||
}
|
||||
@@ -530,7 +536,10 @@ reload_wm_name (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (window->using_net_wm_name)
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
if (priv->using_net_wm_name)
|
||||
{
|
||||
meta_verbose ("Ignoring WM_NAME \"%s\" as _NET_WM_NAME is set\n",
|
||||
value->v.str);
|
||||
@@ -601,71 +610,14 @@ reload_mutter_hints (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_icon_title (MetaWindow *window,
|
||||
const char *title)
|
||||
{
|
||||
gboolean modified =
|
||||
set_title_text (window,
|
||||
window->using_net_wm_visible_icon_name,
|
||||
title,
|
||||
window->display->atom__NET_WM_VISIBLE_ICON_NAME,
|
||||
&window->icon_name);
|
||||
window->using_net_wm_visible_icon_name = modified;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_icon_name (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
set_icon_title (window, value->v.str);
|
||||
window->using_net_wm_icon_name = TRUE;
|
||||
|
||||
meta_verbose ("Using _NET_WM_ICON_NAME for new title of %s: \"%s\"\n",
|
||||
window->desc, window->title);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_icon_title (window, NULL);
|
||||
window->using_net_wm_icon_name = FALSE;
|
||||
if (!initial)
|
||||
meta_window_reload_property (window, XA_WM_ICON_NAME, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reload_wm_icon_name (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (window->using_net_wm_icon_name)
|
||||
{
|
||||
meta_verbose ("Ignoring WM_ICON_NAME \"%s\" as _NET_WM_ICON_NAME is set\n",
|
||||
value->v.str);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
set_icon_title (window, value->v.str);
|
||||
|
||||
meta_verbose ("Using WM_ICON_NAME for new title of %s: \"%s\"\n",
|
||||
window->desc, window->title);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_icon_title (window, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_state (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
int i;
|
||||
|
||||
/* We know this is only an initial window creation,
|
||||
@@ -683,9 +635,9 @@ reload_net_wm_state (MetaWindow *window,
|
||||
window->maximized_horizontally = FALSE;
|
||||
window->maximized_vertically = FALSE;
|
||||
window->fullscreen = FALSE;
|
||||
window->wm_state_modal = FALSE;
|
||||
window->wm_state_skip_taskbar = FALSE;
|
||||
window->wm_state_skip_pager = FALSE;
|
||||
priv->wm_state_modal = FALSE;
|
||||
priv->wm_state_skip_taskbar = FALSE;
|
||||
priv->wm_state_skip_pager = FALSE;
|
||||
window->wm_state_above = FALSE;
|
||||
window->wm_state_below = FALSE;
|
||||
window->wm_state_demands_attention = FALSE;
|
||||
@@ -705,11 +657,11 @@ reload_net_wm_state (MetaWindow *window,
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_HIDDEN)
|
||||
window->minimize_after_placement = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_MODAL)
|
||||
window->wm_state_modal = TRUE;
|
||||
priv->wm_state_modal = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_TASKBAR)
|
||||
window->wm_state_skip_taskbar = TRUE;
|
||||
priv->wm_state_skip_taskbar = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER)
|
||||
window->wm_state_skip_pager = TRUE;
|
||||
priv->wm_state_skip_pager = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_FULLSCREEN)
|
||||
window->fullscreen_after_placement = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE)
|
||||
@@ -727,7 +679,7 @@ reload_net_wm_state (MetaWindow *window,
|
||||
meta_verbose ("Reloaded _NET_WM_STATE for %s\n",
|
||||
window->desc);
|
||||
|
||||
meta_window_recalc_window_type (window);
|
||||
meta_window_x11_recalc_window_type (window);
|
||||
meta_window_recalc_features (window);
|
||||
}
|
||||
|
||||
@@ -1438,10 +1390,9 @@ reload_wm_hints (MetaWindow *window,
|
||||
gboolean initial)
|
||||
{
|
||||
Window old_group_leader;
|
||||
gboolean old_urgent;
|
||||
gboolean urgent;
|
||||
|
||||
old_group_leader = window->xgroup_leader;
|
||||
old_urgent = window->wm_hints_urgent;
|
||||
|
||||
/* Fill in defaults */
|
||||
window->input = TRUE;
|
||||
@@ -1449,7 +1400,7 @@ reload_wm_hints (MetaWindow *window,
|
||||
window->xgroup_leader = None;
|
||||
window->wm_hints_pixmap = None;
|
||||
window->wm_hints_mask = None;
|
||||
window->wm_hints_urgent = FALSE;
|
||||
urgent = FALSE;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -1471,7 +1422,7 @@ reload_wm_hints (MetaWindow *window,
|
||||
window->wm_hints_mask = hints->icon_mask;
|
||||
|
||||
if (hints->flags & XUrgencyHint)
|
||||
window->wm_hints_urgent = TRUE;
|
||||
urgent = TRUE;
|
||||
|
||||
meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n",
|
||||
window->input, window->initially_iconic,
|
||||
@@ -1488,20 +1439,7 @@ reload_wm_hints (MetaWindow *window,
|
||||
meta_window_group_leader_changed (window);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not emit urgency notification on the inital property load
|
||||
*/
|
||||
if (!initial && (window->wm_hints_urgent != old_urgent))
|
||||
g_object_notify (G_OBJECT (window), "urgent");
|
||||
|
||||
/*
|
||||
* Do not emit signal for the initial property load, let the constructor to
|
||||
* take care of it once the MetaWindow is fully constructed.
|
||||
*
|
||||
* Only emit if the property is both changed and set.
|
||||
*/
|
||||
if (!initial && window->wm_hints_urgent && !old_urgent)
|
||||
g_signal_emit_by_name (window->display, "window-marked-urgent", window);
|
||||
meta_window_set_urgent (window, urgent);
|
||||
|
||||
meta_icon_cache_property_changed (&window->icon_cache,
|
||||
window->display,
|
||||
@@ -1733,8 +1671,6 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
{ XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name, TRUE, TRUE },
|
||||
{ display->atom__MUTTER_HINTS, META_PROP_VALUE_TEXT_PROPERTY, reload_mutter_hints, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_OPAQUE_REGION, META_PROP_VALUE_CARDINAL_LIST, reload_opaque_region, TRUE, TRUE },
|
||||
{ display->atom__NET_WM_ICON_NAME, META_PROP_VALUE_UTF8, reload_net_wm_icon_name, TRUE, FALSE },
|
||||
{ XA_WM_ICON_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_icon_name, TRUE, FALSE },
|
||||
{ display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop, TRUE, FALSE },
|
||||
{ display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id, TRUE, FALSE },
|
||||
{ display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER_LIST, reload_update_counter, TRUE, TRUE },
|
57
src/x11/window-x11-private.h
Normal file
57
src/x11/window-x11-private.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington, Anders Carlsson
|
||||
* Copyright (C) 2002, 2003 Red Hat, Inc.
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "window-private.h"
|
||||
|
||||
#ifndef META_WINDOW_X11_PRIVATE_H
|
||||
#define META_WINDOW_X11_PRIVATE_H
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _MetaWindowX11Private MetaWindowX11Private;
|
||||
|
||||
struct _MetaWindowX11
|
||||
{
|
||||
MetaWindow parent;
|
||||
|
||||
MetaWindowX11Private *priv;
|
||||
};
|
||||
|
||||
struct _MetaWindowX11Private
|
||||
{
|
||||
/* TRUE if the client forced these on */
|
||||
guint wm_state_skip_taskbar : 1;
|
||||
guint wm_state_skip_pager : 1;
|
||||
|
||||
/* Weird "_NET_WM_STATE_MODAL" flag */
|
||||
guint wm_state_modal : 1;
|
||||
|
||||
/* Info on which props we got our attributes from */
|
||||
guint using_net_wm_name : 1; /* vs. plain wm_name */
|
||||
guint using_net_wm_visible_name : 1; /* tracked so we can clear it */
|
||||
|
||||
Atom type_atom;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,20 @@
|
||||
#include <meta/window.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_WINDOW_X11 (meta_window_x11_get_type())
|
||||
#define META_WINDOW_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_X11, MetaWindowX11))
|
||||
#define META_WINDOW_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_X11, MetaWindowX11Class))
|
||||
#define META_IS_WINDOW_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_X11))
|
||||
#define META_IS_WINDOW_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_X11))
|
||||
#define META_WINDOW_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_X11, MetaWindowX11Class))
|
||||
|
||||
GType meta_window_x11_get_type (void);
|
||||
|
||||
typedef struct _MetaWindowX11 MetaWindowX11;
|
||||
typedef struct _MetaWindowX11Class MetaWindowX11Class;
|
||||
|
||||
void meta_window_x11_set_net_wm_state (MetaWindow *window);
|
||||
void meta_window_x11_set_wm_state (MetaWindow *window);
|
||||
|
||||
@@ -35,6 +49,8 @@ void meta_window_x11_update_opaque_region (MetaWindow *window);
|
||||
void meta_window_x11_update_input_region (MetaWindow *window);
|
||||
void meta_window_x11_update_shape_region (MetaWindow *window);
|
||||
|
||||
void meta_window_x11_recalc_window_type (MetaWindow *window);
|
||||
|
||||
gboolean meta_window_x11_configure_request (MetaWindow *window,
|
||||
XEvent *event);
|
||||
gboolean meta_window_x11_property_notify (MetaWindow *window,
|
||||
@@ -42,4 +58,7 @@ gboolean meta_window_x11_property_notify (MetaWindow *window,
|
||||
gboolean meta_window_x11_client_message (MetaWindow *window,
|
||||
XEvent *event);
|
||||
|
||||
void meta_window_x11_configure_notify (MetaWindow *window,
|
||||
XConfigureEvent *event);
|
||||
|
||||
#endif
|
@@ -1,7 +0,0 @@
|
||||
# completely hacked-up makefile, proceed at your own risk, etc
|
||||
|
||||
default:
|
||||
@echo "Try 'make tp' or 'make glib'"
|
||||
|
||||
tp: tokentest.c
|
||||
gcc `pkg-config --cflags --libs glib-2.0 gdk-2.0 atk` -DMUTTER_DATADIR=\"/usr/share/mutter\" -I../.. -I../../src -I../../src/include tokentest.c ../../src/ui/theme.c ../../src/ui/gradient.c -o tp
|
@@ -1,19 +0,0 @@
|
||||
Tokeniser test
|
||||
==============
|
||||
This directory contains a set of tools for checking the behaviour
|
||||
of the tokeniser for Metacity theme files.
|
||||
|
||||
tokentest.ini contains a list of all expressions retrieved from
|
||||
all theme files on art.gnome.org, and mappings to what the tokenising
|
||||
should be, in a separate representation. get-tokens.py produces the
|
||||
template version of this; it will produce a file with no expected
|
||||
values.
|
||||
|
||||
tokentest.c will either check that a tokeniser behaves according to
|
||||
tokentest.ini, or, if it finds a file, is empty it will print the
|
||||
values that the tokeniser it's using is producing.
|
||||
|
||||
The makefile is a hacky attempt at letting you compile either against
|
||||
Metacity's existing tokeniser or one which uses GLib's "scanner".
|
||||
|
||||
This code may or may not eventually end up in the automated test suite.
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user