Compare commits
441 Commits
METACITY_2
...
release-2.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8ae90af01f | ||
![]() |
31f48c0cf0 | ||
![]() |
cd0ef08783 | ||
![]() |
4203fd2993 | ||
![]() |
54e56a47da | ||
![]() |
d8a28621cc | ||
![]() |
8216cbc4f6 | ||
![]() |
9a4d1d1375 | ||
![]() |
616e140420 | ||
![]() |
52ea2fd45d | ||
![]() |
050c1e268d | ||
![]() |
7afc4310f6 | ||
![]() |
39a3bb2c7d | ||
![]() |
7eb2843718 | ||
![]() |
91490ed713 | ||
![]() |
081272c5a9 | ||
![]() |
f4bc825cf8 | ||
![]() |
fb1fc4e7c6 | ||
![]() |
ed3d222327 | ||
![]() |
8c0ae7be83 | ||
![]() |
5780ffad12 | ||
![]() |
770a6f0138 | ||
![]() |
16d49695ad | ||
![]() |
6893ef034b | ||
![]() |
9b5d91e33b | ||
![]() |
c7686b2977 | ||
![]() |
3e754a6f35 | ||
![]() |
63744a3dd7 | ||
![]() |
e5db44ca90 | ||
![]() |
032cbe0dd5 | ||
![]() |
7d34a10e4a | ||
![]() |
62f1fc62a7 | ||
![]() |
c26cb4d2be | ||
![]() |
a203fb1037 | ||
![]() |
adeec009e7 | ||
![]() |
8e6c0bec78 | ||
![]() |
69ae9e4a9d | ||
![]() |
1381f6d5f2 | ||
![]() |
a6c951352f | ||
![]() |
0a172cc053 | ||
![]() |
f5fa4a3866 | ||
![]() |
8cbcbb0655 | ||
![]() |
35d9d2864f | ||
![]() |
bb5c0d0c34 | ||
![]() |
226cdc9645 | ||
![]() |
1b35154e2b | ||
![]() |
7c69ab987a | ||
![]() |
ba03230e72 | ||
![]() |
77cb0db9c2 | ||
![]() |
ad080410a3 | ||
![]() |
dab72c3efa | ||
![]() |
32f882093b | ||
![]() |
6ac54641c6 | ||
![]() |
1d38209520 | ||
![]() |
c1f3a5c67d | ||
![]() |
6e543fbcfd | ||
![]() |
9dee164790 | ||
![]() |
b0cc2a8614 | ||
![]() |
f4ecc9bab8 | ||
![]() |
c3884e9900 | ||
![]() |
39c88facc5 | ||
![]() |
1dce6b5fa3 | ||
![]() |
6b1aa3cf04 | ||
![]() |
2e1893f7d3 | ||
![]() |
d1fd844bc4 | ||
![]() |
db273ce50c | ||
![]() |
2338611046 | ||
![]() |
7d3a05f2d1 | ||
![]() |
a02e0b3c98 | ||
![]() |
952d63a127 | ||
![]() |
23bed522ab | ||
![]() |
813acae961 | ||
![]() |
352e2c02dc | ||
![]() |
9ebb135ccb | ||
![]() |
a96939be0f | ||
![]() |
cb3870f9f6 | ||
![]() |
25d628aea2 | ||
![]() |
aad8eb1999 | ||
![]() |
fc6b78a20c | ||
![]() |
4b3a8fefb6 | ||
![]() |
ec0562550a | ||
![]() |
73e14e0bb1 | ||
![]() |
822e125492 | ||
![]() |
b47cd6a3bc | ||
![]() |
95fa3a3879 | ||
![]() |
0b978e61aa | ||
![]() |
d6b974ba15 | ||
![]() |
ec09ac49f6 | ||
![]() |
ee738f1d6f | ||
![]() |
17c10f60d9 | ||
![]() |
24823e19e0 | ||
![]() |
c8e967ba1c | ||
![]() |
f7aa5f8653 | ||
![]() |
6da5a5abcb | ||
![]() |
0fdb644454 | ||
![]() |
f6a3ba26f9 | ||
![]() |
d1920788ac | ||
![]() |
fc1ff18ca7 | ||
![]() |
5f9a4ab8cc | ||
![]() |
920a847508 | ||
![]() |
1e17ba1768 | ||
![]() |
e17377d407 | ||
![]() |
b47459af58 | ||
![]() |
986bdac451 | ||
![]() |
b5b37d72a3 | ||
![]() |
096e3dee8f | ||
![]() |
e25282088b | ||
![]() |
da36829f96 | ||
![]() |
ff5055834b | ||
![]() |
b41abfd1f8 | ||
![]() |
e1cc242b52 | ||
![]() |
4589d1246d | ||
![]() |
66a5edd31a | ||
![]() |
57dec338ba | ||
![]() |
9ecc00a33b | ||
![]() |
ae6032e58e | ||
![]() |
c4d7e0568f | ||
![]() |
c311e96b63 | ||
![]() |
b66fbc0369 | ||
![]() |
151ddc08ec | ||
![]() |
b81c7c48d5 | ||
![]() |
e11100e584 | ||
![]() |
01027006a7 | ||
![]() |
38faa8fe10 | ||
![]() |
9abdc6c0fa | ||
![]() |
34b483ed75 | ||
![]() |
c48c5e44bd | ||
![]() |
b943a74476 | ||
![]() |
13badba158 | ||
![]() |
e1e5cc8f42 | ||
![]() |
6e1ed9ad55 | ||
![]() |
dd2370d9dd | ||
![]() |
45f2ec5f64 | ||
![]() |
e7a69b6a13 | ||
![]() |
10b12f24f0 | ||
![]() |
3b1e91342e | ||
![]() |
e7cef5bbcb | ||
![]() |
6ddec0d855 | ||
![]() |
c0d90e5b76 | ||
![]() |
6c22a997e6 | ||
![]() |
945c9cb8e0 | ||
![]() |
cf2206352f | ||
![]() |
4c5f125a6a | ||
![]() |
1fd45f10a2 | ||
![]() |
3592f8e92e | ||
![]() |
036fe284c2 | ||
![]() |
a1cc5fea1f | ||
![]() |
9442d21f44 | ||
![]() |
a0cd86d2ac | ||
![]() |
157aa0af6d | ||
![]() |
88cd978837 | ||
![]() |
e146c24483 | ||
![]() |
41b6f0803e | ||
![]() |
68ac59ff6d | ||
![]() |
c2abbce2ed | ||
![]() |
38cd6a6c1f | ||
![]() |
ac365b4ead | ||
![]() |
e083742426 | ||
![]() |
e5fc168a46 | ||
![]() |
be7067bc0a | ||
![]() |
1ba3b3dd7d | ||
![]() |
a06d96316e | ||
![]() |
6e8c233d6a | ||
![]() |
c627368ea1 | ||
![]() |
8524f510c6 | ||
![]() |
39e389cc5b | ||
![]() |
d079ef538c | ||
![]() |
203046237c | ||
![]() |
7a5606d241 | ||
![]() |
c4768a3b9f | ||
![]() |
af8d281556 | ||
![]() |
0f73a011ce | ||
![]() |
53cea00323 | ||
![]() |
b7466365a1 | ||
![]() |
3b3226b678 | ||
![]() |
ab2e925b65 | ||
![]() |
0214ece238 | ||
![]() |
a6d04255a8 | ||
![]() |
9821453b5f | ||
![]() |
c61eb77a70 | ||
![]() |
57a2d20d61 | ||
![]() |
8c3bcc7229 | ||
![]() |
f956853550 | ||
![]() |
6849735e9d | ||
![]() |
06817df975 | ||
![]() |
98ccfea388 | ||
![]() |
9a1be03205 | ||
![]() |
026008a700 | ||
![]() |
b26fc771b1 | ||
![]() |
04619df818 | ||
![]() |
c1928ead7c | ||
![]() |
b43f9aec5a | ||
![]() |
79d749fc82 | ||
![]() |
bcc5f104db | ||
![]() |
99f6b2cdce | ||
![]() |
75d3845801 | ||
![]() |
c8e0acfef3 | ||
![]() |
da55d8e738 | ||
![]() |
40c25dc426 | ||
![]() |
f3a8b2f12e | ||
![]() |
dcd350dd90 | ||
![]() |
f826fb1d9a | ||
![]() |
123f4df31b | ||
![]() |
3211fb04d3 | ||
![]() |
17e12ccb6d | ||
![]() |
6eab4fb9e8 | ||
![]() |
8f8097aa2c | ||
![]() |
7a190f33f6 | ||
![]() |
7ec7a8fa44 | ||
![]() |
93b945ea42 | ||
![]() |
0058271aaa | ||
![]() |
cfa45beee1 | ||
![]() |
51468bfb56 | ||
![]() |
f7b0c532aa | ||
![]() |
20ce1e77d9 | ||
![]() |
368346571a | ||
![]() |
7ea4380725 | ||
![]() |
15daecacdc | ||
![]() |
1b943f8191 | ||
![]() |
6d8baea4c2 | ||
![]() |
4c9bfecac5 | ||
![]() |
6683b5efff | ||
![]() |
783e51281a | ||
![]() |
5dc36e1201 | ||
![]() |
6a86912554 | ||
![]() |
7405f040e8 | ||
![]() |
5ed940e101 | ||
![]() |
11f18a25c2 | ||
![]() |
d819b99d99 | ||
![]() |
b5ac24e9c1 | ||
![]() |
d1635d13cb | ||
![]() |
f80e39e2ca | ||
![]() |
a7a0a0300f | ||
![]() |
685bbb2e64 | ||
![]() |
e85f67f564 | ||
![]() |
a2b47741ae | ||
![]() |
eeb762e1e2 | ||
![]() |
6c5fc6b3d6 | ||
![]() |
3991e82539 | ||
![]() |
312cbf3e04 | ||
![]() |
ce2bfc008d | ||
![]() |
b2fe0097e6 | ||
![]() |
e4501f801e | ||
![]() |
7bef175590 | ||
![]() |
a4a102726e | ||
![]() |
a42ea69d0e | ||
![]() |
8f594c93cd | ||
![]() |
8f8a193c7e | ||
![]() |
c283fbe9b3 | ||
![]() |
53d89a7fd5 | ||
![]() |
68c2f75558 | ||
![]() |
2a3445c865 | ||
![]() |
10f9a7f252 | ||
![]() |
b1c5a2e221 | ||
![]() |
1d6e70a49d | ||
![]() |
310970a91b | ||
![]() |
07c1003905 | ||
![]() |
273d213509 | ||
![]() |
8201b0361a | ||
![]() |
f97f20e3b0 | ||
![]() |
fc4ef3417f | ||
![]() |
4d441a6f7b | ||
![]() |
c1348f0322 | ||
![]() |
647f75c4e8 | ||
![]() |
348795b94d | ||
![]() |
bb539466d5 | ||
![]() |
ab9bdf228b | ||
![]() |
c91475f20f | ||
![]() |
445b6ae6ed | ||
![]() |
2e9857b560 | ||
![]() |
3cc7b2c74d | ||
![]() |
275cccb136 | ||
![]() |
8c1a5c6a11 | ||
![]() |
7a9da7eb69 | ||
![]() |
788cbc91b2 | ||
![]() |
9cb0b6ff52 | ||
![]() |
22d5f3fa57 | ||
![]() |
627dcede64 | ||
![]() |
fbefdce4c1 | ||
![]() |
77785ac321 | ||
![]() |
922b490499 | ||
![]() |
ee49194cf5 | ||
![]() |
f2bf9703db | ||
![]() |
1866268c94 | ||
![]() |
b7ee7bdd9b | ||
![]() |
ba3cf5dfad | ||
![]() |
f186d90dd3 | ||
![]() |
671b69a251 | ||
![]() |
fd01dbaaea | ||
![]() |
be11a6bf72 | ||
![]() |
4854710de2 | ||
![]() |
0684ef95c5 | ||
![]() |
775cb1f4a4 | ||
![]() |
73f90dfd69 | ||
![]() |
8a0ffa93eb | ||
![]() |
7ddb3a4663 | ||
![]() |
493408167b | ||
![]() |
a8f1a61242 | ||
![]() |
4c3a5883d7 | ||
![]() |
9a66ce6b01 | ||
![]() |
08c3c187eb | ||
![]() |
b422faa4fe | ||
![]() |
a8dd848ca4 | ||
![]() |
143cb3d60b | ||
![]() |
92610f53c3 | ||
![]() |
6904b7a5d7 | ||
![]() |
30ece059cf | ||
![]() |
1e59d63e31 | ||
![]() |
7380163eaf | ||
![]() |
dc33ad1adf | ||
![]() |
b5414c27a3 | ||
![]() |
2f790b0165 | ||
![]() |
d185a84140 | ||
![]() |
749698eb54 | ||
![]() |
6323467879 | ||
![]() |
d94a34a2c1 | ||
![]() |
9005e4a68f | ||
![]() |
9e4f5a26dd | ||
![]() |
ae906b318a | ||
![]() |
8d373e009d | ||
![]() |
7d67a9aee9 | ||
![]() |
f0364b2eed | ||
![]() |
5af56eebd1 | ||
![]() |
5f3e27bbd7 | ||
![]() |
b1b8d51264 | ||
![]() |
3ee8a903e8 | ||
![]() |
f6c958ff26 | ||
![]() |
27fac47e76 | ||
![]() |
6144787b3e | ||
![]() |
c1e7ead397 | ||
![]() |
c4fe54d004 | ||
![]() |
48f1dd5a7e | ||
![]() |
ff0fa107a4 | ||
![]() |
acd81439eb | ||
![]() |
b625ed254d | ||
![]() |
334370f5d1 | ||
![]() |
66c031315d | ||
![]() |
74b34fe239 | ||
![]() |
7124a7acc1 | ||
![]() |
2fffd6fe9f | ||
![]() |
6b1719de1c | ||
![]() |
0225449e12 | ||
![]() |
1a8e5872d1 | ||
![]() |
0e6fba083f | ||
![]() |
1178800abb | ||
![]() |
f061a6d793 | ||
![]() |
976635a22b | ||
![]() |
69c0da91e5 | ||
![]() |
306a7497fc | ||
![]() |
1addb6ddc1 | ||
![]() |
0a7fc94799 | ||
![]() |
cca5e69c64 | ||
![]() |
bbdd7d9b15 | ||
![]() |
60695fd89a | ||
![]() |
c5d59254af | ||
![]() |
2bcd7c839b | ||
![]() |
cc50d99712 | ||
![]() |
93c316f3b8 | ||
![]() |
7983c29f67 | ||
![]() |
22f386b35b | ||
![]() |
d6e4fc41c2 | ||
![]() |
f65d898f80 | ||
![]() |
a49f986c67 | ||
![]() |
b1fb765d8e | ||
![]() |
9e72d661d6 | ||
![]() |
03ccf99dbb | ||
![]() |
f67f9bbf23 | ||
![]() |
85e67d1d49 | ||
![]() |
735877d89a | ||
![]() |
ee60128334 | ||
![]() |
3bbd5e32f2 | ||
![]() |
c2403a0c62 | ||
![]() |
839082aae8 | ||
![]() |
98753ed946 | ||
![]() |
0ee05e6617 | ||
![]() |
2d4a0c9cbe | ||
![]() |
43e3fbc518 | ||
![]() |
c58ade6600 | ||
![]() |
33ae559eca | ||
![]() |
4f1fd37231 | ||
![]() |
6654cb65d7 | ||
![]() |
19d338cb50 | ||
![]() |
0bbe8b8004 | ||
![]() |
99d3cc1b2b | ||
![]() |
c5d86fae01 | ||
![]() |
d6f340eb96 | ||
![]() |
bd3d643f96 | ||
![]() |
7bd5f61db7 | ||
![]() |
0037a5fccc | ||
![]() |
1ea071fc18 | ||
![]() |
bc1e74153c | ||
![]() |
65a10829fd | ||
![]() |
0c0e102023 | ||
![]() |
914c93ae0d | ||
![]() |
a1c3a05b43 | ||
![]() |
f53e03f0a2 | ||
![]() |
5e76e1b221 | ||
![]() |
9b3a0d1ad8 | ||
![]() |
d509097967 | ||
![]() |
b7bdc5ec69 | ||
![]() |
0e8c8ba825 | ||
![]() |
f19aff7818 | ||
![]() |
52d14ee16d | ||
![]() |
4774a798a7 | ||
![]() |
28793c9f81 | ||
![]() |
3109a67a71 | ||
![]() |
d4662bb6a2 | ||
![]() |
13a8cdcbb3 | ||
![]() |
d2a4800e75 | ||
![]() |
ba19215cd4 | ||
![]() |
cf48407972 | ||
![]() |
f227fc4872 | ||
![]() |
0407545283 | ||
![]() |
438ac55cb1 | ||
![]() |
0fd855f492 | ||
![]() |
177202e2d1 | ||
![]() |
18d9d15a1a | ||
![]() |
6946d6a4a3 | ||
![]() |
2bcb7d73be | ||
![]() |
655bfaec80 | ||
![]() |
a3f56bb289 | ||
![]() |
b48f9ca907 | ||
![]() |
8589eab403 | ||
![]() |
1ee1842638 | ||
![]() |
70afce0325 | ||
![]() |
1f29679c0d | ||
![]() |
99b547bc1d | ||
![]() |
030afac8ab | ||
![]() |
121a65e4f4 | ||
![]() |
a8bcfb9a0c | ||
![]() |
9f9df52ba6 | ||
![]() |
676a516ff2 | ||
![]() |
4134949d72 | ||
![]() |
e6e6aecb93 | ||
![]() |
f7f696c310 | ||
![]() |
5ebaa15333 | ||
![]() |
e1965914a3 | ||
![]() |
fa2f76d4d4 | ||
![]() |
2c6c5a6dd1 | ||
![]() |
c29232fd0d | ||
![]() |
8fd2f1d22a |
60
.gitignore
vendored
Normal file
60
.gitignore
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
Makefile.in.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
.deps
|
||||
src/metacity-wm.desktop
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
.libs
|
||||
*.swp
|
||||
tidy-enum-types.[ch]
|
||||
tidy-marshal.[ch]
|
||||
stamp-tidy-enum-types.h
|
||||
stamp-tidy-marshal.h
|
||||
stamp-h1
|
||||
*.gmo
|
||||
*.make
|
||||
*~
|
||||
stamp-it
|
||||
.intltool-merge-cache
|
||||
POTFILES
|
||||
50-metacity-desktop-key.xml
|
||||
50-metacity-key.xml
|
||||
inlinepixbufs.h
|
||||
libmetacity-private.pc
|
||||
metacity
|
||||
metacity-dialog
|
||||
metacity-theme-viewer
|
||||
metacity.desktop
|
||||
metacity.schemas
|
||||
testasyncgetprop
|
||||
testboxes
|
||||
testgradient
|
||||
metacity-grayscale
|
||||
metacity-mag
|
||||
metacity-message
|
||||
metacity-window-demo
|
||||
focus-window
|
||||
test-gravity
|
||||
test-resizing
|
||||
test-size-hints
|
||||
wm-tester
|
||||
INSTALL
|
||||
mkinstalldirs
|
728
ChangeLog
728
ChangeLog
@@ -1,3 +1,731 @@
|
||||
2009-02-01 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.144 release.
|
||||
|
||||
2009-02-01 Matt Kraai <kraai@ftbfs.org>
|
||||
|
||||
Set prop_hooks_table to NULL after freeing it.
|
||||
|
||||
* src/core/window-props.c:
|
||||
|
||||
2009-01-29 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Window properties are looked up in a hash table rather than
|
||||
by iteration over an array. Saves ~44us per window, but
|
||||
also makes the code cleaner.
|
||||
|
||||
* src/core/display-private.h:
|
||||
* src/core/window-props.c:
|
||||
|
||||
2009-01-27 Matthias Claesen <mclasen@redhat.com>
|
||||
|
||||
* src/core/edge-resistance.c: some lists failed to keep track
|
||||
of their contents and therefore didn't free correctly.
|
||||
Closes #552303.
|
||||
|
||||
2009-01-27 Matthias Claesen <mclasen@redhat.com>
|
||||
|
||||
* src/core/prefs.c: Free name of old theme when new theme
|
||||
is loaded. Closes #552973.
|
||||
|
||||
2009-01-27 Matthias Claesen <mclasen@redhat.com>
|
||||
|
||||
* src/ui/ui.c: free the result of gdk_text_property_to_utf8_list()
|
||||
even when it returns no data.
|
||||
|
||||
2009-01-27 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
GtkStyle is specific to a particular colormap. Metacity
|
||||
uses different colormaps for windows with different
|
||||
visuals, so it must specialize the GtkStyle.
|
||||
|
||||
Closes #568365 and #513944.
|
||||
|
||||
* src/ui/frames.[ch]: Keep a GtkStyle for each MetaUIFrame, which is
|
||||
obtained by calling gtk_style_attach() on the style for the
|
||||
MetaFrames. When the style of the MetaFrames changes, reattach
|
||||
everything. When we call gtk_style_set_background() pass in the
|
||||
right style.
|
||||
|
||||
* src/ui/themes.[ch]: Create a _with_style() variant of functions that
|
||||
previously took the style from widget->style passed in, so we
|
||||
can draw with the right style for the colormap.
|
||||
|
||||
2009-01-27 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Added a gconf key to swap the meanings of the right and
|
||||
middle buttons when the modifier key is held down.
|
||||
Closes #437910. Thanks to Matt Kraai for looking over
|
||||
the patch.
|
||||
|
||||
* src/core/display.c:
|
||||
* src/core/prefs.c:
|
||||
* src/include/prefs.h:
|
||||
* src/metacity.schemas.in.in:
|
||||
|
||||
2009-01-27 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
All the window properties are now handled using simple
|
||||
window property handlers. Closes #549886.
|
||||
|
||||
* src/core/window-private.h:
|
||||
* src/core/window-props.c:
|
||||
* src/core/window.c:
|
||||
|
||||
2009-01-26 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
More of the window properties are checked using simple
|
||||
window property handlers. The ones which remain don't
|
||||
actually look up the new value in the ordinary way, and
|
||||
so are a little trickier to merge. Added an "initial"
|
||||
flag to be on the safe side that the behaviour is the
|
||||
same as before (so we don't do things when a window's
|
||||
first mapped that we only used to do when a property
|
||||
changed). Partial fix for bug #549886.
|
||||
|
||||
* src/core/window-props.c:
|
||||
* src/core/window-props.h:
|
||||
* src/core/window.c:
|
||||
|
||||
2009-01-25 Elijah Newren <newren gmail com>
|
||||
|
||||
* src/core/window.c: add support for _NET_WM_MOVERESIZE_CANCEL.
|
||||
|
||||
2009-01-10 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/ui/theme.[ch]: add meta_theme_draw_frame_by_name, which
|
||||
is needed for the theme editor.
|
||||
|
||||
2008-12-26 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Post-release bump to 2.25.144.
|
||||
|
||||
2008-12-26 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.89 release.
|
||||
|
||||
2008-12-25 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/include/all-keybindings.h: alt-F10 toggles maximisation,
|
||||
alt-F5 only restores. Also rename "unmaximize" to "restore".
|
||||
* src/ui/frames.c: Rename "unmaximize" to "restore".
|
||||
Closes #343824.
|
||||
|
||||
2008-12-25 Frederic Peters <fpeters@0d.be>
|
||||
|
||||
* src/core/main.c: (main): added call to g_thread_init(), as ORBit2
|
||||
stopped doing it and Metacity is using gconf; closes #565517.
|
||||
|
||||
2008-12-24 Yanko Kaneti <yaneti@declera.com>
|
||||
|
||||
* src/metacity.schemas.in.in: add screenshot commands which had
|
||||
mistakenly been removed; closes #564343, Launchpad bug 298463,
|
||||
Red Hat bug 474635, and probably others.
|
||||
|
||||
2008-12-24 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/include/all-keybindings.h: fix move_to_corner_se
|
||||
|
||||
2008-12-21 Colin Walters <walters@verbum.org>
|
||||
|
||||
* src/core/window.c: windows which attempt to present themselves
|
||||
but are offscreen end up demanding attention, unless they
|
||||
are transient, when they move to the current workspace
|
||||
as before. Closes #482354.
|
||||
|
||||
2008-12-19 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/ui/frames.c: when the user double-clicks the title bar,
|
||||
end the grab op. Closes #401028.
|
||||
|
||||
2008-12-16 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Post-release bump to 2.25.89.
|
||||
|
||||
2008-12-16 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.55 release.
|
||||
|
||||
2008-12-15 Erwann Chenede <erwann.chenede@sun.com>
|
||||
|
||||
* configure.in: fix build on Solaris. Closes #564123.
|
||||
|
||||
2008-12-02 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Post-release bump to 2.25.55.
|
||||
|
||||
2008-12-02 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.34 release.
|
||||
|
||||
2008-12-02 Matt Kraai <kraai@ftbfs.org>
|
||||
|
||||
* src/core/iconcache.c: patches to fixes for -Wall. Closes #562939.
|
||||
|
||||
2008-12-01 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Post-release bump to 2.25.34.
|
||||
|
||||
2008-12-01 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.21 release.
|
||||
|
||||
2008-12-01 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: gnome-doc-tools version doesn't need to be so high.
|
||||
* src/compositor/compositor-xrender.c: disable the entire file if the
|
||||
compositor is disabled.
|
||||
* src/core/async-getprop.[ch]: fixes for -Wall
|
||||
* src/core/iconcache.c: fixes for -Wall
|
||||
* src/core/testasyncgetprop.c: fixes for -Wall
|
||||
* src/core/xprops.c: fixes for -Wall
|
||||
|
||||
2008-11-26 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* tools/announce-wrangler.py: linked language codes to po files
|
||||
* tools/commit-wrangler.py: print revision url
|
||||
|
||||
2008-11-26 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* tools/announce-wrangler.py: renamed ini file
|
||||
* tools/commit-wrangler.py: rewriting in terms of moap
|
||||
|
||||
2008-11-25 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Post-release bump to 2.25.21.
|
||||
|
||||
2008-11-25 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.13 release.
|
||||
|
||||
2008-11-26 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* tools/announce-wrangler.py (added): script to produce announcements
|
||||
|
||||
2008-11-26 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/xprops.c: add casts (#562106)
|
||||
|
||||
2008-11-25 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* metacity.doap: change to standard description.
|
||||
|
||||
2008-11-23 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Post-release bump to 2.25.13.
|
||||
|
||||
2008-11-23 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.8 release.
|
||||
|
||||
2008-11-23 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* po/POTFILES.in: add new bindings file
|
||||
|
||||
2008-11-23 Daniel Macks <dmacks@netspace.org>
|
||||
|
||||
reviewed by: Thomas Thurman
|
||||
|
||||
* src/Makefile.am: reorder compiler flags so local includes come last.
|
||||
Closes #562033.
|
||||
|
||||
2008-11-23 Daniel Macks <dmacks@netspace.org>
|
||||
|
||||
reviewed by: Thomas Thurman
|
||||
|
||||
* configure.in: only accept --enable-compositor if we find we can
|
||||
actually composite. Closes #560990.
|
||||
|
||||
2008-11-23 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/display.c: remove apparently spurious warnings about
|
||||
operations on window "none"
|
||||
|
||||
2008-11-23 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/util.c: Set _POSIX_C_SOURCE to 200112L as it should always
|
||||
have been, in an attempt to close #561962.
|
||||
|
||||
2008-11-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Set -ansi so people stop complaining about C99.
|
||||
|
||||
2008-11-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/prefs.c: fix stupid infinite loop when GConf is turned off.
|
||||
|
||||
2008-11-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/prefs.c: fix two places where there was a warning
|
||||
if GConf was turned off.
|
||||
|
||||
2008-11-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/all-keybindings.h: "backward", not "backwards" throughout.
|
||||
|
||||
2008-11-20 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: turned on -Wall and -Werror in order to
|
||||
trap as many problems as possible.
|
||||
* src/ui/resizepopup.c: added correct #include.
|
||||
* src/ui/theme-viewer.c: initialised variable.
|
||||
* src/core/xprops.c: corrected cast.
|
||||
* src/core/main.c: added warning if chdir() fails.
|
||||
* src/core/schema-bindings.c: checking the return
|
||||
result of fgets().
|
||||
|
||||
2008-11-20 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Merged screen and window keybinding tables so that
|
||||
we can use just one file for the both. Also incidentally
|
||||
closes #528337. Further efficiencies of scale to come.
|
||||
|
||||
* src/include/prefs.h: replace META_PREF_*_KEYBINDINGS
|
||||
with META_PREF_KEYBINDINGS
|
||||
* src/core/keybindings.c: replace *_bindings with key_bindings
|
||||
and similar throughout; all window-based functions are now
|
||||
guaranteed to receive a window so don't need to check for
|
||||
themselves
|
||||
(find_handler): moved so it can also be called from
|
||||
rebuild_binding_table
|
||||
* src/core/display-private.h: replace *_bindings with key_bindings
|
||||
* src/core/prefs.c: update_*_binding becomes update_key_binding;
|
||||
(change_notify): tidy up references to "enormous if statement"
|
||||
since it's almost entirely gone now
|
||||
* src/core/all-keybindings.h: new merged version of
|
||||
screen-bindings.h and window-bindings.h.
|
||||
|
||||
2008-11-16 David Trowbridge <trowbrds@gmail.com>
|
||||
|
||||
This change adds support for the new _NET_WM_FULLSCREEN_MONITORS
|
||||
property and client message. This allows client applications to request
|
||||
that a fullscreen window cover more than one monitor.
|
||||
|
||||
* src/include/boxes.h:
|
||||
* src/core/boxes.c: Add meta_rectangle_union
|
||||
|
||||
* src/core/window-private.h:
|
||||
* src/core/window.c:
|
||||
(meta_window_new_with_attrs, meta_window_free, set_net_wm_state,
|
||||
meta_window_update_fullscreen_monitors, meta_window_client_message): Add
|
||||
MetaWindow property to store fullscreen monitors field, update
|
||||
_NET_WM_FULLSCREEN_MONITORS property on windows, and handle client
|
||||
message.
|
||||
|
||||
* src/core/atomnames.h: Add _NET_WM_FULLSCREEN_MONITORS atom.
|
||||
|
||||
* src/core/constraints.c (setup_constraint_info): If
|
||||
_NET_WM_FULLSCREEN_MONITORS is interesting, use the data stored in
|
||||
MetaWindow::fullscreen_monitors to determine the fullscreen area instead
|
||||
of the basic xinerama_info area.
|
||||
|
||||
2008-11-11 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Removed deprecated calls. Closes #560445.
|
||||
|
||||
* src/core/delete.c: remove deprecated g_strcasecmp.
|
||||
* src/include/main.h: no actual deprecated call, but
|
||||
a mention of one which was out of date.
|
||||
|
||||
2008-11-11 Maxim Ermilov <zaspire@rambler.ru>
|
||||
|
||||
Clean up #includes according to the GNOME Goal.
|
||||
Closes #560449. Patch is 122467.
|
||||
|
||||
* src/core/place.c:
|
||||
* src/ui/draw-workspace.h:
|
||||
* src/ui/gradient.h:
|
||||
* src/ui/metaaccellabel.c:
|
||||
* src/ui/metaaccellabel.h:
|
||||
* src/ui/preview-widget.c:
|
||||
* src/ui/preview-widget.h:
|
||||
* src/ui/resizepopup.c:
|
||||
* src/ui/theme.c:
|
||||
* src/ui/theme.h:
|
||||
* src/ui/themewidget.h:
|
||||
|
||||
2008-11-10 Elijah Newren <newren gmail com>
|
||||
|
||||
* src/metacity.schemas.in.in: updated description of
|
||||
raise_on_click:
|
||||
http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6
|
||||
|
||||
2008-11-08 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: added dependency on Zenity
|
||||
* src/core/keybindings.c: remove error_on_generic_command() and
|
||||
error_on_terminal_command(); rewrite error_on_command
|
||||
in terms of meta_show_dialog()
|
||||
* src/core/util.c: add meta_show_dialog() to call Zenity
|
||||
* src/include/util.h: ditto
|
||||
|
||||
2008-11-03 Olav Vitters <olav@bkor.dhs.org>
|
||||
|
||||
* src/ui/theme-parser.c: Fix build by readding accidentally removed
|
||||
'}'.
|
||||
|
||||
2008-10-29 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/ui/theme-parser.c: variable names in messages should be
|
||||
double-quoted. Closes #558309.
|
||||
|
||||
2008-10-28 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/include/screen-bindings.h: fix accidental name change of
|
||||
run_command_terminal. Closes #557943.
|
||||
|
||||
2008-10-27 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/prefs.c (titlebar_handler, handle_preference_update_enum):
|
||||
Add initialisation which I missed on the previous checkin. Also
|
||||
an extra comment.
|
||||
|
||||
2008-10-27 Brian Cameron <brian.cameron@sun.com>
|
||||
|
||||
Fix some crashes with the new GDM 2.24. Closes #558058.
|
||||
|
||||
* src/ui/ui.c (meta_ui_parse_modifier): another null check
|
||||
* src/core/prefs.c (titlebar_handler, button_layout_handler):
|
||||
more null checks.
|
||||
|
||||
2008-10-26 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/prefs.c (mouse_button_mods_handler): Ignore values
|
||||
of .../mouse_button_modifier key if the key's missing.
|
||||
Closes Launchpad bug #258054, Launchpad bug #266929.
|
||||
|
||||
2008-10-23 Frederic Peters <fpeters@0d.be>
|
||||
|
||||
* doc/creating_themes/C/creating-metacity-themes.xml: added missing @id
|
||||
on <book> top element.
|
||||
|
||||
2008-10-23 Frederic Peters <fpeters@0d.be>
|
||||
|
||||
* doc/creating_themes/Makefile.am:
|
||||
* doc/creating_themes/C/creating_metacity_themes.xml: renamed document
|
||||
to creating-metacity-themes to match other manuals usage of dashes.
|
||||
|
||||
2008-10-23 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Post-release bump to 2.25.8.
|
||||
|
||||
2008-10-23 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.5 release.
|
||||
|
||||
2008-10-23 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/schema-bindings.c: fix stupid thinko which
|
||||
caused defaults to be incorrect
|
||||
* src/include/window-bindings.h: "space" needs to be
|
||||
lowercase
|
||||
|
||||
2008-10-23 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Support _NET_WM_STATE_STICKY (i.e. allow third-party apps to decide
|
||||
whether a window is on all workspaces). Bug found by Ka-Hing
|
||||
Cheung. Closes #557536.
|
||||
|
||||
* src/core/window.c (set_net_wm_state): report it
|
||||
* src/core/window.c (meta_window_client_message): set sticky
|
||||
if we receive it
|
||||
* src/core/window-props.c: set sticky if we find it
|
||||
* src/core/atomnames.h: add _NET_WM_STATE_STICKY
|
||||
|
||||
2008-10-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/core/schema-bindings.c: support builds outside tree properly.
|
||||
* src/Makefile.am: ditto.
|
||||
* po/POTFILES.skip: ditto.
|
||||
|
||||
2008-10-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Post-release bump to 2.25.5.
|
||||
|
||||
2008-10-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.3 release.
|
||||
|
||||
2008-10-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: bump to 2.25.3 (thought the release script
|
||||
had already done this)
|
||||
|
||||
2008-10-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Fixes to make distcheck work again.
|
||||
|
||||
* src/Makefile.am: include *-binding.h, and make the schema
|
||||
building work when builddir != srcdir
|
||||
* po/POTFILES.in (src/core/keybindings.): include *-binding.h
|
||||
|
||||
2008-10-22 Götz Waschk <waschk@mandriva.org>
|
||||
|
||||
* configure.in: add libm reference. Closes #557357.
|
||||
|
||||
2008-10-22 Murray Cumming <murrayc@murrayc.com>
|
||||
|
||||
* doc/creating_themes/C/creating_metacity_themes.xml:
|
||||
Fixed various tags to make this validate.
|
||||
Bug #557337
|
||||
|
||||
2008-10-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.2 release.
|
||||
|
||||
2008-10-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.2 release.
|
||||
|
||||
2008-10-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.2 release.
|
||||
|
||||
2008-10-22 Joe Marcus Clarke <marcus@freebsd.org>
|
||||
|
||||
* src/core/main.c (meta_finalize, sigterm_handler): new functions
|
||||
* src/core/main.c (main): add sigterm_handler in case we receive
|
||||
a SIGTERM. Closes #553980.
|
||||
|
||||
2008-10-22 Matthew Martin <mtt.martin@gmail.com>
|
||||
|
||||
* src/core/window.c (meta_window_set_demands_attention): minimised
|
||||
windows are necessarily obscured. Closes #528927.
|
||||
|
||||
2008-10-22 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Slight transformation of the x-macros used in keybindings
|
||||
to make them clearer: write handler names out in full
|
||||
because the old suffix system was confusing to people
|
||||
skim-reading, and switched the order of the last two
|
||||
parameters so more would generally fit on a screen.
|
||||
|
||||
* src/core/keybindings.c, src/core/schema-bindings.c
|
||||
src/core/prefs.c: sympathy changes
|
||||
* src/core/window-bindings.h, src/core/screen-bindings.h:
|
||||
transformation as above
|
||||
|
||||
2008-10-21 Christian Persch <chpe@gnome.org>
|
||||
|
||||
* src/Makefile.am: fix build when schemas are not installed.
|
||||
Closes #557335.
|
||||
|
||||
2008-10-21 Tomas Frydrych <tf@linux.intel.com>
|
||||
|
||||
* src/core/screen-bindings.h: Fix off-by-one error.
|
||||
* src/core/window-bindings.h: Fix off-by-one error.
|
||||
Closes #557201.
|
||||
|
||||
2008-10-18 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
During a discussion with Rodney Dawes about making life easier
|
||||
for the translators, he pointed out that the short and long
|
||||
forms of almost all the keybindings say much the same thing
|
||||
in different words. I believe this is an unconscionable burden
|
||||
to place on translators, and have therefore merged the short
|
||||
and long descriptions into the short description. The long
|
||||
is now a general explanation of the format, plus possibly a
|
||||
notice about reversibility. Closes #469361, and should solve
|
||||
the l10n issue previously mentioned.
|
||||
|
||||
* src/core/keybindings.c: reflect changes in *-bindings.h
|
||||
* src/core/schema-bindings.c: reflect changes in *-bindings.h
|
||||
* src/core/prefs.c: reflect changes in *-bindings.h
|
||||
* src/core/window-bindings.h: Add flags field, always the same
|
||||
currently, so that it's the same as screen-bindings.h.
|
||||
Also, lose ONLY_BOUND_BY_DEFAULT, since we already had a
|
||||
rather more elegant way to perform the same effect.
|
||||
And merge the long and short descriptions.
|
||||
* src/core/screen-bindings.h (, item): Merge the long and
|
||||
short descriptions.
|
||||
|
||||
2008-10-17 Murray Cumming <murrayc@murrayc.com>
|
||||
|
||||
* configure.in: Call GNOME_DOC_INIT() so we can use the gnome-doc-utils
|
||||
variables in our Makefile.am:
|
||||
* doc/Makefile.am:
|
||||
* doc/creating_themes/Makefile.am
|
||||
* doc/creating_themes/C/creating_metacity_themes.xml:
|
||||
Added this new DocBook document, converted from the HTML here
|
||||
http://blogs.gnome.org/metacity/2008/05/30/themes/
|
||||
This will be installed for yelp and can be translated and hosted on
|
||||
library.gnome.org.
|
||||
|
||||
2008-10-15 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Since Patrick Niklaus's checkin of 2008-08-14 dealt with windows with
|
||||
no icons not using fallback icons, we don't need fallback icons.
|
||||
|
||||
* src/ui/theme.h: remove fallback icons from struct.
|
||||
* src/core/iconcache.c (meta_read_icons): don't look for fallbacks.
|
||||
* src/*/ui.[ch] (meta_ui_get_fallback_icons): removed
|
||||
* src/ui/theme-parser.c (typedef, parse_toplevel_element): don't
|
||||
parse fallback specifications.
|
||||
|
||||
2008-10-13 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* po/POTFILES.in: add screen-bindings.h
|
||||
|
||||
2008-10-13 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* po/POTFILES.in: raw schemas is now .in.in
|
||||
* po/LINGUAS: add Latin
|
||||
|
||||
2008-10-12 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Make the bindings in src/core/*-bindings.h generate
|
||||
GConf schemas too. Note that there's an i18n issue
|
||||
(documented in schema-bindings.c) which will be fixed
|
||||
next checkin.
|
||||
|
||||
* src/core/schema-bindings.c: major fixup to make it
|
||||
ready for use as part of the actual build process.
|
||||
* src/Makefile.am: added magic to make it call schema-bindings
|
||||
after it builds it.
|
||||
* src/core/window-bindings.h: added comments;
|
||||
also, window menu was listed variously as alt-Space
|
||||
and alt-Print; it should have been alt-Space.
|
||||
* src/metacity.schemas.in.in: renamed from s/\.in$//,
|
||||
sentinel added for the generated bindings,
|
||||
warning at the top now untrue, and removed.
|
||||
|
||||
2008-10-12 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Fix annoying bug where alt-tab and friends would jump
|
||||
backwards a space on initial movement.
|
||||
|
||||
* src/core/screen-bindings.h: although reversed bindings
|
||||
are necessarily reversible, don't set both bits in the
|
||||
constant, or when we test for them we'll get confused.
|
||||
|
||||
2008-10-12 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
An attempt to make life a little easier for our beloved translators;
|
||||
this has the same behaviour as before, but removes over thirty
|
||||
translation strings.
|
||||
|
||||
* src/core/session.c (start_element_handler): all "attribute not found
|
||||
on element" strings are identical
|
||||
* src/ui/theme-parser.c (locate_attributes): allow attribute names to
|
||||
be preceded with "!" (in the code) to show they're required.
|
||||
(parse_aspect_ratio, parse_distance, parse_toplevel_element,
|
||||
parse_style_element, parse_gradient_element, static, parse_border,
|
||||
parse_style_set_element, parse_draw_op_element): use the new "!"
|
||||
prefix for locate_attributes(), or in some cases just the identical
|
||||
constant, for generating this error.
|
||||
* src/ui/theme.c (check_state, meta_theme_validate): add
|
||||
translator comments
|
||||
* src/ui/resizepopup.c (update_size_window): add
|
||||
translator comments
|
||||
|
||||
2008-10-06 William Lachance <wrlach@gmail.com>
|
||||
|
||||
Pass modified mouse button events down to panel windows
|
||||
instead of dealing with them ourselves. Closes #554428.
|
||||
|
||||
* src/core/display.c (prefs_changed_callback): don't grab mouse
|
||||
buttons on panels
|
||||
* src/core/window.c (meta_window_new_with_attrs): ditto
|
||||
|
||||
2008-10-05 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Second half of the switch to using x-macros for keybindings so that
|
||||
we don't have lots of places with the same information which must
|
||||
stay in the same order. This time it's screen bindings.
|
||||
|
||||
* src/core/screen-bindings.h: New file, containing screen bindings.
|
||||
* src/core/schema-bindings.c: added ability to output screen bindings.
|
||||
* src/core/window-bindings.h: tiny tweak to comment
|
||||
* src/core/keybindings.c: generate function prototypes using s-b.h;
|
||||
several handlers modified to use ints rather than ints cast into
|
||||
pointers, or renamed.
|
||||
* src/include/prefs.h: generate names of bindings using s-b.h;
|
||||
generate screen_handlers using s-b.h;
|
||||
arguments to bindings are ints and not ints cast to pointers;
|
||||
several handler functions renamed to consistent names.
|
||||
* src/core/prefs.c (meta_prefs_set_num_workspaces, init_bindings):
|
||||
generate screen_handlers using s-b.h;
|
||||
generate screen_string_bindings using s-b.h (and add check for
|
||||
null bindings in init_bindings to enable this simply).
|
||||
|
||||
2008-10-05 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* tools/ppa-magic.py: experimental tool for Launchpad upload
|
||||
|
||||
2008-10-05 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* metacity.doap: Havoc is an author; Thomas has an email address;
|
||||
add a ton of release information going back to the early days,
|
||||
although not right to the beginning.
|
||||
|
||||
2008-09-26 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* autogen.sh: not all versions of /bin/sh can handle this script,
|
||||
so specify one. Also update the error message because we don't
|
||||
use CVS these days.
|
||||
|
||||
2008-09-20 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* po/POTFILES.in: fix name of window-bindings.h
|
||||
|
||||
2008-09-20 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* po/POTFILES.in: added new files and re-sorted
|
||||
|
||||
2008-09-12 Vincent Untz <vuntz@gnome.org>
|
||||
|
||||
Install desktop files in both
|
||||
.../share/applications and .../share/gnome/wm-properties.
|
||||
Copied in from the 2.23.x branch. Closes #549479.
|
||||
|
||||
* src/metacity-wm.desktop.in: new file
|
||||
* src/.cvsignore: include the above
|
||||
* src/Makefile.am: install the above
|
||||
|
||||
2008-09-06 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
An attempt to keep all information about window bindings
|
||||
in the same place. Screen bindings to come.
|
||||
|
||||
* src/core/window-bindings.h: new file, list of all window bindings
|
||||
* src/include/prefs.h: drop all the existing window-binding macros
|
||||
|
||||
* src/core/schema-bindings.c (): output all the schema blocks that
|
||||
would appear in metacity.schema for these window bindings. This
|
||||
ought to become part of the build process, and hopefully will soon.
|
||||
When this works it will also close #469361.
|
||||
|
||||
* src/core/keybindings.c: generate handle_* prototypes using
|
||||
x-macros; populate window_handlers using x-macros; rename several
|
||||
functions to have consistent names; do_handle_move_to_workspace(),
|
||||
handle_move_to_workspace_flip(), and handle_move_to_workspace() all
|
||||
merged into handle_move_to_workspace.
|
||||
|
||||
* src/core/prefs.c: generate window_bindings and window_string_bindings
|
||||
using x-macros; (meta_prefs_set_compositing_manager) fix unrelated
|
||||
problem with use of GConf functions when GConf was disabled.
|
||||
|
||||
* src/core/core.c (meta_core_get_menu_accelerator): binding names
|
||||
given as literals since this is the only place in the code they
|
||||
now appear
|
||||
|
||||
|
||||
2008-09-03 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* src/metacity.desktop.in: removed invalid "Window Manager" group
|
||||
at request of Matthias Clasen.
|
||||
|
||||
2008-09-02 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
Desktop file moved, according to policy change. Closes #549479.
|
||||
|
||||
* src/metacity.desktop.in: Don't display the desktop file
|
||||
* src/Makefile.am: Desktop file goes in apps directory
|
||||
|
||||
2008-09-01 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* configure.in: Post-release bump to 2.25.2.
|
||||
|
||||
2008-09-01 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* NEWS: 2.25.1 release.
|
||||
|
@@ -1,7 +1,6 @@
|
||||
|
||||
SUBDIRS=src po doc
|
||||
|
||||
EXTRA_DIST = HACKING MAINTAINERS rationales.txt \
|
||||
intltool-extract.in intltool-merge.in intltool-update.in
|
||||
EXTRA_DIST = HACKING MAINTAINERS rationales.txt
|
||||
|
||||
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
||||
|
169
NEWS
169
NEWS
@@ -1,3 +1,172 @@
|
||||
2.25.144
|
||||
========
|
||||
|
||||
Thanks to Matthias Claesen, Matt Kraai, Elijah Newren, Owen Taylor, and Thomas
|
||||
Thurman for improvements in this version.
|
||||
|
||||
- Optimise window property lookup (Thomas) (#549886)
|
||||
- Fix slip in the above (Matt)
|
||||
- Several memory leaks fixed (Matthias) (#552303, #552973, #552307)
|
||||
- Fix longstanding crasher about colourmaps (Owen) (#568365)
|
||||
- Alt+middle/right buttons can be switched (Thomas) (#437910)
|
||||
- Support _NET_WM_MOVERESIZE_CANCEL (Elijah)
|
||||
- minor fix paving the way for a theme editor (Thomas)
|
||||
|
||||
Translations
|
||||
David Planella (ca), Jorge González (es), Mattias Põldaru (et), saudat
|
||||
mohammed (ha), Yuval Tanny\n (he), Gabor Kelemen (hu), Onye, Sylvester (ig),
|
||||
Changwoo Ryu (ko), Raivis Dejus (lv), Kjartan Maraas (nb), Daniel Nylander (sv),
|
||||
Fajuyitan, Sunday Ayo (yo), 甘露 (Gan Lu) (zh_CN)
|
||||
|
||||
2.25.89
|
||||
=======
|
||||
|
||||
Thanks to Yanko Kaneti, Frederic Peters, Thomas Thurman, and Colin Walters for
|
||||
improvements in this version.
|
||||
|
||||
- The maximisation key is a toggle. (Thomas) (#343824)
|
||||
- "Unmaximise" is now called "restore". (Thomas) (#343824)
|
||||
- New thread handling call for gconf (Frederic) (#565517)
|
||||
- Add screenshot commands back which had been removed (Yanko) (#565343)
|
||||
- move_to_corner_se keybinding fixed (Thomas)
|
||||
- Windows on other workspaces which attempt to present themselves
|
||||
are marked as needing attention (Colin) (#482354)
|
||||
- End the grab op when the user clicks the titlebar (Thomas) (#401028)
|
||||
|
||||
Translations
|
||||
Jorge González (es)
|
||||
|
||||
2.25.55
|
||||
=======
|
||||
|
||||
Thanks to Erwann Chenede for improvements in this version.
|
||||
|
||||
- Fix build on Solaris (Erwann) (#564123)
|
||||
|
||||
Translations
|
||||
Mattias Põldaru (et), Luca Ferretti (it)
|
||||
|
||||
2.25.34
|
||||
=======
|
||||
|
||||
Thanks to Matt Kraai for improvements in this version.
|
||||
|
||||
- Fixes to Thomas's earlier fixes (Matt) (#562939)
|
||||
|
||||
Translations
|
||||
None
|
||||
|
||||
2.25.21
|
||||
=======
|
||||
|
||||
Thanks to Thomas Thurman for improvements in this version.
|
||||
|
||||
- Fixes to allow building without compositor again (Thomas)
|
||||
- Fixes for -Wall problems (Thomas)
|
||||
- Various tool updates (Thomas)
|
||||
|
||||
Translations: none
|
||||
|
||||
|
||||
2.25.13
|
||||
=======
|
||||
|
||||
Thanks to Thomas Thurman for improvements in this version.
|
||||
|
||||
- Add casts to fix failure to build from source on 64bit hosts (Thomas) (#562106)
|
||||
- Added script to produce annoucements (Thomas)
|
||||
|
||||
Translations
|
||||
Jorge González (es)
|
||||
|
||||
2.25.8
|
||||
======
|
||||
|
||||
Thanks to Brian Cameron, Maxim Ermilov, Daniel Macks, Elijah Newren, Frederic
|
||||
Peters, Thomas Thurman, David Trowbridge, and Olav Vitters for improvements in
|
||||
this version.
|
||||
|
||||
- Reorder compiler flags (Daniel) (#562033)
|
||||
- Fix compositor switch (Daniel) (#560990)
|
||||
- Remove spurious warnings about operations on window "none" (Thomas)
|
||||
- Fix _POSIX_C_SOURCE which was breaking OS X builds (Thomas) (#561962)
|
||||
- -Werror -Wall and -ansi are now standard compile flags (Thomas)
|
||||
- Merge screen and window keybindings files; fix minor alt-tab bug
|
||||
in the process (Thomas) (#528337)
|
||||
- Support _NET_WM_FULLSCREEN_MONITORS (David)
|
||||
- Remove some deprecated calls (Thomas) (#560445)
|
||||
- Clean up #includes (Maxim) (#560449)
|
||||
- Update description of raise_on_click (Elijah)
|
||||
- First dialogue delegated to zenity (Thomas)
|
||||
- fix theme-parser typo (Olav)
|
||||
- double-quote variable names in messages (Thomas) (#558309)
|
||||
- fix accidental renaming of run_command_terminal (Thomas) (#557943)
|
||||
- some null checks; problems exposed by new GDM (Brian) (#558058)
|
||||
- ignore mouse button modifier if it's missing (Thomas) (Launchpad 258054, Launchpad 266929)
|
||||
- fix docbook markup (Frederic)
|
||||
|
||||
Translations
|
||||
Astur (ast), Jorge González (es), Thomas Thurman (la), Leonardo Ferreira
|
||||
Fontenelle (pt_BR), Daniel Nylander (sv)
|
||||
|
||||
2.25.5
|
||||
======
|
||||
|
||||
Thanks to Thomas Thurman for improvements in this version.
|
||||
|
||||
- Allow third-party apps to decide whether a window appears
|
||||
on all workspaces (Thomas) (#557536)
|
||||
- Fixed keybindings script (again) (Thomas)
|
||||
|
||||
Translations
|
||||
David Planella (ca), Robert Millan (ca@valencia)
|
||||
|
||||
2.25.3
|
||||
======
|
||||
|
||||
Brown paper bag release which fixes numerous build problems from last night's
|
||||
release of 2.25.2. Apologies.
|
||||
|
||||
Thanks to Murray Cumming, Thomas Thurman, and Götz Waschk for improvements
|
||||
in this version.
|
||||
|
||||
- Fix distcheck (Thomas) (#557356)
|
||||
- add libm reference (Götz) (#557357)
|
||||
- fix docbook tags (Murray) (#557337)
|
||||
|
||||
Translations
|
||||
Yavor Doganov (bg), David Planella (ca), Robert Millan (ca@valencia), Kenneth
|
||||
Nielsen (da), Hendrik Richter (de), Ivar Smolin (et), Claude Paroz (fr), Seán de
|
||||
Búrca (ga), Launchpad Translations Administrators (hr), Gabor Kelemen (hu),
|
||||
Thomas Thurman (la), Žygimantas Beručka (lt), Kjartan Maraas (nb), Duarte
|
||||
Loreto (pt), Djavan Fagundes (pt_BR), Mugurel Tudor (ro), Pavol Šimo (sk),
|
||||
Laurent Dhima (sq), Горан Ракић (sr), Theppitak Karoonboonyanan (th),
|
||||
Funda Wang (zh_CN)
|
||||
|
||||
2.25.2
|
||||
======
|
||||
|
||||
Thanks to Joe Marcus Clarke, Murray Cumming, Tomas Frydrych, William Lachance,
|
||||
Matthew Martin, Christian Persch, Thomas Thurman, and Vincent Untz for
|
||||
improvements in this version.
|
||||
|
||||
- Add handler for SIGTERM (Joe) (#553980)
|
||||
- Minimised windows are necessarily obscured (Matthew) (#528927)
|
||||
- Build fixes with the above (Christian, Tomas, Thomas) (#557335)
|
||||
(#557201) (#469361)
|
||||
- Changed keybindings to be in a single place (Thomas) (#469361)
|
||||
- Add new document about themes (Murray)
|
||||
- Remove obsolete support for fallback icons (Thomas)
|
||||
- Pass modified mouse events to panels (William) (#554428)
|
||||
- Change where desktop files should go (Vincent) (#549479)
|
||||
|
||||
Translations
|
||||
Yavor Doganov (bg), David Planella (ca), Kenneth Nielsen (da), Hendrik
|
||||
Richter (de), Ivar Smolin (et), Claude Paroz (fr), Seán de Búrca (ga), Launchpad
|
||||
Translations Administrators (hr), Gabor Kelemen (hu), Thomas Thurman (la),
|
||||
Žygimantas Beručka (lt), Kjartan Maraas (nb), Duarte Loreto (pt), Djavan
|
||||
Fagundes (pt_BR), Mugurel Tudor (ro), Pavol Šimo (sk), Laurent Dhima (sq),
|
||||
Горан Ракић (sr), Theppitak Karoonboonyanan (th), Funda Wang (zh_CN)
|
||||
2.25.1
|
||||
======
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
@@ -15,7 +15,8 @@ REQUIRED_AUTOMAKE_VERSION=1.10
|
||||
}
|
||||
|
||||
which gnome-autogen.sh || {
|
||||
echo "You need to install gnome-common from the GNOME CVS"
|
||||
echo "You need to install gnome-common from GNOME Subversion (or from"
|
||||
echo "your distribution's package manager)."
|
||||
exit 1
|
||||
}
|
||||
USE_GNOME2_MACROS=1 USE_COMMON_DOC_BUILD=yes . gnome-autogen.sh
|
||||
|
123
configure.in
123
configure.in
@@ -4,10 +4,13 @@ m4_define([metacity_major_version], [2])
|
||||
m4_define([metacity_minor_version], [25])
|
||||
# Fibonacci sequence for micro version numbering:
|
||||
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987
|
||||
m4_define([metacity_micro_version], [1])
|
||||
|
||||
m4_define([metacity_micro_version], [144])
|
||||
m4_define([mutter_version],[0.4])
|
||||
m4_define([metacity_version],
|
||||
[metacity_major_version.metacity_minor_version.metacity_micro_version])
|
||||
[metacity_major_version.metacity_minor_version.metacity_micro_version~mutter_version])
|
||||
|
||||
m4_define([metacity_clutter_plugin_api_version], [2])
|
||||
|
||||
AC_INIT([metacity], [metacity_version],
|
||||
[http://bugzilla.gnome.org/enter_bug.cgi?product=metacity])
|
||||
|
||||
@@ -17,6 +20,18 @@ AC_CONFIG_HEADERS(config.h)
|
||||
AM_INIT_AUTOMAKE
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
METACITY_MAJOR_VERSION=metacity_major_version
|
||||
METACITY_MINOR_VERSION=metacity_minor_version
|
||||
METACITY_MICRO_VERSION=metacity_micro_version
|
||||
METACITY_CLUTTER_PLUGIN_API_VERSION=metacity_clutter_plugin_api_version
|
||||
AC_SUBST(METACITY_MAJOR_VERSION)
|
||||
AC_SUBST(METACITY_MINOR_VERSION)
|
||||
AC_SUBST(METACITY_MICRO_VERSION)
|
||||
AC_SUBST(METACITY_CLUTTER_PLUGIN_API_VERSION)
|
||||
|
||||
MUTTER_PLUGIN_DIR="$libdir/$PACKAGE/plugins/clutter"
|
||||
AC_SUBST(MUTTER_PLUGIN_DIR)
|
||||
|
||||
# Honor aclocal flags
|
||||
AC_SUBST(ACLOCAL_AMFLAGS, "\${ACLOCAL_FLAGS}")
|
||||
|
||||
@@ -31,7 +46,7 @@ AC_HEADER_STDC
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
#### Integer sizes
|
||||
#### Integer sizes
|
||||
|
||||
AC_CHECK_SIZEOF(char)
|
||||
AC_CHECK_SIZEOF(short)
|
||||
@@ -143,6 +158,11 @@ AC_ARG_ENABLE(compositor,
|
||||
[disable metacity's compositing manager]),,
|
||||
enable_compositor=auto)
|
||||
|
||||
AC_ARG_WITH(clutter,
|
||||
AC_HELP_STRING([--with-clutter],
|
||||
[Use clutter for compositing]),,
|
||||
with_clutter=auto)
|
||||
|
||||
AC_ARG_ENABLE(xsync,
|
||||
AC_HELP_STRING([--disable-xsync],
|
||||
[disable metacity's use of the XSync extension]),,
|
||||
@@ -164,7 +184,7 @@ AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
## here we get the flags we'll actually use
|
||||
# GOptionEntry requires glib-2.6.0
|
||||
# GOptionEntry requires glib-2.6.0
|
||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.6.0)
|
||||
# gtk_window_set_icon_name requires gtk2+-2.60
|
||||
PKG_CHECK_MODULES(METACITY_MESSAGE, gtk+-2.0 >= 2.6.0)
|
||||
@@ -206,22 +226,13 @@ else
|
||||
echo "Building without libstartup-notification"
|
||||
fi
|
||||
|
||||
## init this, it gets set either in the compositor check below
|
||||
## init this, it gets set either in the compositor check below
|
||||
## or the render-specific check later
|
||||
have_xrender=no
|
||||
|
||||
XCOMPOSITE_VERSION=0.2
|
||||
AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION])
|
||||
if $PKG_CONFIG --atleast-version $XCOMPOSITE_VERSION xcomposite; then
|
||||
have_xcomposite=yes
|
||||
else
|
||||
have_xcomposite=no
|
||||
fi
|
||||
AC_MSG_RESULT($have_xcomposite)
|
||||
|
||||
if test x$enable_compositor = xyes; then
|
||||
have_xcomposite=yes
|
||||
echo "CompositeExt support forced on"
|
||||
elif test x$enable_compositor = xauto; then
|
||||
echo "Building compositing manager by default now."
|
||||
have_xcomposite=yes
|
||||
@@ -229,10 +240,31 @@ else
|
||||
have_xcomposite=no
|
||||
fi
|
||||
|
||||
if test x$with_clutter = xyes; then
|
||||
have_xcomposite=yes
|
||||
have_clutter=yes
|
||||
echo "CompositeExt support and Clutter forced on"
|
||||
elif test x$with_clutter = xauto; then
|
||||
have_clutter=no
|
||||
else
|
||||
have_clutter=no
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(WITH_CLUTTER, test "$have_clutter" = "yes")
|
||||
|
||||
if test x$have_xcomposite = xyes; then
|
||||
AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION])
|
||||
if $PKG_CONFIG --atleast-version $XCOMPOSITE_VERSION xcomposite; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_ERROR([no. Use --disable-compositor to disable.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x$have_xcomposite = xyes; then
|
||||
echo "Building with CompositeExt"
|
||||
METACITY_PC_MODULES="$METACITY_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender xdamage"
|
||||
AC_DEFINE(HAVE_COMPOSITE_EXTENSIONS, , [Building with compositing manager support])
|
||||
AC_DEFINE(HAVE_COMPOSITE_EXTENSIONS, 1, [Building with compositing manager support])
|
||||
echo "Building with compositing manager"
|
||||
|
||||
## force on render also
|
||||
have_xrender=yes
|
||||
@@ -270,6 +302,27 @@ if test x$have_xrender = xyes; then
|
||||
AC_DEFINE(HAVE_RENDER, , [Building with Render extension support])
|
||||
fi
|
||||
|
||||
CLUTTER_PACKAGE=clutter-0.9
|
||||
AC_SUBST(CLUTTER_PACKAGE)
|
||||
if test x$have_clutter = xyes; then
|
||||
METACITY_PC_MODULES="$METACITY_PC_MODULES $CLUTTER_PACKAGE "
|
||||
PKG_CHECK_MODULES(CLUTTER, $CLUTTER_PACKAGE)
|
||||
AC_DEFINE(WITH_CLUTTER, , [Building with Clutter compositor])
|
||||
|
||||
dnl Check for the clutter-glx-texture-pixmap header
|
||||
metacity_save_cppflags="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $CLUTTER_CFLAGS"
|
||||
AC_CHECK_HEADER([clutter/glx/clutter-glx-texture-pixmap.h],
|
||||
[have_glx_texture_pixmap=yes],
|
||||
[have_glx_texture_pixmap=no])
|
||||
CPPFLAGS="$metacity_save_cppflags"
|
||||
|
||||
if test x$have_glx_texture_pixmap = xyes; then
|
||||
AC_DEFINE(HAVE_GLX_TEXTURE_PIXMAP, ,
|
||||
[Is ClutterGLXTexturePixmap available?])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([Xcursor])
|
||||
if $PKG_CONFIG xcursor; then
|
||||
have_xcursor=yes
|
||||
@@ -281,7 +334,7 @@ if $PKG_CONFIG xcursor; then
|
||||
if test x$have_xcursor = xyes; then
|
||||
echo "Building with Xcursor"
|
||||
METACITY_PC_MODULES="$METACITY_PC_MODULES xcursor"
|
||||
AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support])
|
||||
AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support])
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(METACITY, $METACITY_PC_MODULES)
|
||||
@@ -318,7 +371,7 @@ if test "${try_xinerama}" != no; then
|
||||
AC_DEFINE(HAVE_XINERAMA, , [Have some version of Xinerama]),
|
||||
use_solaris_xinerama=no,
|
||||
[#include <X11/Xlib.h>])
|
||||
fi
|
||||
fi
|
||||
AC_MSG_CHECKING(for Xinerama support on Solaris)
|
||||
AC_MSG_RESULT($use_solaris_xinerama);
|
||||
;;
|
||||
@@ -327,12 +380,12 @@ if test "${try_xinerama}" != no; then
|
||||
use_xfree_xinerama=yes
|
||||
AC_CHECK_LIB(Xinerama, XineramaQueryExtension,
|
||||
[AC_CHECK_HEADER(X11/extensions/Xinerama.h,
|
||||
X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
|
||||
X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
|
||||
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
|
||||
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
|
||||
fi
|
||||
AC_DEFINE(HAVE_XFREE_XINERAMA, , [Have XFree86-style Xinerama])
|
||||
AC_DEFINE(HAVE_XINERAMA,, [Have some version of Xinerama]),
|
||||
AC_DEFINE(HAVE_XINERAMA,, [Have some version of Xinerama]),
|
||||
use_xfree_xinerama=no,
|
||||
[#include <X11/Xlib.h>])],
|
||||
use_xfree_xinerama=no, -lXext $ALL_X_LIBS)
|
||||
@@ -413,7 +466,7 @@ if test "x$found_xsync" = "xyes"; then
|
||||
AC_DEFINE(HAVE_XSYNC, , [Have the Xsync extension library])
|
||||
fi
|
||||
|
||||
METACITY_LIBS="$METACITY_LIBS $XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||
METACITY_LIBS="$METACITY_LIBS $XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
|
||||
METACITY_MESSAGE_LIBS="$METACITY_MESSAGE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||
METACITY_WINDOW_DEMO_LIBS="$METACITY_WINDOW_DEMO_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||
METACITY_PROPS_LIBS="$METACITY_PROPS_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||
@@ -424,7 +477,7 @@ case "$METACITY_LIBS" in
|
||||
found_sm=yes
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_LIB(SM, SmcSaveYourselfDone,
|
||||
AC_CHECK_LIB(SM, SmcSaveYourselfDone,
|
||||
[AC_CHECK_HEADERS(X11/SM/SMlib.h,
|
||||
METACITY_LIBS="-lSM -lICE $METACITY_LIBS" found_sm=yes)],
|
||||
, $METACITY_LIBS)
|
||||
@@ -446,7 +499,7 @@ if test "$found_sm" = "yes"; then
|
||||
AC_DEFINE(HAVE_SM, , [Building with SM support])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "yes")
|
||||
AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "yes")
|
||||
|
||||
HOST_ALIAS=$host_alias
|
||||
AC_SUBST(HOST_ALIAS)
|
||||
@@ -459,7 +512,7 @@ fi
|
||||
|
||||
AC_SUBST(GDK_PIXBUF_CSOURCE)
|
||||
|
||||
if test x$enable_gconf = xyes; then
|
||||
if test x$enable_gconf = xyes; then
|
||||
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
|
||||
if test x"$GCONFTOOL" = xno; then
|
||||
AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
|
||||
@@ -471,21 +524,38 @@ else
|
||||
GCONF_SCHEMAS_INSTALL_FALSE=
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(ZENITY, zenity, no)
|
||||
if test x"$ZENITY" = xno; then
|
||||
AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug enable debugging],,
|
||||
enable_debug=no)
|
||||
if test "x$enable_debug" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -g -O -Wall"
|
||||
CFLAGS="$CFLAGS -g -O"
|
||||
fi
|
||||
|
||||
# Warnings are there for a reason
|
||||
if test "x$GCC" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -Wall -Werror -ansi"
|
||||
fi
|
||||
|
||||
# Use gnome-doc-utils:
|
||||
GNOME_DOC_INIT([0.8.0])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
doc/Makefile
|
||||
doc/creating_themes/Makefile
|
||||
doc/man/Makefile
|
||||
src/Makefile
|
||||
src/wm-tester/Makefile
|
||||
src/libmetacity-private.pc
|
||||
src/metacity-plugins.pc
|
||||
src/tools/Makefile
|
||||
src/themes/Makefile
|
||||
src/compositor/mutter/plugins/Makefile
|
||||
po/Makefile.in
|
||||
])
|
||||
|
||||
@@ -525,6 +595,7 @@ metacity-$VERSION:
|
||||
Xsync: ${found_xsync}
|
||||
Render: ${have_xrender}
|
||||
Xcursor: ${have_xcursor}
|
||||
Clutter: ${have_clutter}
|
||||
"
|
||||
|
||||
METACITY_MINOR_VERSION=metacity_minor_version
|
||||
|
@@ -1,4 +1,4 @@
|
||||
SUBDIRS = man
|
||||
SUBDIRS = man creating_themes
|
||||
|
||||
EXTRA_DIST=theme-format.txt metacity-theme.dtd dialogs.txt code-overview.txt \
|
||||
how-to-get-focus-right.txt
|
||||
|
286
doc/creating_themes/C/creating-metacity-themes.xml
Normal file
286
doc/creating_themes/C/creating-metacity-themes.xml
Normal file
@@ -0,0 +1,286 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://docbook.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
]>
|
||||
|
||||
<book id="index">
|
||||
|
||||
<bookinfo>
|
||||
|
||||
<title>Understanding Metacity Themes</title>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Thomas</firstname>
|
||||
<surname>Thurman</surname>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<abstract>
|
||||
|
||||
<para>
|
||||
We very much appreciate any reports of inaccuracies or other errors in
|
||||
this document. Contributions are also most welcome. Post your
|
||||
suggestions, critiques or addenda to the <ulink
|
||||
url="mailto:tthurman@gnome.org">team</ulink>.</para>
|
||||
|
||||
</abstract>
|
||||
|
||||
<copyright>
|
||||
<year>2008</year>
|
||||
<holder>Thomas Thurman</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.2
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
You may obtain a copy of the GNU Free Documentation License from the Free Software Foundation by visiting their Web site or by writing to: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
</para>
|
||||
</legalnotice>
|
||||
|
||||
</bookinfo>
|
||||
|
||||
<chapter id="sec-introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>This is an article about how to theme Metacity. It is a work in progress, and I have had to dig deeply to find some answers; I may well have made mistakes and I welcome corrections and suggestions.</para>
|
||||
<para>GNOME lets you theme a bunch of different things, but we're only talking about <literal>window border</literal> themes here, which some people call Metacity themes; <ulink url="http://en.wikipedia.org/wiki/Metacity#Themes">Wikipedia begins a sentence</ulink> with "Despite the incomplete state of Metacity theme development documentation", and though there <emphasis>is</emphasis> <ulink url="http://svn.gnome.org/viewvc/metacity/trunk/doc/theme-format.txt?view=markup">documentation in the source</ulink>, apparently not many people find it, and it's written more for programmers than theme designers. Glynn Foster also wrote <ulink url="http://developer.gnome.org/doc/tutorials/metacity/metacity-themes.html">a very good introduction to Metacity themes</ulink> (<ulink url="http://home.arcor.de/rybaczyk/documents/tutorials/metacity/metacity-themes.de.html">[de]</ulink>) six years ago, but things have changed a little since then. <ulink url="http://lists.freedesktop.org/archives/compiz/2006-September/000445.html">Metacity themes can also be used by Compiz</ulink>, and perhaps by other window managers for all I know.</para>
|
||||
|
||||
<para>So, a Metacity theme is a set of instructions about how to "decorate" (draw the borders around) a window. Presumably you don't want to style all windows identically, so the format lets you specify details for different kinds of window:</para>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>state:</term><listitem><para>Every window must be in exactly one of these states: <literal>normal</literal>, <literal>dialog</literal>, <literal>modal dialog</literal> (i.e. a dialogue which means you can't interact with the rest of the program while it's up), <literal>menu</literal> (torn off from the main application, not that people do that much these days), <literal>utility</literal> (that is, palettes and toolboxes and things), and <literal>border</literal>. X also allows a window to explicitly ask to be undecorated, but of course we don't provide for those in a list of decoration instructions.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>focused</term><listitem><para>Every window is either the active window (which X people call "focused"), or it isn't.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>maximized</term><listitem><para>Every window is either (fully) maximised (horizontal and vertical only don't count), or it isn't.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>shaded</term><listitem><para>Every window is either rolled up to show just its titlebar (which techies call "shaded" for some reason I can't fathom), or it isn't.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem><para><emphasis>If a window is not fully maximised and not shaded,</emphasis> it either allows horizontal resizing, or it doesn't.</para></listitem>
|
||||
<listitem><para><emphasis>If a window is not fully maximised and not shaded,</emphasis> it either allows vertical resizing, or it doesn't.</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
<title>What's in the file</title>
|
||||
|
||||
<para>The files must be called either</para>
|
||||
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem><para>~/.themes/<varname>N</varname>/metacity-1/metacity-theme-<varname>V</varname>.xml
|
||||
for a theme used only by you, or</para></listitem>
|
||||
<listitem><para>/usr/share/themes/<varname>N</varname>/metacity-1/metacity-theme-<varname>V</varname>.xml
|
||||
for a theme installed for all users.</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>where <varname>N</varname> is the name of the theme and <varname>V</varname> is the version of the format. Version 2, <ulink url="http://svn.gnome.org/viewvc/metacity?view=revision&revision=2973">introduced in October 2006</ulink>, adds a few extra features, but it's rarely used. Version 1 is the original format. The formats are fixed once they're stable for both backwards and forwards compatibility; <ulink url="http://bugzilla.gnome.org/show_bug.cgi?id=482165">new features</ulink> can't be added without introducing a new version number, which is why improvements come out rarely and in large clumps. <literal>metacity-1</literal> in the names is a fossil and doesn't mean version 1 of anything.</para>
|
||||
|
||||
<para>The metacity-theme-V.xml files are <ulink url="http://blogs.gnome.org/tthurman/2008/02/14/gmarkup/">GMarkup files</ulink>, which are very similar to XML. For now, you actually have to write these in a text editor or something; you can either start with a blank page, or modify a theme someone else has made. (I am thinking of writing a general theme editor program, but that'll have to wait until I've reduced Metacity's open bug queue a little.) If you want to see a fully-fledged one, you can look at <ulink url="http://svn.gnome.org/viewvc/metacity/trunk/src/themes/Atlanta/metacity-theme-1.xml?view=markup">the current version of "Atlanta"</ulink>, one of the simplest themes, but even that is quite complicated-looking at first.</para>
|
||||
<para>So, let's talk about what actually goes inside the files. As in any XML file, <!-<!-- x -->- … <!-- x -->> are comments. At its most basic, it would go:</para>
|
||||
|
||||
<para>
|
||||
<programlisting>
|
||||
<metacity_theme>
|
||||
<!-<!-- x -->- Helper stuff: -<!-- x -->->
|
||||
<info …> <!-<!-- x -->- to be explained -<!-- x -->->
|
||||
<constant …> <!-<!-- x -->- maybe; to be explained -<!-- x -->->
|
||||
|
||||
<draw_ops …> <!-<!-- x -->- maybe; to be explained -<!-- x -->->
|
||||
|
||||
<!-<!-- x -->- Things we build the top level onto: -<!-- x -->->
|
||||
<frame_geometry …> <!-<!-- x -->- to be explained -<!-- x -->->
|
||||
|
||||
<frame_style …> <!-<!-- x -->- to be explained -<!-- x -->->
|
||||
<frame_style_set …> <!-<!-- x -->- to be explained -<!-- x -->->
|
||||
|
||||
<!-<!-- x -->- And the top level: -<!-- x -->->
|
||||
|
||||
<window type="normal" style_set="…" />
|
||||
<window type="dialog" style_set="…" />
|
||||
<window type="modal_dialog" style_set="…" />
|
||||
|
||||
<window type="menu" style_set="…" />
|
||||
<window type="utility" style_set="…" />
|
||||
<window type="border" style_set="…" />
|
||||
|
||||
</metacity_theme>
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
<title>Matching windows</title>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>window</term><listitem><para>You see that at the top level we have a list of <window> tags, one for each window state we discussed above. The style_set argument of each of these gives the name of a frame_style_set.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>frame_style_set:</term><listitem><para>tells Metacity how to draw windows according to whether they're focused or not, maximised or not, shaded or not, and allowing resizing vertically, horizontally, both, or neither. It looks like this:</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<programlisting>
|
||||
<frame_style_set>
|
||||
<frame focus="F" state="S" resize="R" style="N"/>
|
||||
<frame… />
|
||||
|
||||
…
|
||||
</frame_style_set>
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>where:</para>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>F</term><listitem><para>is yes for focused, no for unfocused.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>S</term><listitem><para>combines the shaded and maximized flags: normal, maximized, shaded, or maximized_and_shaded.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>R</term><listitem><para>represents resize permissions that the window gives us: none, vertical, horizontal, or both. Frame settings for maximised windows, which can't be resized, don't have this attribute.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<varname>N</varname> is the name of a <literal>frame_style</literal> to apply to a window which has these attributes.</para>
|
||||
|
||||
<para>A <literal>frame_style_set</literal> tag may also have a "parent" tag, which should be the name of another <literal>frame_style_set</literal>. This means that if Metacity wants to know about a kind of window which that <literal>frame_style_set</literal> doesn't describe, it should look in the parent. Most of the more complicated tags in Metacity theme files also have a "parent" attribute which work the same way. This is particularly useful because, taken together, all the <literal>frame_style_set</literal>s in a theme file must be capable of matching every possible kind of window; if a window turns up that they can't match, there will be an error at runtime.</para>
|
||||
|
||||
<para>Let's recap what we've seen so far. The combination of a <literal>window</literal>, which matches a window's state (normal, dialog, and so forth), with an entry in the corresponding <literal>frame_style_set</literal>, which matches its focus, shadedness, maximisedness, and resize permissions where relevant, will allow you to make a list of rules to match any window against. The next piece of this puzzle lets you specify what Metacity should do with such windows once it's matched them.</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
<title>Actually drawing stuff</title>
|
||||
|
||||
<para><literal>frame_style:</literal> This is probably the most complicated part of the whole system. A <literal>frame_style</literal> a series of <emphasis><literal>piece</literal></emphasis>s and <emphasis><literal>button</literal></emphasis>s. It looks like this:</para>
|
||||
|
||||
<para>
|
||||
<programlisting>
|
||||
<frame_style name="…" geometry="G">
|
||||
<piece position="P">
|
||||
<draw_ops>
|
||||
</draw_ops>
|
||||
</piece>
|
||||
…
|
||||
<button function="F" state="S" draw_ops="D"/>
|
||||
|
||||
<draw_ops>
|
||||
</draw_ops>
|
||||
</button>
|
||||
…
|
||||
</frame_style>
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>The <literal>pieces</literal> are pieces of the window frame. When Metacity draws a window frame, it renders its various pieces always in the same order. The bolded parts are all the possible values of P:</para>
|
||||
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem><para>the <literal>entire_background</literal>, covering the whole frame</para></listitem>
|
||||
|
||||
<listitem><para>the <literal>titlebar</literal>, covering the entire background of the titlebar</para></listitem>
|
||||
<listitem><para>the <literal>titlebar_middle</literal>, the part of the titlebar that doesn't touch its edges</para></listitem>
|
||||
<listitem><para>the <literal>left_titlebar_edge</literal>, <literal>right_titlebar_edge</literal>, <literal>top_titlebar_edge</literal>, and <literal>bottom_titlebar_edge</literal></para></listitem>
|
||||
|
||||
<listitem><para>the <literal>title</literal>, just exactly that area which is covered by the text on the titlebar</para></listitem>
|
||||
<listitem><para>the <literal>left_edge</literal>, <literal>right_edge</literal>, and <literal>bottom_edge</literal> of the frame (yes, there is no top_edge: it's identical to top_titlebar_edge, isn't it?)</para></listitem>
|
||||
<listitem><para>the <literal>overlay</literal>, which covers everything– the same as entire_background, but done last instead of first.</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para><emphasis>What</emphasis> Metacity draws in these pieces is decided by the theme. If a <literal>frame_style</literal> or its parents don't specify a particular piece, nothing will be drawn for that piece. You have two ways to specify what to draw: one is that the <literal>piece</literal> tag can have a <literal>draw_ops</literal> tag inside it which lists a sequence of drawing operations in Metacity's custom format. <ulink url="http://bugzilla.gnome.org/show_bug.cgi?id=107012">You might ask why we don't use SVG</ulink>; one answer is that SVG support wasn't very strong when this format was designed, and another answer is that these days you can use SVG all you like; just include it as an image and Metacity will know what to do.</para>
|
||||
|
||||
<para>An alternative to including a draw_ops tag inside a piece tag is to add a draw_ops attribute to the piece tag. Then you can add a draw_ops tag at top level (inside the metacity_theme tag) with a name attribute, and Metacity will use that. This is useful if you use similar draw_ops over and over.</para>
|
||||
<para>I'm not going to document draw_ops at present, because this is already very long. I will write it up later and link it from here.</para>
|
||||
<para>The <literal>button</literal> tag tells Metacity how, but not where, to draw buttons. Buttons are drawn after all the pieces are finished, and the way to draw them is also given using draw_ops. You ought to provide buttons for all the possible kinds of button; if you don't give one it won't be drawn, which is unfortunate for the user who wants to use it:</para>
|
||||
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>left_left_background</literal>, <literal>left_middle_background</literal>, and <literal>left_right_background</literal> don't represent buttons as such, but the background behind them, assuming there can be at most three buttons on the left. These days there can be more, so the extra ones also use left_middle_background.</para></listitem>
|
||||
|
||||
<listitem><para><literal>right_left_background</literal>, <literal>right_middle_background</literal>, and <literal>right_right_background</literal> similarly.</para></listitem>
|
||||
<listitem><para><literal>close</literal>, <literal>minimize</literal>, <literal>maximize</literal> are the obvious original three buttons.</para></listitem>
|
||||
<listitem><para><literal>menu</literal> is the menu button you can click to get a list of actions you can perform on the window.</para></listitem>
|
||||
|
||||
<listitem><para><literal>shade</literal>, <literal>above</literal>, <literal>stick</literal> are similar to the original buttons but only allowed in version 2</para></listitem>
|
||||
<listitem><para><literal>unshade</literal>, <literal>unabove</literal>, <literal>unstick</literal> are the toggled versions of these buttons. Again, version 2 only.</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>The reason there are toggled versions of shade, above, and stick, and not maximize, is that by the time you get this far you've probably already decided whether you're drawing a maximised window. So if you <emphasis>are</emphasis> drawing a maximised window, you can make the button called "maximize" look how you want the restore button to be; otherwise, make it look like you want the maximise button to be.</para>
|
||||
<para>For each button tag you should also set a "state" attribute; this time the state is either <literal>normal</literal> (the way you see it most of the time), <literal>pressed</literal>, or <literal>prelight</literal> (this makes the buttons subtly light up when you hover over them). You only really need "normal", but the others are good to have too.</para>
|
||||
|
||||
<para>The "geometry" attribute of a <literal>frame_style</literal> tag is the name of a…</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
<title>Geometry</title>
|
||||
|
||||
<para>The <literal>geometry</literal> tag defines the sizes of things around the window. It is important, but not easy to explain, and again this file has gone on too long. I'll write it up later.</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
<title>Other things which lie around a file</title>
|
||||
|
||||
<para>The most important other thing in a theme file is the metadata held in the <literal>info</literal> tag. This contains a set of tags each of which contains some text explaining something about the theme itself, in a sort of <ulink url="http://en.wikipedia.org/wiki/Dublin_Core">Dublin Core</ulink> sort of way. (Next time around, we should probably use the actual Dublin Core.) The tags are <literal>name</literal>, <literal>author</literal>, <literal>copyright</literal>, <literal>date</literal>, and <literal>description</literal>.</para>
|
||||
|
||||
<para>Version 1 of the format had a <literal>menu_icon</literal> tag at top level, which let themes specify the icons beside options in the menu you get from the menu icon. This has become redundant; the icons are taken from the icon theme! The tag can still be used in all formats, but does nothing and is deprecated.</para>
|
||||
<para>Version 2 of the format has a <literal>fallback</literal> tag at top level, which let the theme specify what icon a window should be considered to have if it doesn't provide an icon of its own. This should also be taken from the icon theme, <ulink url="http://bugzilla.gnome.org/show_bug.cgi?id=524343">if anyone fancies fixing it</ulink>, and the tag should also then be deprecated. It shouldn't be hard.</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
<title>When you're working on a theme</title>
|
||||
|
||||
<para>When you're editing a theme, you can view it without using it on the whole desktop using
|
||||
<command>metacity-theme-viewer YourThemeName</command></para>
|
||||
<para>and view it on the whole desktop using
|
||||
<command>gconftool -<!-- x -->-type=string -<!-- x -->-set /apps/metacity/general/theme YourThemeName</command></para>
|
||||
|
||||
<para>Whenever you change the selected theme in GConf, Metacity will load the newly-chosen theme. This is how control-center does it. But when you change a theme, as you're working on it, you might want to ask Metacity to reload the theme which is currently used on the whole desktop to reflect your changes. You can do this using the little-known <command>metacity-message</command> program, with the command <literal>metacity-message reload-theme</literal>. This works by sending the ClientMessage <literal>_METACITY_RELOAD_THEME_MESSAGE</literal> to the root window, in case you're interested.</para>
|
||||
|
||||
<para>Once you're done with your theme, consider submitting it to <ulink url="http://art.gnome.org/themes/metacity/">the art.gnome.org site</ulink>, or <ulink url="http://www.gnome-look.org/index.php?xcontentmode=101">the gnome-look site</ulink>.</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter>
|
||||
<title>The future</title>
|
||||
|
||||
<para>Please feel free to link to this so people don't have to keep asking the basic questions and can start asking the deeper ones. One of the important deeper ones is: where should we go in the future? Since this format is becoming something of a de facto standard between window managers, should we set up some kind of freedesktop.org standards discussion? Would it be useful to spin off Metacity's theme parsing code into a separate, LGPL-licensed library so that other applications could use it more easily?</para>
|
||||
<para>What would a version 3 of this format look like? Could we simplify the window / frame_style_set system? (I can imagine abolishing both, and being able to write <literal><frame_style for="normal+unfocused+maximized">…</literal> and having Metacity assume it applied to all resize permissions and shadednesses.) Maybe we should try to do everything with SVG we can? Getting more wild and handwavey, is it worth keeping XML-like? Maybe if other window managers were dealing with the files, .ini-style files would be more universally useful? Or perhaps not. And then of course we need a decent graphical editor for it. I have a few ideas, but if anyone fancies jumping in...</para>
|
||||
</chapter>
|
||||
|
||||
</book>
|
||||
|
||||
|
24
doc/creating_themes/Makefile.am
Normal file
24
doc/creating_themes/Makefile.am
Normal file
@@ -0,0 +1,24 @@
|
||||
### This part of Makefile.am can be customized by you.
|
||||
|
||||
# gnome-doc-utils standard variables:
|
||||
include $(top_srcdir)/gnome-doc-utils.make
|
||||
dist-hook: doc-dist-hook
|
||||
|
||||
# The name of the directory in /usr/share/gnome/help/,
|
||||
# and the name of the main .xml file:
|
||||
DOC_MODULE = creating-metacity-themes
|
||||
|
||||
# The names of any files included via entity declarations.
|
||||
DOC_ENTITIES =
|
||||
|
||||
# The names of any files included by xincluded (preferred):
|
||||
DOC_INCLUDES =
|
||||
|
||||
# The names of any pictures:
|
||||
DOC_FIGURES =
|
||||
|
||||
# The names of any locales for which documentation translations exist:
|
||||
DOC_LINGUAS =
|
||||
|
||||
|
||||
|
653
metacity.doap
653
metacity.doap
@@ -1,3 +1,4 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<Project
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
|
||||
@@ -16,7 +17,7 @@
|
||||
<created>2001-05-30</created>
|
||||
|
||||
<shortdesc xml:lang="en">
|
||||
A simple GTK+ window manager that tries not to get in your way.
|
||||
Metacity is a simple compositing window manager that integrates nicely with GNOME 2.
|
||||
</shortdesc>
|
||||
<description xml:lang="en">
|
||||
A window manager for GNOME, with a focus on simplicity and usability
|
||||
@@ -41,16 +42,16 @@ Many window managers are like Marshmallow Froot Loops; Metacity is like Cheerios
|
||||
|
||||
<repository>
|
||||
<SVNRepository>
|
||||
<location rdf:resource="http://svn.gnome.org/svn/metacity/trunk" />
|
||||
<location rdf:resource="http://svn.gnome.org/svn/metacity" />
|
||||
<browse rdf:resource="http://svn.gnome.org/viewvc/metacity/" />
|
||||
</SVNRepository>
|
||||
</repository>
|
||||
|
||||
<maintainer>
|
||||
<author>
|
||||
<foaf:Person>
|
||||
<foaf:name>Havoc Pennington</foaf:name>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
</author>
|
||||
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
@@ -61,11 +62,649 @@ Many window managers are like Marshmallow Froot Loops; Metacity is like Cheerios
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Thomas Thurman</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:tthurman@gnome.org"/>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
<!-- Releases would go here, but there have been dozens.
|
||||
Maybe another time.
|
||||
-->
|
||||
<release><Version>
|
||||
<name>2.25.1 release</name>
|
||||
<created>2008-09-01</created>
|
||||
<branch></branch>
|
||||
<revision>2.25.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.25/2.25.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.25/2.25.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.25.0 release</name>
|
||||
<created>2008-08-18</created>
|
||||
<branch></branch>
|
||||
<revision>2.25.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.25/2.25.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.25/2.25.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.89 release</name>
|
||||
<created>2008-08-04</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.89</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.89.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.89.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.55 release</name>
|
||||
<created>2008-07-14</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.55</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.55.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.55.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.34 release</name>
|
||||
<created>2008-06-16</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.34</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.34.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.34.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.34 release</name>
|
||||
<created>2008-06-16</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.34</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.34.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.34.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.34 release</name>
|
||||
<created>2008-06-02</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.34</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.34.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.34.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.21 release</name>
|
||||
<created>2008-05-26</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.21</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.21.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.21.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.13 release</name>
|
||||
<created>2008-04-27</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.13</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.13.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.13.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.8 release</name>
|
||||
<created>2008-04-22</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.8</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.8.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.8.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.5 release</name>
|
||||
<created>2008-04-06</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.5</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.5.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.5.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.3 release</name>
|
||||
<created>2008-03-21</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.3</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.3.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.3.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.2 release</name>
|
||||
<created>2008-03-07</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.2</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.2.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.2.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.1 release</name>
|
||||
<created>2008-03-06</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.23.0 release</name>
|
||||
<created>2008-02-26</created>
|
||||
<branch></branch>
|
||||
<revision>2.23.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.23/2.23.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.21.13 release</name>
|
||||
<created>2008-02-11</created>
|
||||
<branch></branch>
|
||||
<revision>2.21.13</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.13.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.13.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.21.8 release</name>
|
||||
<created>2008-02-03</created>
|
||||
<branch></branch>
|
||||
<revision>2.21.8</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.8.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.8.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.21.5 release</name>
|
||||
<created>2007-12-19</created>
|
||||
<branch></branch>
|
||||
<revision>2.21.5</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.5.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.5.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.21.3 release</name>
|
||||
<created>2007-12-14</created>
|
||||
<branch></branch>
|
||||
<revision>2.21.3</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.3.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.3.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.21.2 release</name>
|
||||
<created>2007-11-17</created>
|
||||
<branch></branch>
|
||||
<revision>2.21.2</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.2.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.2.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.21.1 release</name>
|
||||
<created>2007-11-11</created>
|
||||
<branch></branch>
|
||||
<revision>2.21.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.21/2.21.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.20.0 release</name>
|
||||
<created>2007-09-15</created>
|
||||
<branch></branch>
|
||||
<revision>2.20.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.20/2.20.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.20/2.20.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.19.55 release</name>
|
||||
<created>2007-08-07</created>
|
||||
<branch></branch>
|
||||
<revision>2.19.55</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.55.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.55.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.19.34 release</name>
|
||||
<created>2007-07-22</created>
|
||||
<branch></branch>
|
||||
<revision>2.19.34</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.34.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.34.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.19.21 release</name>
|
||||
<created>2007-06-18</created>
|
||||
<branch></branch>
|
||||
<revision>2.19.21</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.21.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.21.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.19.13 release</name>
|
||||
<created>2007-06-10</created>
|
||||
<branch></branch>
|
||||
<revision>2.19.13</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.13.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.13.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.19.8 release</name>
|
||||
<created>2007-06-04</created>
|
||||
<branch></branch>
|
||||
<revision>2.19.8</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.8.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.8.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.19.5 release</name>
|
||||
<created>2007-04-23</created>
|
||||
<branch></branch>
|
||||
<revision>2.19.5</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.5.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.5.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.19.3 release</name>
|
||||
<created>2007-04-16</created>
|
||||
<branch></branch>
|
||||
<revision>2.19.3</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.3.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.3.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.19.2 release</name>
|
||||
<created>2007-04-09</created>
|
||||
<branch></branch>
|
||||
<revision>2.19.2</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.2.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.2.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.19.1 release</name>
|
||||
<created>2007-04-04</created>
|
||||
<branch></branch>
|
||||
<revision>2.19.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.19/2.19.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.17.3 release</name>
|
||||
<created>2006-12-10</created>
|
||||
<branch></branch>
|
||||
<revision>2.17.3</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.17/2.17.3.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.17/2.17.3.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.17.2 release</name>
|
||||
<created>2006-11-06</created>
|
||||
<branch></branch>
|
||||
<revision>2.17.2</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.17/2.17.2.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.17/2.17.2.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.17.1 release</name>
|
||||
<created>2006-10-16</created>
|
||||
<branch></branch>
|
||||
<revision>2.17.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.17/2.17.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.17/2.17.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.17.0 release</name>
|
||||
<created>2006-10-07</created>
|
||||
<branch></branch>
|
||||
<revision>2.17.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.17/2.17.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.17/2.17.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.16.2 release</name>
|
||||
<created>2006-09-18</created>
|
||||
<branch></branch>
|
||||
<revision>2.16.2</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.16/2.16.2.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.16/2.16.2.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.16.1 release</name>
|
||||
<created>2006-09-11</created>
|
||||
<branch></branch>
|
||||
<revision>2.16.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.16/2.16.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.16/2.16.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.16.0 release</name>
|
||||
<created>2006-09-04</created>
|
||||
<branch></branch>
|
||||
<revision>2.16.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.16/2.16.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.16/2.16.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.15.34 release</name>
|
||||
<created>2006-08-21</created>
|
||||
<branch></branch>
|
||||
<revision>2.15.34</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.34.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.34.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.15.21 release</name>
|
||||
<created>2006-08-07</created>
|
||||
<branch></branch>
|
||||
<revision>2.15.21</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.21.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.21.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.15.13 release</name>
|
||||
<created>2006-07-24</created>
|
||||
<branch></branch>
|
||||
<revision>2.15.13</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.13.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.13.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.15.8 release</name>
|
||||
<created>2006-07-10</created>
|
||||
<branch></branch>
|
||||
<revision>2.15.8</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.8.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.8.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.15.5 release</name>
|
||||
<created>2006-06-12</created>
|
||||
<branch></branch>
|
||||
<revision>2.15.5</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.5.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.5.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.15.3 release</name>
|
||||
<created>2006-05-15</created>
|
||||
<branch></branch>
|
||||
<revision>2.15.3</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.3.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.3.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.15.2 release</name>
|
||||
<created>2006-04-25</created>
|
||||
<branch></branch>
|
||||
<revision>2.15.2</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.2.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.2.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.15.1 release</name>
|
||||
<created>2006-04-25</created>
|
||||
<branch></branch>
|
||||
<revision>2.15.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.15.0 release</name>
|
||||
<created>2006-04-24</created>
|
||||
<branch></branch>
|
||||
<revision>2.15.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.15/2.15.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.89 release</name>
|
||||
<created>2006-02-13</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.89</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.89.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.89.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.55 release</name>
|
||||
<created>2006-01-30</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.55</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.55.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.55.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.34 release</name>
|
||||
<created>2006-01-20</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.34</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.34.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.34.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.21 release</name>
|
||||
<created>2006-01-16</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.21</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.21.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.21.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.13 release</name>
|
||||
<created>2006-01-10</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.13</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.13.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.13.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.8 release</name>
|
||||
<created>2006-01-02</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.8</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.8.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.8.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.5 release</name>
|
||||
<created>2005-12-12</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.5</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.5.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.5.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.3 release</name>
|
||||
<created>2005-11-22</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.3</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.3.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.3.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.2 release</name>
|
||||
<created>2005-11-19</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.2</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.2.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.2.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.1 release</name>
|
||||
<created>2005-11-14</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.13.0 release</name>
|
||||
<created>2005-10-24</created>
|
||||
<branch></branch>
|
||||
<revision>2.13.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.13/2.13.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.12.1 release</name>
|
||||
<created>2005-10-03</created>
|
||||
<branch></branch>
|
||||
<revision>2.12.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.12/2.12.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.12/2.12.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.12.0 release</name>
|
||||
<created>2005-09-05</created>
|
||||
<branch></branch>
|
||||
<revision>2.12.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.12/2.12.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.12/2.12.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.11.3 release</name>
|
||||
<created>2005-08-22</created>
|
||||
<branch></branch>
|
||||
<revision>2.11.3</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.11/2.11.3.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.11/2.11.3.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.11.2 release</name>
|
||||
<created>2005-08-08</created>
|
||||
<branch></branch>
|
||||
<revision>2.11.2</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.11/2.11.2.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.11/2.11.2.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.11.1 release</name>
|
||||
<created>2005-07-24</created>
|
||||
<branch></branch>
|
||||
<revision>2.11.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.11/2.11.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.11/2.11.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.11.0 release</name>
|
||||
<created>2005-07-12</created>
|
||||
<branch></branch>
|
||||
<revision>2.11.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.11/2.11.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.11/2.11.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.10.2 release</name>
|
||||
<created>2005-06-27</created>
|
||||
<branch></branch>
|
||||
<revision>2.10.2</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.10/2.10.2.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.10/2.10.2.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.10.1 release</name>
|
||||
<created>2005-04-11</created>
|
||||
<branch></branch>
|
||||
<revision>2.10.1</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.10/2.10.1.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.10/2.10.1.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.10.0 release</name>
|
||||
<created>2005-03-07</created>
|
||||
<branch></branch>
|
||||
<revision>2.10.0</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.10/2.10.0.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.10/2.10.0.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.8.5 release</name>
|
||||
<created>2004-09-13</created>
|
||||
<branch></branch>
|
||||
<revision>2.8.5</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.8/2.8.5.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.8/2.8.5.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.8.5 release</name>
|
||||
<created>2004-09-13</created>
|
||||
<branch></branch>
|
||||
<revision>2.8.5</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.8/2.8.5.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.8/2.8.5.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.8.4 release</name>
|
||||
<created>2004-08-29</created>
|
||||
<branch></branch>
|
||||
<revision>2.8.4</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.8/2.8.4.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.8/2.8.4.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<release><Version>
|
||||
<name>2.8.3 release</name>
|
||||
<created>2004-08-15</created>
|
||||
<branch></branch>
|
||||
<revision>2.8.3</revision>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.8/2.8.3.tar.gz"/>
|
||||
<file-release rdf:resource="http://download.gnome.org/sources/metacity/2.8/2.8.3.tar.bz2"/>
|
||||
</Version></release>
|
||||
|
||||
<!-- earlier ones not yet documented, and will have to be added by hand -->
|
||||
|
||||
</Project>
|
||||
|
223
po/ChangeLog
223
po/ChangeLog
@@ -1,3 +1,226 @@
|
||||
2009-02-01 Gil Forcada <gforcada@gnome.org>
|
||||
|
||||
* ca.po: Updated Catalan translation by David Planella.
|
||||
|
||||
2009-01-31 Jorge Gonzalez <jorgegonz@svn.gnome.org>
|
||||
|
||||
* es.po: Updated Spanish translation
|
||||
|
||||
2009-01-31 Daniel Nylander <po@danielnylander.se>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2009-01-29 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* nb.po: Updated Norwegian bokmål translation.
|
||||
|
||||
2009-01-29 Changwoo Ryu <cwryu@debian.org>
|
||||
|
||||
* ko.po: Updated Korean translation.
|
||||
|
||||
2009-01-24 Raivis DEjus <orvils@gmail.com>
|
||||
|
||||
* lv.po: Updated Latvian translation.
|
||||
|
||||
2009-01-22 Yair Hershkovitz <yairhr@gmail.com>
|
||||
|
||||
* he.po: Updated Hebrew translation.
|
||||
|
||||
2009-01-17 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* ig.po: Added Igbo translation by Sylvester Onye.
|
||||
* yo.po Added Yoruba translation by Sunday Ayo Fajuyitan.
|
||||
* ha.po: Added Hausa translation by Saudat Mohammed.
|
||||
* LINGUAS: added Igbo, Yoruba and Hausa.
|
||||
|
||||
2009-01-17 Gabor Kelemen <kelemeng@gnome.hu>
|
||||
|
||||
* hu.po: Translation updated.
|
||||
|
||||
2009-01-09 Daniel Nylander <po@danielnylander.se>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2009-01-03 甘露(Gan Lu) <rhythm.gan@gmail.com>
|
||||
|
||||
* zh_CN.po: Updated Chinese Simplified translation
|
||||
|
||||
2009-01-03 Priit Laes <plaes at svn dot gnome dot org>
|
||||
|
||||
* et.po: Translation updated by Mattias Põldaru
|
||||
|
||||
2008-12-26 Jorge Gonzalez <jorgegonz@svn.gnome.org>
|
||||
|
||||
* es.po: Updated Spanish translation.
|
||||
|
||||
2008-12-12 Luca Ferretti <elle.uca@libero.it>
|
||||
|
||||
* it.po: Imported updated translation from gnome-2-24 branch.
|
||||
|
||||
2008-12-08 Priit Laes <plaes at svn dot gnome dot org>
|
||||
|
||||
* et.po: Translation updated by Mattias Põldaru
|
||||
|
||||
2008-11-23 Jorge Gonzalez <jorgegonz@svn.gnome.org>
|
||||
|
||||
* es.po: Updated Spanish translation
|
||||
|
||||
2008-11-14 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* la.po: Updated Latin translation
|
||||
|
||||
2008-11-14 Jorge Gonzalez <jorgegonz@svn.gnome.org>
|
||||
|
||||
* es.po: Updated Spanish translation
|
||||
|
||||
2008-11-09 Jorge Gonzalez <jorgegonz@svn.gnome.org>
|
||||
|
||||
* es.po: Updated Spanish translation
|
||||
|
||||
2008-11-08 Jorge Gonzalez <jorgegonz@svn.gnome.org>
|
||||
|
||||
* es.po: Updated Spanish translation
|
||||
|
||||
2008-11-03 Leonardo Ferreira Fontenelle <leonardof@gnome.org>
|
||||
|
||||
* pt_BR.po: Merged from branch gnome-2-24. Minor capitalization fix in
|
||||
the Brazilian Portuguese translation.
|
||||
|
||||
2008-10-27 Og Maciel <ogmaciel@gnome.org>
|
||||
|
||||
* pt_BR.po: Updated Brazilian Portuguese translation by
|
||||
Og Maciel.
|
||||
|
||||
2008-10-27 Daniel Nylander <po@danielnylander.se>
|
||||
|
||||
* sv.po: Updated Swedish translation.
|
||||
|
||||
2008-10-23 Gil Forcada <gforcada@gnome.org>
|
||||
|
||||
* LINGUAS: Added ast.
|
||||
* ast.po: Added Asturian translation on behalf of Mikel González.
|
||||
|
||||
2008-10-22 Jordi Mallach <jordi@sindominio.net>
|
||||
|
||||
* ca@valencia.po: New Valencian (Southern Catalan) translation
|
||||
based on the Catalan file.
|
||||
* LINGUAS: Added Valencian (Southern Catalan) (ca@valencia).
|
||||
|
||||
2008-10-22 Jordi Mallach <jordi@sindominio.net>
|
||||
|
||||
* ca.po: Apply Catalan fixes from Robert Millan.
|
||||
|
||||
2008-10-17 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* la.po: Updated Latin translation.
|
||||
|
||||
2008-10-16 Marcel Telka <marcel@telka.sk>
|
||||
|
||||
* sk.po: Updated Slovak translation by Pavol Šimo.
|
||||
|
||||
2008-10-15 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* la.po: Updated Latin translation.
|
||||
|
||||
2008-10-15 Thomas Thurman <tthurman@gnome.org>
|
||||
|
||||
* la.po: Updated Latin translation.
|
||||
|
||||
2008-10-12 Kjartan Maraas <kmaraas@gnome.org>
|
||||
|
||||
* nb.po: Updated Norwegian bokmål translation.
|
||||
|
||||
2008-10-12 Theppitak Karoonboonyanan <thep@linux.thai.net>
|
||||
|
||||
* th.po: Updated Thai translation (merged from gnome-2-24 branch).
|
||||
|
||||
2008-10-11 Claude Paroz <claude@2xlibre.net>
|
||||
|
||||
* fr.po: Fixed minimize/unmaximize French translation (sync with 2.24) and
|
||||
complete some other translations.
|
||||
|
||||
2008-09-30 Og Maciel <ogmaciel@gnome.org>
|
||||
|
||||
* pt_BR.po: Updated Brazilian Portuguese translation by Vladimir Melo.
|
||||
|
||||
2008-09-29 Alexander Shopov <ash@contact.bg>
|
||||
|
||||
* bg.po: Updated Bulgarian translation by
|
||||
Alexander Shopov <ash@contact.bg>
|
||||
|
||||
2008-09-27 Gil Forcada <gforcada@gnome.org>
|
||||
|
||||
* ca.po: Updated Catalan translation.
|
||||
|
||||
2008-09-27 Laurent Dhima <laurenti@alblinux.net>
|
||||
|
||||
* sq.po: Updated Albanian Translation.
|
||||
|
||||
2008-09-24 Priit Laes <plaes at svn dot gnome dot org>
|
||||
|
||||
* et.po: Translation updated by Ivar Smolin
|
||||
|
||||
2008-09-22 Kenneth Nielsen <k.nielsen81@gmail.com>
|
||||
|
||||
* da.po: Updated Danish translation by Kenneth Nielsen
|
||||
|
||||
2008-09-22 Kenneth Nielsen <k.nielsen81@gmail.com>
|
||||
|
||||
* da.po: Updated Danish translation by Kenneth Nielsen
|
||||
|
||||
2008-09-22 Mugurel Tudor <mugurelu@gnome.ro>
|
||||
|
||||
* ro.po: Updated Romanian translation by
|
||||
Mişu Moldovan <dumol@gnome.ro>
|
||||
|
||||
2008-09-21 Theppitak Karoonboonyanan <thep@linux.thai.net>
|
||||
|
||||
* th.po: Updated Thai translation.
|
||||
|
||||
2008-09-21 Gintautas Miliauskas <gintas@akl.lt>
|
||||
|
||||
* lt.po: Updated Lithuanian translation.
|
||||
|
||||
2008-09-20 Priit Laes <plaes at svn dot gnome dot org>
|
||||
|
||||
* et.po: Translation updated by Ivar Smolin
|
||||
|
||||
2008-09-17 Gabor Kelemen <kelemeng@gnome.hu>
|
||||
|
||||
* hu.po: Translation updated.
|
||||
|
||||
2008-09-14 Duarte Loreto <happyguy_pt@hotmail.com>
|
||||
|
||||
* pt.po: Fixed Portuguese terminology.
|
||||
|
||||
2008-09-12 Hendrik Richter <hendrikr@gnome.org>
|
||||
|
||||
* de.po: Updated German translation.
|
||||
|
||||
2008-09-12 Goran Rakić <grakic@devbase.net>
|
||||
|
||||
* sr.po, sr@latin.po: Updated Serbian translation (by Miloš Popović).
|
||||
|
||||
2008-09-09 Robert Sedak <robert.sedak@sk.t-com.hr>
|
||||
|
||||
* hr.po: Updated Croatian translation.
|
||||
|
||||
2008-09-08 Priit Laes <plaes at svn dot gnome dot org>
|
||||
|
||||
* et.po: Translation updated by Mattias Põldaru
|
||||
|
||||
2008-09-07 Seán de Búrca <sdeburca@svn.gnome.org>
|
||||
|
||||
* ga.po: Updated Irish translation.
|
||||
|
||||
2008-09-06 Funda Wang <fundawang@gmail.com>
|
||||
|
||||
* zh_CN.po: Updated zh_CN translation.
|
||||
|
||||
2008-09-06 Claude Paroz <claude@2xlibre.net>
|
||||
|
||||
* fr.po: Updated French translation.
|
||||
|
||||
2008-08-24 Gintautas Miliauskas <gintas@akl.lt>
|
||||
|
||||
* lt.po: Updated Lithuanian translation.
|
||||
|
@@ -3,6 +3,7 @@
|
||||
am
|
||||
ar
|
||||
as
|
||||
ast
|
||||
az
|
||||
be
|
||||
be@latin
|
||||
@@ -11,6 +12,7 @@ bn
|
||||
bn_IN
|
||||
bs
|
||||
ca
|
||||
ca@valencia
|
||||
cs
|
||||
cy
|
||||
da
|
||||
@@ -28,12 +30,14 @@ fr
|
||||
ga
|
||||
gl
|
||||
gu
|
||||
ha
|
||||
he
|
||||
hi
|
||||
hr
|
||||
hu
|
||||
hy
|
||||
id
|
||||
ig
|
||||
is
|
||||
it
|
||||
ja
|
||||
@@ -41,6 +45,7 @@ ka
|
||||
kn
|
||||
ko
|
||||
ku
|
||||
la
|
||||
lt
|
||||
lv
|
||||
mg
|
||||
@@ -67,7 +72,7 @@ sk
|
||||
sl
|
||||
sq
|
||||
sr
|
||||
sr@Latn
|
||||
sr@latin
|
||||
sv
|
||||
ta
|
||||
th
|
||||
@@ -77,6 +82,7 @@ uk
|
||||
vi
|
||||
wa
|
||||
xh
|
||||
yo
|
||||
zh_CN
|
||||
zh_HK
|
||||
zh_TW
|
||||
|
@@ -10,20 +10,23 @@ src/core/keybindings.c
|
||||
src/core/main.c
|
||||
src/core/prefs.c
|
||||
src/core/screen.c
|
||||
src/core/schema-bindings.c
|
||||
src/core/session.c
|
||||
src/core/util.c
|
||||
src/core/window-props.c
|
||||
src/core/window.c
|
||||
src/core/window-props.c
|
||||
src/core/xprops.c
|
||||
src/include/all-keybindings.h
|
||||
src/metacity.desktop.in
|
||||
src/metacity.schemas.in
|
||||
src/metacity.schemas.in.in
|
||||
src/metacity-wm.desktop.in
|
||||
src/tools/metacity-message.c
|
||||
src/ui/frames.c
|
||||
src/ui/menu.c
|
||||
src/ui/metaaccellabel.c
|
||||
src/ui/metacity-dialog.c
|
||||
src/ui/resizepopup.c
|
||||
src/ui/theme.c
|
||||
src/ui/theme-parser.c
|
||||
src/ui/theme-viewer.c
|
||||
src/ui/theme.c
|
||||
src/tools/metacity-message.c
|
||||
|
||||
|
2
po/POTFILES.skip
Normal file
2
po/POTFILES.skip
Normal file
@@ -0,0 +1,2 @@
|
||||
src/metacity.schemas.in
|
||||
|
4079
po/ca@valencia.po
Normal file
4079
po/ca@valencia.po
Normal file
File diff suppressed because it is too large
Load Diff
4816
po/pt_BR.po
4816
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
5048
po/zh_CN.po
5048
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@ testboxes
|
||||
testgradient
|
||||
inlinepixbufs.h
|
||||
metacity.desktop
|
||||
metacity-wm.desktop
|
||||
metacity.schemas
|
||||
libmetacity-private.pc
|
||||
testasyncgetprop
|
||||
|
@@ -2,12 +2,15 @@ lib_LTLIBRARIES = libmetacity-private.la
|
||||
|
||||
SUBDIRS=wm-tester tools themes
|
||||
|
||||
INCLUDES=@METACITY_CFLAGS@ -I $(srcdir)/include -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMETACITY_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMETACITY_PKGDATADIR=\"$(pkgdatadir)\" -DMETACITY_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"metacity\" -DSN_API_NOT_YET_FROZEN=1
|
||||
if WITH_CLUTTER
|
||||
SUBDIRS += compositor/mutter/plugins
|
||||
endif
|
||||
|
||||
INCLUDES=@METACITY_CFLAGS@ -I $(srcdir)/include -I$(srcdir)/compositor -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMETACITY_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMETACITY_PKGDATADIR=\"$(pkgdatadir)\" -DMETACITY_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"metacity\" -DSN_API_NOT_YET_FROZEN=1 -DMETACITY_MAJOR_VERSION=$(METACITY_MAJOR_VERSION) -DMETACITY_MINOR_VERSION=$(METACITY_MINOR_VERSION) -DMETACITY_MICRO_VERSION=$(METACITY_MICRO_VERSION) -DMETACITY_CLUTTER_PLUGIN_API_VERSION=$(METACITY_CLUTTER_PLUGIN_API_VERSION) -DMETACITY_PKGLIBDIR=\"$(pkglibdir)\" -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"
|
||||
|
||||
metacity_SOURCES= \
|
||||
core/async-getprop.c \
|
||||
core/async-getprop.h \
|
||||
core/atomnames.h \
|
||||
core/bell.c \
|
||||
core/bell.h \
|
||||
core/boxes.c \
|
||||
@@ -43,11 +46,11 @@ metacity_SOURCES= \
|
||||
core/group-props.c \
|
||||
core/group-props.h \
|
||||
core/group.c \
|
||||
core/group.h \
|
||||
include/group.h \
|
||||
core/iconcache.c \
|
||||
core/iconcache.h \
|
||||
core/keybindings.c \
|
||||
core/keybindings.h \
|
||||
core/keybindings-private.h \
|
||||
core/main.c \
|
||||
include/main.h \
|
||||
core/metacity-Xatomtype.h \
|
||||
@@ -71,7 +74,7 @@ metacity_SOURCES= \
|
||||
core/window-private.h \
|
||||
include/window.h \
|
||||
core/workspace.c \
|
||||
core/workspace.h \
|
||||
core/workspace-private.h \
|
||||
core/xprops.c \
|
||||
include/xprops.h \
|
||||
include/common.h \
|
||||
@@ -96,7 +99,24 @@ metacity_SOURCES= \
|
||||
ui/theme.h \
|
||||
ui/themewidget.c \
|
||||
ui/themewidget.h \
|
||||
ui/ui.c
|
||||
ui/ui.c \
|
||||
include/all-keybindings.h
|
||||
|
||||
if WITH_CLUTTER
|
||||
metacity_SOURCES += \
|
||||
compositor/mutter/compositor-mutter.c \
|
||||
compositor/mutter/mutter-shaped-texture.c \
|
||||
compositor/mutter/mutter-shaped-texture.h \
|
||||
compositor/mutter/mutter-plugin-manager.c \
|
||||
compositor/mutter/mutter-plugin-manager.h \
|
||||
compositor/mutter/tidy/tidy-texture-frame.c \
|
||||
compositor/mutter/tidy/tidy-texture-frame.h \
|
||||
compositor/mutter/mutter-module.c \
|
||||
compositor/mutter/mutter-module.h \
|
||||
compositor/mutter/mutter-plugin.c \
|
||||
include/mutter-plugin.h \
|
||||
include/compositor-mutter.h
|
||||
endif
|
||||
|
||||
# by setting libmetacity_private_la_CFLAGS, the files shared with
|
||||
# metacity proper will be compiled with different names.
|
||||
@@ -128,7 +148,19 @@ libmetacityinclude_HEADERS = \
|
||||
include/common.h \
|
||||
ui/preview-widget.h \
|
||||
ui/theme-parser.h \
|
||||
ui/theme.h
|
||||
ui/theme.h \
|
||||
include/atomnames.h \
|
||||
include/prefs.h \
|
||||
include/window.h \
|
||||
include/workspace.h \
|
||||
include/compositor.h \
|
||||
include/compositor-mutter.h \
|
||||
include/types.h \
|
||||
include/screen.h \
|
||||
include/display.h \
|
||||
include/group.h \
|
||||
include/keybindings.h \
|
||||
include/mutter-plugin.h
|
||||
|
||||
metacity_theme_viewer_SOURCES= \
|
||||
ui/theme-viewer.c
|
||||
@@ -136,11 +168,21 @@ metacity_theme_viewer_SOURCES= \
|
||||
metacity_dialog_SOURCES= \
|
||||
ui/metacity-dialog.c
|
||||
|
||||
schema_bindings_SOURCES = \
|
||||
core/schema-bindings.c \
|
||||
metacity.schemas.in.in
|
||||
|
||||
schema_bindings_LDADD = @METACITY_LIBS@
|
||||
metacity.schemas.in: schema_bindings ${srcdir}/metacity.schemas.in.in
|
||||
@echo Generating keybinding schemas... ${srcdir}/metacity.schemas.in.in
|
||||
${builddir}/schema_bindings ${srcdir}/metacity.schemas.in.in ${builddir}/metacity.schemas.in
|
||||
|
||||
bin_PROGRAMS=metacity metacity-theme-viewer
|
||||
libexec_PROGRAMS=metacity-dialog
|
||||
|
||||
EFENCE=
|
||||
metacity_LDADD=@METACITY_LIBS@ $(EFENCE)
|
||||
metacity_LDFLAGS=-export-dynamic
|
||||
metacity_theme_viewer_LDADD= @METACITY_LIBS@ libmetacity-private.la
|
||||
metacity_dialog_LDADD=@METACITY_LIBS@
|
||||
|
||||
@@ -148,18 +190,23 @@ testboxes_SOURCES=include/util.h core/util.c include/boxes.h core/boxes.c core/t
|
||||
testgradient_SOURCES=ui/gradient.h ui/gradient.c ui/testgradient.c
|
||||
testasyncgetprop_SOURCES=core/async-getprop.h core/async-getprop.c core/testasyncgetprop.c
|
||||
|
||||
noinst_PROGRAMS=testboxes testgradient testasyncgetprop
|
||||
noinst_PROGRAMS=testboxes testgradient testasyncgetprop schema_bindings
|
||||
|
||||
testboxes_LDADD= @METACITY_LIBS@
|
||||
testgradient_LDADD= @METACITY_LIBS@
|
||||
testasyncgetprop_LDADD= @METACITY_LIBS@
|
||||
|
||||
desktopfilesdir=$(datadir)/gnome/wm-properties
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
desktopfilesdir=$(datadir)/applications
|
||||
desktopfiles_in_files=metacity.desktop.in
|
||||
desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop)
|
||||
desktopfiles_DATA = $(desktopfiles_files)
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
wmpropertiesdir=$(datadir)/gnome/wm-properties
|
||||
wmproperties_in_files=metacity-wm.desktop.in
|
||||
wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop)
|
||||
wmproperties_DATA = $(wmproperties_files)
|
||||
|
||||
schemadir = @GCONF_SCHEMA_FILE_DIR@
|
||||
schema_in_files = metacity.schemas.in
|
||||
@@ -186,19 +233,22 @@ VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
|
||||
stock_delete_data $(srcdir)/stock_delete.png
|
||||
|
||||
BUILT_SOURCES = inlinepixbufs.h
|
||||
CLEANFILES = inlinepixbufs.h metacity.desktop metacity.schemas 50-metacity-desktop-key.xml 50-metacity-key.xml
|
||||
CLEANFILES = inlinepixbufs.h metacity.desktop metacity-wm.desktop metacity.schemas metacity.schemas.in 50-metacity-desktop-key.xml 50-metacity-key.xml
|
||||
|
||||
inlinepixbufs.h: $(IMAGES)
|
||||
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
pkgconfig_DATA = libmetacity-private.pc
|
||||
pkgconfig_DATA = libmetacity-private.pc metacity-plugins.pc
|
||||
|
||||
EXTRA_DIST=$(desktopfiles_files) \
|
||||
$(wmproperties_files) \
|
||||
$(IMAGES) $(schema_DATA) \
|
||||
$(desktopfiles_in_files) \
|
||||
$(wmproperties_in_files) \
|
||||
$(schema_in_files) \
|
||||
$(xml_in_files) \
|
||||
libmetacity-private.pc.in
|
||||
libmetacity-private.pc.in \
|
||||
metacity-plugins.pc.in
|
||||
|
||||
|
@@ -33,22 +33,58 @@ struct _MetaCompositor
|
||||
void (*unmanage_screen) (MetaCompositor *compositor,
|
||||
MetaScreen *screen);
|
||||
void (*add_window) (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
Window xwindow,
|
||||
XWindowAttributes *attrs);
|
||||
MetaWindow *window);
|
||||
void (*remove_window) (MetaCompositor *compositor,
|
||||
Window xwindow);
|
||||
MetaWindow *window);
|
||||
void (*set_updates) (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean update);
|
||||
void (*process_event) (MetaCompositor *compositor,
|
||||
XEvent *event,
|
||||
MetaWindow *window);
|
||||
gboolean (*process_event) (MetaCompositor *compositor,
|
||||
XEvent *event,
|
||||
MetaWindow *window);
|
||||
Pixmap (*get_window_pixmap) (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void (*set_active_window) (MetaCompositor *compositor,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window);
|
||||
void (*map_window) (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void (*unmap_window) (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void (*minimize_window) (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaRectangle *window_rect,
|
||||
MetaRectangle *icon_rect);
|
||||
void (*unminimize_window) (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaRectangle *window_rect,
|
||||
MetaRectangle *icon_rect);
|
||||
void (*maximize_window) (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaRectangle *window_rect);
|
||||
void (*unmaximize_window) (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaRectangle *window_rect);
|
||||
void (*update_workspace_geometry) (MetaCompositor *compositor,
|
||||
MetaWorkspace *workspace);
|
||||
void (*switch_workspace) (MetaCompositor *compositor,
|
||||
MetaScreen *screen,
|
||||
MetaWorkspace *from,
|
||||
MetaWorkspace *to,
|
||||
MetaMotionDirection direction);
|
||||
void (*sync_stack) (MetaCompositor *compositor,
|
||||
MetaScreen *screen,
|
||||
GList *stack);
|
||||
void (*set_window_hidden) (MetaCompositor *compositor,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
gboolean hidden);
|
||||
void (*sync_window_geometry) (MetaCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
void (*sync_screen_size) (MetaCompositor *compositor,
|
||||
MetaScreen *screen,
|
||||
guint width,
|
||||
guint height);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -26,6 +26,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
@@ -81,17 +83,6 @@ composite_at_least_version (MetaDisplay *display,
|
||||
|
||||
#endif
|
||||
|
||||
typedef enum _MetaCompWindowType
|
||||
{
|
||||
META_COMP_WINDOW_NORMAL,
|
||||
META_COMP_WINDOW_DND,
|
||||
META_COMP_WINDOW_DESKTOP,
|
||||
META_COMP_WINDOW_DOCK,
|
||||
META_COMP_WINDOW_MENU,
|
||||
META_COMP_WINDOW_DROP_DOWN_MENU,
|
||||
META_COMP_WINDOW_TOOLTIP,
|
||||
} MetaCompWindowType;
|
||||
|
||||
typedef enum _MetaShadowType
|
||||
{
|
||||
META_SHADOW_SMALL,
|
||||
@@ -922,7 +913,7 @@ window_has_shadow (MetaCompWindow *cw)
|
||||
}
|
||||
|
||||
if (cw->type == META_COMP_WINDOW_MENU ||
|
||||
cw->type == META_COMP_WINDOW_DROP_DOWN_MENU) {
|
||||
cw->type == META_COMP_WINDOW_DROPDOWN_MENU) {
|
||||
meta_verbose ("Window has shadow as it is a menu\n");
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1787,7 +1778,7 @@ get_window_type (MetaDisplay *display,
|
||||
else if (type_atom == compositor->atom_net_wm_window_type_menu)
|
||||
cw->type = META_COMP_WINDOW_MENU;
|
||||
else if (type_atom == compositor->atom_net_wm_window_type_dropdown_menu)
|
||||
cw->type = META_COMP_WINDOW_DROP_DOWN_MENU;
|
||||
cw->type = META_COMP_WINDOW_DROPDOWN_MENU;
|
||||
else if (type_atom == compositor->atom_net_wm_window_type_tooltip)
|
||||
cw->type = META_COMP_WINDOW_TOOLTIP;
|
||||
else
|
||||
@@ -2400,14 +2391,14 @@ process_destroy (MetaCompositorXRender *compositor,
|
||||
destroy_win (compositor->display, event->window, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
process_damage (MetaCompositorXRender *compositor,
|
||||
XDamageNotifyEvent *event)
|
||||
{
|
||||
MetaCompWindow *cw = find_window_in_display (compositor->display,
|
||||
event->drawable);
|
||||
if (cw == NULL)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
repair_win (cw);
|
||||
|
||||
@@ -2415,6 +2406,8 @@ process_damage (MetaCompositorXRender *compositor,
|
||||
if (event->more == FALSE)
|
||||
add_repair (compositor->display);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2452,23 +2445,21 @@ timeout_debug (MetaCompositorXRender *compositor)
|
||||
|
||||
static void
|
||||
xrender_add_window (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
Window xwindow,
|
||||
XWindowAttributes *attrs)
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
MetaCompositorXRender *xrc = (MetaCompositorXRender *) compositor;
|
||||
MetaScreen *screen = meta_screen_for_x_screen (attrs->screen);
|
||||
MetaScreen *screen = meta_window_get_screen (window);
|
||||
|
||||
meta_error_trap_push (xrc->display);
|
||||
add_win (screen, window, xwindow);
|
||||
add_win (screen, window, meta_window_get_xwindow (window));
|
||||
meta_error_trap_pop (xrc->display, FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
xrender_remove_window (MetaCompositor *compositor,
|
||||
Window xwindow)
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
#endif
|
||||
@@ -2748,7 +2739,7 @@ xrender_free_window (MetaCompositor *compositor,
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
xrender_process_event (MetaCompositor *compositor,
|
||||
XEvent *event,
|
||||
MetaWindow *window)
|
||||
@@ -2809,7 +2800,7 @@ xrender_process_event (MetaCompositor *compositor,
|
||||
else
|
||||
{
|
||||
meta_error_trap_pop (xrc->display, FALSE);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2819,7 +2810,7 @@ xrender_process_event (MetaCompositor *compositor,
|
||||
repair_display (xrc->display);
|
||||
#endif
|
||||
|
||||
return;
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3071,3 +3062,6 @@ meta_compositor_xrender_new (MetaDisplay *display)
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||
|
||||
|
@@ -22,12 +22,24 @@
|
||||
#include <config.h>
|
||||
#include "compositor-private.h"
|
||||
#include "compositor-xrender.h"
|
||||
#include "prefs.h"
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
#include "compositor-mutter.h"
|
||||
int meta_compositor_can_use_clutter__ = 0;
|
||||
#endif
|
||||
|
||||
MetaCompositor *
|
||||
meta_compositor_new (MetaDisplay *display)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
#ifdef WITH_CLUTTER
|
||||
/* At some point we would have a way to select between backends */
|
||||
/* return meta_compositor_xrender_new (display); */
|
||||
if (meta_compositor_can_use_clutter__ && !meta_prefs_get_clutter_disabled ())
|
||||
return mutter_new (display);
|
||||
else
|
||||
#endif
|
||||
return meta_compositor_xrender_new (display);
|
||||
#else
|
||||
return NULL;
|
||||
@@ -45,23 +57,21 @@ meta_compositor_destroy (MetaCompositor *compositor)
|
||||
|
||||
void
|
||||
meta_compositor_add_window (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
Window xwindow,
|
||||
XWindowAttributes *attrs)
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->add_window)
|
||||
compositor->add_window (compositor, window, xwindow, attrs);
|
||||
compositor->add_window (compositor, window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_remove_window (MetaCompositor *compositor,
|
||||
Window xwindow)
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->remove_window)
|
||||
compositor->remove_window (compositor, xwindow);
|
||||
compositor->remove_window (compositor, window);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -96,14 +106,16 @@ meta_compositor_set_updates (MetaCompositor *compositor,
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
gboolean
|
||||
meta_compositor_process_event (MetaCompositor *compositor,
|
||||
XEvent *event,
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->process_event)
|
||||
compositor->process_event (compositor, event, window);
|
||||
return compositor->process_event (compositor, event, window);
|
||||
else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -114,7 +126,7 @@ meta_compositor_get_window_pixmap (MetaCompositor *compositor,
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->get_window_pixmap)
|
||||
return compositor->get_window_pixmap (compositor, window);
|
||||
else
|
||||
else
|
||||
return None;
|
||||
#else
|
||||
return None;
|
||||
@@ -127,7 +139,7 @@ meta_compositor_set_active_window (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->set_active_window)
|
||||
if (compositor && compositor->set_active_window)
|
||||
compositor->set_active_window (compositor, screen, window);
|
||||
#endif
|
||||
}
|
||||
@@ -136,14 +148,14 @@ meta_compositor_set_active_window (MetaCompositor *compositor,
|
||||
void meta_compositor_begin_move (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaRectangle *initial,
|
||||
int grab_x,
|
||||
int grab_x,
|
||||
int grab_y)
|
||||
{
|
||||
}
|
||||
|
||||
void meta_compositor_update_move (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
int x,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
}
|
||||
@@ -153,7 +165,137 @@ void meta_compositor_end_move (MetaCompositor *compositor,
|
||||
{
|
||||
}
|
||||
|
||||
void meta_compositor_free_window (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
void
|
||||
meta_compositor_map_window (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->map_window)
|
||||
compositor->map_window (compositor, window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_unmap_window (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->unmap_window)
|
||||
compositor->unmap_window (compositor, window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_minimize_window (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaRectangle *window_rect,
|
||||
MetaRectangle *icon_rect)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->minimize_window)
|
||||
compositor->minimize_window (compositor, window, window_rect, icon_rect);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_unminimize_window (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaRectangle *window_rect,
|
||||
MetaRectangle *icon_rect)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->unminimize_window)
|
||||
compositor->unminimize_window (compositor, window, window_rect, icon_rect);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_maximize_window (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaRectangle *window_rect)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->maximize_window)
|
||||
compositor->maximize_window (compositor, window, window_rect);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_unmaximize_window (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaRectangle *window_rect)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->unmaximize_window)
|
||||
compositor->unmaximize_window (compositor, window, window_rect);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_update_workspace_geometry (MetaCompositor *compositor,
|
||||
MetaWorkspace *workspace)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->update_workspace_geometry)
|
||||
compositor->update_workspace_geometry (compositor, workspace);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_switch_workspace (MetaCompositor *compositor,
|
||||
MetaScreen *screen,
|
||||
MetaWorkspace *from,
|
||||
MetaWorkspace *to,
|
||||
MetaMotionDirection direction)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->switch_workspace)
|
||||
compositor->switch_workspace (compositor, screen, from, to, direction);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_sync_stack (MetaCompositor *compositor,
|
||||
MetaScreen *screen,
|
||||
GList *stack)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->sync_stack)
|
||||
compositor->sync_stack (compositor, screen, stack);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_set_window_hidden (MetaCompositor *compositor,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
gboolean hidden)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->set_window_hidden)
|
||||
compositor->set_window_hidden (compositor, screen, window, hidden);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->sync_window_geometry)
|
||||
compositor->sync_window_geometry (compositor, window);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_sync_screen_size (MetaCompositor *compositor,
|
||||
MetaScreen *screen,
|
||||
guint width,
|
||||
guint height)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
if (compositor && compositor->sync_screen_size)
|
||||
compositor->sync_screen_size (compositor, screen, width, height);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
10
src/compositor/mutter/README
Normal file
10
src/compositor/mutter/README
Normal file
@@ -0,0 +1,10 @@
|
||||
Intro
|
||||
=====
|
||||
|
||||
Fix me.
|
||||
|
||||
|
||||
Env Vars
|
||||
========
|
||||
|
||||
MUTTER_DISABLE_MIPMAPS - set to disable use of mipmaped windows.
|
2872
src/compositor/mutter/compositor-mutter.c
Normal file
2872
src/compositor/mutter/compositor-mutter.c
Normal file
File diff suppressed because it is too large
Load Diff
207
src/compositor/mutter/mutter-module.c
Normal file
207
src/compositor/mutter/mutter-module.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Intel Corp.
|
||||
*
|
||||
* Author: Tomas Frydrych <tf@linux.intel.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "mutter-plugin.h"
|
||||
#include "mutter-module.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PATH,
|
||||
};
|
||||
|
||||
struct _MutterModulePrivate
|
||||
{
|
||||
GModule *lib;
|
||||
gchar *path;
|
||||
GType plugin_type;
|
||||
};
|
||||
|
||||
#define MUTTER_MODULE_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUTTER_TYPE_MODULE, MutterModulePrivate))
|
||||
|
||||
G_DEFINE_TYPE (MutterModule, mutter_module, G_TYPE_TYPE_MODULE);
|
||||
|
||||
static gboolean
|
||||
mutter_module_load (GTypeModule *gmodule)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (gmodule)->priv;
|
||||
MutterPluginVersion *info = NULL;
|
||||
GType (*register_type) (GTypeModule *) = NULL;
|
||||
|
||||
if (priv->lib && priv->plugin_type)
|
||||
return TRUE;
|
||||
|
||||
g_assert (priv->path);
|
||||
|
||||
if (!priv->lib &&
|
||||
!(priv->lib = g_module_open (priv->path, G_MODULE_BIND_LOCAL)))
|
||||
{
|
||||
g_warning ("Could not load library [%s (%s)]",
|
||||
priv->path, g_module_error ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (g_module_symbol (priv->lib, "mutter_plugin_version", (gpointer *)&info) &&
|
||||
g_module_symbol (priv->lib, "mutter_plugin_register_type",
|
||||
(gpointer *)®ister_type) &&
|
||||
info && register_type)
|
||||
{
|
||||
if (info->version_api != METACITY_CLUTTER_PLUGIN_API_VERSION)
|
||||
g_warning ("Plugin API mismatch for [%s]", priv->path);
|
||||
else
|
||||
{
|
||||
GType plugin_type;
|
||||
|
||||
if (!(plugin_type = register_type (gmodule)))
|
||||
{
|
||||
g_warning ("Could not register type for plugin %s",
|
||||
priv->path);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->plugin_type = plugin_type;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
g_warning ("Broken plugin module [%s]", priv->path);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_unload (GTypeModule *gmodule)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (gmodule)->priv;
|
||||
|
||||
g_module_close (priv->lib);
|
||||
|
||||
priv->lib = NULL;
|
||||
priv->plugin_type = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_dispose (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (mutter_module_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_finalize (GObject *object)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (object)->priv;
|
||||
|
||||
g_free (priv->path);
|
||||
priv->path = NULL;
|
||||
|
||||
G_OBJECT_CLASS (mutter_module_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
g_free (priv->path);
|
||||
priv->path = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PATH:
|
||||
g_value_set_string (value, priv->path);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_class_init (MutterModuleClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GTypeModuleClass *gmodule_class = G_TYPE_MODULE_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = mutter_module_finalize;
|
||||
gobject_class->dispose = mutter_module_dispose;
|
||||
gobject_class->set_property = mutter_module_set_property;
|
||||
gobject_class->get_property = mutter_module_get_property;
|
||||
|
||||
gmodule_class->load = mutter_module_load;
|
||||
gmodule_class->unload = mutter_module_unload;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PATH,
|
||||
g_param_spec_string ("path",
|
||||
"Path",
|
||||
"Load path",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (MutterModulePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_module_init (MutterModule *self)
|
||||
{
|
||||
MutterModulePrivate *priv;
|
||||
|
||||
self->priv = priv = MUTTER_MODULE_GET_PRIVATE (self);
|
||||
|
||||
}
|
||||
|
||||
GType
|
||||
mutter_module_get_plugin_type (MutterModule *module)
|
||||
{
|
||||
MutterModulePrivate *priv = MUTTER_MODULE (module)->priv;
|
||||
|
||||
return priv->plugin_type;
|
||||
}
|
||||
|
57
src/compositor/mutter/mutter-module.h
Normal file
57
src/compositor/mutter/mutter-module.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Intel Corp.
|
||||
*
|
||||
* Author: Tomas Frydrych <tf@linux.intel.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef MUTTER_MODULE_H_
|
||||
#define MUTTER_MODULE_H_
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#define MUTTER_TYPE_MODULE (mutter_module_get_type ())
|
||||
#define MUTTER_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_MODULE, MutterModule))
|
||||
#define MUTTER_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_MODULE, MutterModuleClass))
|
||||
#define MUTTER_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_MODULE_TYPE))
|
||||
#define MUTTER_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_MODULE))
|
||||
#define MUTTER_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_MODULE, MutterModuleClass))
|
||||
|
||||
typedef struct _MutterModule MutterModule;
|
||||
typedef struct _MutterModuleClass MutterModuleClass;
|
||||
typedef struct _MutterModulePrivate MutterModulePrivate;
|
||||
|
||||
struct _MutterModule
|
||||
{
|
||||
GTypeModule parent;
|
||||
|
||||
MutterModulePrivate *priv;
|
||||
};
|
||||
|
||||
struct _MutterModuleClass
|
||||
{
|
||||
GTypeModuleClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType mutter_module_get_type (void);
|
||||
|
||||
GType mutter_module_get_plugin_type (MutterModule *module);
|
||||
|
||||
#endif
|
590
src/compositor/mutter/mutter-plugin-manager.c
Normal file
590
src/compositor/mutter/mutter-plugin-manager.c
Normal file
@@ -0,0 +1,590 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Intel Corp.
|
||||
*
|
||||
* Author: Tomas Frydrych <tf@linux.intel.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "mutter-plugin-manager.h"
|
||||
#include "prefs.h"
|
||||
#include "errors.h"
|
||||
#include "workspace.h"
|
||||
#include "mutter-module.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* There is only one instace of each module per the process.
|
||||
*/
|
||||
static GHashTable *plugin_modules = NULL;
|
||||
|
||||
static gboolean mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr);
|
||||
|
||||
struct MutterPluginManager
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
GList *plugins;
|
||||
GList *unload; /* Plugins that are disabled and pending unload */
|
||||
|
||||
guint idle_unload_id;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Checks that the plugin is compatible with the WM and sets up the plugin
|
||||
* struct.
|
||||
*/
|
||||
static MutterPlugin *
|
||||
mutter_plugin_load (MutterPluginManager *mgr,
|
||||
MutterModule *module,
|
||||
const gchar *params)
|
||||
{
|
||||
MutterPlugin *plugin = NULL;
|
||||
GType plugin_type = mutter_module_get_plugin_type (module);
|
||||
|
||||
if (!plugin_type)
|
||||
{
|
||||
g_warning ("Plugin type not registered !!!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
plugin = g_object_new (plugin_type,
|
||||
"screen", mgr->screen,
|
||||
"params", params,
|
||||
NULL);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempst to unload a plugin; returns FALSE if plugin cannot be unloaded at
|
||||
* present (e.g., and effect is in progress) and should be scheduled for
|
||||
* removal later.
|
||||
*/
|
||||
static gboolean
|
||||
mutter_plugin_unload (MutterPlugin *plugin)
|
||||
{
|
||||
if (mutter_plugin_running (plugin))
|
||||
{
|
||||
g_object_set (plugin, "disabled", TRUE, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_object_unref (plugin);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iddle callback to remove plugins that could not be removed directly and are
|
||||
* pending for removal.
|
||||
*/
|
||||
static gboolean
|
||||
mutter_plugin_manager_idle_unload (MutterPluginManager *plugin_mgr)
|
||||
{
|
||||
GList *l = plugin_mgr->unload;
|
||||
gboolean dont_remove = TRUE;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
|
||||
if (mutter_plugin_unload (plugin))
|
||||
{
|
||||
/* Remove from list */
|
||||
GList *p = l->prev;
|
||||
GList *n = l->next;
|
||||
|
||||
if (!p)
|
||||
plugin_mgr->unload = n;
|
||||
else
|
||||
p->next = n;
|
||||
|
||||
if (n)
|
||||
n->prev = p;
|
||||
|
||||
g_list_free_1 (l);
|
||||
|
||||
l = n;
|
||||
}
|
||||
else
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
if (!plugin_mgr->unload)
|
||||
{
|
||||
/* If no more unloads are pending, remove the handler as well */
|
||||
dont_remove = FALSE;
|
||||
plugin_mgr->idle_unload_id = 0;
|
||||
}
|
||||
|
||||
return dont_remove;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unloads all plugins
|
||||
*/
|
||||
static void
|
||||
mutter_plugin_manager_unload (MutterPluginManager *plugin_mgr)
|
||||
{
|
||||
GList *plugins = plugin_mgr->plugins;
|
||||
|
||||
while (plugins)
|
||||
{
|
||||
MutterPlugin *plugin = plugins->data;
|
||||
|
||||
/* If the plugin could not be removed, move it to the unload list */
|
||||
if (!mutter_plugin_unload (plugin))
|
||||
{
|
||||
plugin_mgr->unload = g_list_prepend (plugin_mgr->unload, plugin);
|
||||
|
||||
if (!plugin_mgr->idle_unload_id)
|
||||
{
|
||||
plugin_mgr->idle_unload_id = g_idle_add ((GSourceFunc)
|
||||
mutter_plugin_manager_idle_unload,
|
||||
plugin_mgr);
|
||||
}
|
||||
}
|
||||
|
||||
plugins = plugins->next;
|
||||
}
|
||||
|
||||
g_list_free (plugin_mgr->plugins);
|
||||
plugin_mgr->plugins = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
prefs_changed_callback (MetaPreference pref,
|
||||
void *data)
|
||||
{
|
||||
MutterPluginManager *plugin_mgr = data;
|
||||
|
||||
if (pref == META_PREF_CLUTTER_PLUGINS)
|
||||
{
|
||||
mutter_plugin_manager_reload (plugin_mgr);
|
||||
}
|
||||
}
|
||||
|
||||
static MutterModule *
|
||||
mutter_plugin_manager_get_module (const gchar *path)
|
||||
{
|
||||
MutterModule *module = g_hash_table_lookup (plugin_modules, path);
|
||||
|
||||
if (!module &&
|
||||
(module = g_object_new (MUTTER_TYPE_MODULE, "path", path, NULL)))
|
||||
{
|
||||
g_hash_table_insert (plugin_modules, g_strdup (path), module);
|
||||
}
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads all plugins listed in gconf registry.
|
||||
*/
|
||||
static gboolean
|
||||
mutter_plugin_manager_load (MutterPluginManager *plugin_mgr)
|
||||
{
|
||||
const gchar *dpath = MUTTER_PLUGIN_DIR "/";
|
||||
GSList *plugins, *fallback = NULL;
|
||||
|
||||
plugins = meta_prefs_get_clutter_plugins ();
|
||||
|
||||
if (!plugins)
|
||||
{
|
||||
/*
|
||||
* If no plugins are specified, try to load the default plugin.
|
||||
*/
|
||||
fallback = g_slist_append (fallback, "default");
|
||||
plugins = fallback;
|
||||
}
|
||||
|
||||
while (plugins)
|
||||
{
|
||||
gchar *plugin_string;
|
||||
gchar *params;
|
||||
|
||||
plugin_string = g_strdup (plugins->data);
|
||||
|
||||
if (plugin_string)
|
||||
{
|
||||
MutterModule *module;
|
||||
gchar *path;
|
||||
|
||||
params = strchr (plugin_string, ':');
|
||||
|
||||
if (params)
|
||||
{
|
||||
*params = 0;
|
||||
++params;
|
||||
}
|
||||
|
||||
if (g_path_is_absolute (plugin_string))
|
||||
path = g_strdup (plugin_string);
|
||||
else
|
||||
path = g_strconcat (dpath, plugin_string, ".so", NULL);
|
||||
|
||||
module = mutter_plugin_manager_get_module (path);
|
||||
|
||||
if (module)
|
||||
{
|
||||
MutterPlugin *p;
|
||||
gboolean use_succeeded;
|
||||
|
||||
/*
|
||||
* This dlopens the module and registers the plugin type with the
|
||||
* GType system, if the module is not already loaded. When we
|
||||
* create a plugin, the type system also calls g_type_module_use()
|
||||
* to guarantee the module will not be unloaded during the plugin
|
||||
* life time. Consequently we can unuse() the module again.
|
||||
*/
|
||||
use_succeeded = g_type_module_use (G_TYPE_MODULE (module));
|
||||
|
||||
if (use_succeeded &&
|
||||
(p = mutter_plugin_load (plugin_mgr, module, params)))
|
||||
{
|
||||
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Plugin load for [%s] failed", path);
|
||||
}
|
||||
|
||||
if (use_succeeded)
|
||||
g_type_module_unuse (G_TYPE_MODULE (module));
|
||||
}
|
||||
else
|
||||
g_warning ("Unable to load plugin module [%s]: %s",
|
||||
path, g_module_error());
|
||||
|
||||
g_free (path);
|
||||
g_free (plugin_string);
|
||||
}
|
||||
|
||||
plugins = plugins->next;
|
||||
}
|
||||
|
||||
|
||||
if (fallback)
|
||||
g_slist_free (fallback);
|
||||
|
||||
if (plugin_mgr->plugins != NULL)
|
||||
{
|
||||
meta_prefs_add_listener (prefs_changed_callback, plugin_mgr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reloads all plugins
|
||||
*/
|
||||
static gboolean
|
||||
mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr)
|
||||
{
|
||||
/* TODO -- brute force; should we build a list of plugins to load and list of
|
||||
* plugins to unload? We are probably not going to have large numbers of
|
||||
* plugins loaded at the same time, so it might not be worth it.
|
||||
*/
|
||||
mutter_plugin_manager_unload (plugin_mgr);
|
||||
return mutter_plugin_manager_load (plugin_mgr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mutter_plugin_manager_init (MutterPluginManager *plugin_mgr)
|
||||
{
|
||||
return mutter_plugin_manager_load (plugin_mgr);
|
||||
}
|
||||
|
||||
MutterPluginManager *
|
||||
mutter_plugin_manager_new (MetaScreen *screen)
|
||||
{
|
||||
MutterPluginManager *plugin_mgr;
|
||||
|
||||
if (!plugin_modules)
|
||||
{
|
||||
plugin_modules = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||
NULL);
|
||||
}
|
||||
|
||||
plugin_mgr = g_new0 (MutterPluginManager, 1);
|
||||
|
||||
plugin_mgr->screen = screen;
|
||||
|
||||
if (!mutter_plugin_manager_init (plugin_mgr))
|
||||
{
|
||||
g_free (plugin_mgr);
|
||||
plugin_mgr = NULL;
|
||||
}
|
||||
|
||||
return plugin_mgr;
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
|
||||
MutterWindow *actor,
|
||||
unsigned long events)
|
||||
{
|
||||
GList *l = plugin_mgr->plugins;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!mutter_plugin_disabled (plugin)
|
||||
&& (mutter_plugin_features (plugin) & events)
|
||||
&& klass->kill_effect)
|
||||
klass->kill_effect (plugin, actor, events);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
#define ALL_BUT_SWITCH \
|
||||
MUTTER_PLUGIN_ALL_EFFECTS & \
|
||||
~MUTTER_PLUGIN_SWITCH_WORKSPACE
|
||||
/*
|
||||
* Public method that the compositor hooks into for events that require
|
||||
* no additional parameters.
|
||||
*
|
||||
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
|
||||
* if the return value is FALSE, there will be no subsequent call to the
|
||||
* manager completed() callback, and the compositor must ensure that any
|
||||
* appropriate post-effect cleanup is carried out.
|
||||
*/
|
||||
gboolean
|
||||
mutter_plugin_manager_event_simple (MutterPluginManager *plugin_mgr,
|
||||
MutterWindow *actor,
|
||||
unsigned long event)
|
||||
{
|
||||
GList *l = plugin_mgr->plugins;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!mutter_plugin_disabled (plugin) &&
|
||||
(mutter_plugin_features (plugin) & event))
|
||||
{
|
||||
retval = TRUE;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case MUTTER_PLUGIN_MINIMIZE:
|
||||
if (klass->minimize)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->minimize (plugin, actor);
|
||||
}
|
||||
break;
|
||||
case MUTTER_PLUGIN_MAP:
|
||||
if (klass->map)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->map (plugin, actor);
|
||||
}
|
||||
break;
|
||||
case MUTTER_PLUGIN_DESTROY:
|
||||
if (klass->destroy)
|
||||
{
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->destroy (plugin, actor);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_warning ("Incorrect handler called for event %lu", event);
|
||||
}
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* The public method that the compositor hooks into for maximize and unmaximize
|
||||
* events.
|
||||
*
|
||||
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
|
||||
* if the return value is FALSE, there will be no subsequent call to the
|
||||
* manager completed() callback, and the compositor must ensure that any
|
||||
* appropriate post-effect cleanup is carried out.
|
||||
*/
|
||||
gboolean
|
||||
mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
|
||||
MutterWindow *actor,
|
||||
unsigned long event,
|
||||
gint target_x,
|
||||
gint target_y,
|
||||
gint target_width,
|
||||
gint target_height)
|
||||
{
|
||||
GList *l = plugin_mgr->plugins;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!mutter_plugin_disabled (plugin) &&
|
||||
(mutter_plugin_features (plugin) & event))
|
||||
{
|
||||
retval = TRUE;
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case MUTTER_PLUGIN_MAXIMIZE:
|
||||
if (klass->maximize)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->maximize (plugin, actor,
|
||||
target_x, target_y,
|
||||
target_width, target_height);
|
||||
}
|
||||
break;
|
||||
case MUTTER_PLUGIN_UNMAXIMIZE:
|
||||
if (klass->unmaximize)
|
||||
{
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
actor,
|
||||
ALL_BUT_SWITCH);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->unmaximize (plugin, actor,
|
||||
target_x, target_y,
|
||||
target_width, target_height);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_warning ("Incorrect handler called for event %lu", event);
|
||||
}
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* The public method that the compositor hooks into for desktop switching.
|
||||
*
|
||||
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
|
||||
* if the return value is FALSE, there will be no subsequent call to the
|
||||
* manager completed() callback, and the compositor must ensure that any
|
||||
* appropriate post-effect cleanup is carried out.
|
||||
*/
|
||||
gboolean
|
||||
mutter_plugin_manager_switch_workspace (MutterPluginManager *plugin_mgr,
|
||||
const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction)
|
||||
{
|
||||
GList *l = plugin_mgr->plugins;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (!mutter_plugin_disabled (plugin) &&
|
||||
(mutter_plugin_features (plugin) & MUTTER_PLUGIN_SWITCH_WORKSPACE) &&
|
||||
(actors && *actors))
|
||||
{
|
||||
if (klass->switch_workspace)
|
||||
{
|
||||
retval = TRUE;
|
||||
mutter_plugin_manager_kill_effect (
|
||||
plugin_mgr,
|
||||
MUTTER_WINDOW ((*actors)->data),
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
|
||||
_mutter_plugin_effect_started (plugin);
|
||||
klass->switch_workspace (plugin, actors, from, to, direction);
|
||||
}
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* The public method that the compositor hooks into for desktop switching.
|
||||
*
|
||||
* Returns TRUE if at least one of the plugins handled the event type (i.e.,
|
||||
* if the return value is FALSE, there will be no subsequent call to the
|
||||
* manager completed() callback, and the compositor must ensure that any
|
||||
* appropriate post-effect cleanup is carried out.
|
||||
*/
|
||||
gboolean
|
||||
mutter_plugin_manager_xevent_filter (MutterPluginManager *plugin_mgr,
|
||||
XEvent *xev)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
if (!plugin_mgr)
|
||||
return FALSE;
|
||||
|
||||
l = plugin_mgr->plugins;
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterPlugin *plugin = l->data;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (klass->xevent_filter)
|
||||
{
|
||||
if (klass->xevent_filter (plugin, xev) == TRUE)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
61
src/compositor/mutter/mutter-plugin-manager.h
Normal file
61
src/compositor/mutter/mutter-plugin-manager.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Intel Corp.
|
||||
*
|
||||
* Author: Tomas Frydrych <tf@linux.intel.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef MUTTER_PLUGIN_MANAGER_H_
|
||||
#define MUTTER_PLUGIN_MANAGER_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "screen.h"
|
||||
|
||||
#define MUTTER_PLUGIN_FROM_MANAGER_
|
||||
#include "mutter-plugin.h"
|
||||
#undef MUTTER_PLUGIN_FROM_MANAGER_
|
||||
|
||||
typedef struct MutterPluginManager MutterPluginManager;
|
||||
|
||||
MutterPluginManager * mutter_plugin_manager_new (MetaScreen *screen);
|
||||
gboolean mutter_plugin_manager_event_simple (MutterPluginManager *mgr,
|
||||
MutterWindow *actor,
|
||||
unsigned long event);
|
||||
|
||||
gboolean mutter_plugin_manager_event_maximize (MutterPluginManager *mgr,
|
||||
MutterWindow *actor,
|
||||
unsigned long event,
|
||||
gint target_x,
|
||||
gint target_y,
|
||||
gint target_width,
|
||||
gint target_height);
|
||||
void mutter_plugin_manager_update_workspaces (MutterPluginManager *mgr);
|
||||
|
||||
void mutter_plugin_manager_update_workspace (MutterPluginManager *mgr, MetaWorkspace *w);
|
||||
|
||||
gboolean mutter_plugin_manager_switch_workspace (MutterPluginManager *mgr,
|
||||
const GList **actors,
|
||||
gint from,
|
||||
gint to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
gboolean mutter_plugin_manager_xevent_filter (MutterPluginManager *mgr,
|
||||
XEvent *xev);
|
||||
|
||||
#endif
|
515
src/compositor/mutter/mutter-plugin.c
Normal file
515
src/compositor/mutter/mutter-plugin.c
Normal file
@@ -0,0 +1,515 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Intel Corp.
|
||||
*
|
||||
* Author: Tomas Frydrych <tf@linux.intel.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "mutter-plugin.h"
|
||||
#include "screen.h"
|
||||
#include "display.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (MutterPlugin, mutter_plugin, G_TYPE_OBJECT);
|
||||
|
||||
#define MUTTER_PLUGIN_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUTTER_TYPE_PLUGIN, MutterPluginPrivate))
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_SCREEN,
|
||||
PROP_PARAMS,
|
||||
PROP_FEATURES,
|
||||
PROP_DISABLED,
|
||||
PROP_DEBUG_MODE,
|
||||
};
|
||||
|
||||
struct _MutterPluginPrivate
|
||||
{
|
||||
MetaScreen *screen;
|
||||
gchar *params;
|
||||
gulong features;
|
||||
|
||||
gint running;
|
||||
|
||||
gboolean disabled : 1;
|
||||
gboolean debug : 1;
|
||||
};
|
||||
|
||||
static void
|
||||
mutter_plugin_dispose (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (mutter_plugin_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_finalize (GObject *object)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (object)->priv;
|
||||
|
||||
g_free (priv->params);
|
||||
priv->params = NULL;
|
||||
|
||||
G_OBJECT_CLASS (mutter_plugin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_parse_params (MutterPlugin *plugin)
|
||||
{
|
||||
char *p;
|
||||
gulong features = 0;
|
||||
MutterPluginPrivate *priv = plugin->priv;
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
/*
|
||||
* Feature flags: identify events that the plugin can handle; a plugin can
|
||||
* handle one or more events.
|
||||
*/
|
||||
if (klass->minimize)
|
||||
features |= MUTTER_PLUGIN_MINIMIZE;
|
||||
|
||||
if (klass->maximize)
|
||||
features |= MUTTER_PLUGIN_MAXIMIZE;
|
||||
|
||||
if (klass->unmaximize)
|
||||
features |= MUTTER_PLUGIN_UNMAXIMIZE;
|
||||
|
||||
if (klass->map)
|
||||
features |= MUTTER_PLUGIN_MAP;
|
||||
|
||||
if (klass->destroy)
|
||||
features |= MUTTER_PLUGIN_DESTROY;
|
||||
|
||||
if (klass->switch_workspace)
|
||||
features |= MUTTER_PLUGIN_SWITCH_WORKSPACE;
|
||||
|
||||
if (priv->params)
|
||||
{
|
||||
gboolean debug = FALSE;
|
||||
|
||||
if ((p = strstr (priv->params, "disable:")))
|
||||
{
|
||||
gchar *d = g_strdup (p+8);
|
||||
|
||||
p = strchr (d, ';');
|
||||
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
if (strstr (d, "minimize"))
|
||||
features &= ~ MUTTER_PLUGIN_MINIMIZE;
|
||||
|
||||
if (strstr (d, "maximize"))
|
||||
features &= ~ MUTTER_PLUGIN_MAXIMIZE;
|
||||
|
||||
if (strstr (d, "unmaximize"))
|
||||
features &= ~ MUTTER_PLUGIN_UNMAXIMIZE;
|
||||
|
||||
if (strstr (d, "map"))
|
||||
features &= ~ MUTTER_PLUGIN_MAP;
|
||||
|
||||
if (strstr (d, "destroy"))
|
||||
features &= ~ MUTTER_PLUGIN_DESTROY;
|
||||
|
||||
if (strstr (d, "switch-workspace"))
|
||||
features &= ~MUTTER_PLUGIN_SWITCH_WORKSPACE;
|
||||
|
||||
g_free (d);
|
||||
}
|
||||
|
||||
if (strstr (priv->params, "debug"))
|
||||
debug = TRUE;
|
||||
|
||||
if (debug != priv->debug)
|
||||
{
|
||||
priv->debug = debug;
|
||||
|
||||
g_object_notify (G_OBJECT (plugin), "debug-mode");
|
||||
}
|
||||
}
|
||||
|
||||
if (features != priv->features)
|
||||
{
|
||||
priv->features = features;
|
||||
|
||||
g_object_notify (G_OBJECT (plugin), "features");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SCREEN:
|
||||
priv->screen = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_PARAMS:
|
||||
priv->params = g_value_dup_string (value);
|
||||
mutter_plugin_parse_params (MUTTER_PLUGIN (object));
|
||||
break;
|
||||
case PROP_DISABLED:
|
||||
priv->disabled = g_value_get_boolean (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
|
||||
mutter_plugin_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (object)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SCREEN:
|
||||
g_value_set_object (value, priv->screen);
|
||||
break;
|
||||
case PROP_PARAMS:
|
||||
g_value_set_string (value, priv->params);
|
||||
break;
|
||||
case PROP_DISABLED:
|
||||
g_value_set_boolean (value, priv->disabled);
|
||||
break;
|
||||
case PROP_DEBUG_MODE:
|
||||
g_value_set_boolean (value, priv->debug);
|
||||
break;
|
||||
case PROP_FEATURES:
|
||||
g_value_set_ulong (value, priv->features);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mutter_plugin_class_init (MutterPluginClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = mutter_plugin_finalize;
|
||||
gobject_class->dispose = mutter_plugin_dispose;
|
||||
gobject_class->set_property = mutter_plugin_set_property;
|
||||
gobject_class->get_property = mutter_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_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PARAMS,
|
||||
g_param_spec_string ("params",
|
||||
"Parameters",
|
||||
"Plugin Parameters",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_FEATURES,
|
||||
g_param_spec_ulong ("features",
|
||||
"Features",
|
||||
"Plugin Features",
|
||||
0 , G_MAXULONG, 0,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_DISABLED,
|
||||
g_param_spec_boolean ("disabled",
|
||||
"Plugin disabled",
|
||||
"Plugin disabled",
|
||||
FALSE,
|
||||
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 (MutterPluginPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_plugin_init (MutterPlugin *self)
|
||||
{
|
||||
MutterPluginPrivate *priv;
|
||||
|
||||
self->priv = priv = MUTTER_PLUGIN_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
gulong
|
||||
mutter_plugin_features (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return priv->features;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_plugin_disabled (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return priv->disabled;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_plugin_running (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return (priv->running > 0);
|
||||
}
|
||||
|
||||
gboolean
|
||||
mutter_plugin_debug_mode (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return priv->debug;
|
||||
}
|
||||
|
||||
const MutterPluginInfo *
|
||||
mutter_plugin_get_info (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
if (klass && klass->plugin_info)
|
||||
return klass->plugin_info (plugin);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_overlay_group (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return mutter_get_overlay_group_for_screen (priv->screen);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_stage (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return mutter_get_stage_for_screen (priv->screen);
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_plugin_get_window_group (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return mutter_get_window_group_for_screen (priv->screen);
|
||||
}
|
||||
|
||||
/**
|
||||
* _mutter_plugin_effect_started:
|
||||
* @plugin: the plugin
|
||||
*
|
||||
* Mark that an effect has started for the plugin. This is called
|
||||
* internally by MutterPluginManager.
|
||||
*/
|
||||
void
|
||||
_mutter_plugin_effect_started (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
priv->running++;
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_effect_completed (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
unsigned long event)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
if (priv->running-- < 0)
|
||||
{
|
||||
g_warning ("Error in running effect accounting, adjusting.");
|
||||
priv->running = 0;
|
||||
}
|
||||
|
||||
if (!actor)
|
||||
{
|
||||
const MutterPluginInfo *info;
|
||||
const gchar *name = NULL;
|
||||
|
||||
if (plugin && (info = mutter_plugin_get_info (plugin)))
|
||||
name = info->name;
|
||||
|
||||
g_warning ("Plugin [%s] passed NULL for actor!",
|
||||
name ? name : "unknown");
|
||||
}
|
||||
|
||||
mutter_window_effect_completed (actor, event);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_query_screen_size (MutterPlugin *plugin,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
meta_screen_get_size (priv->screen, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_reactive (MutterPlugin *plugin,
|
||||
gboolean reactive)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = mutter_get_stage_for_screen (screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (screen);
|
||||
|
||||
static XserverRegion region = None;
|
||||
|
||||
if (region == None)
|
||||
region = XFixesCreateRegion (xdpy, NULL, 0);
|
||||
|
||||
if (reactive)
|
||||
{
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage,
|
||||
ShapeInput, 0, 0, None);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
||||
ShapeInput, 0, 0, None);
|
||||
}
|
||||
else
|
||||
{
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage,
|
||||
ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay,
|
||||
ShapeInput, 0, 0, region);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_input_area (MutterPlugin *plugin,
|
||||
gint x, gint y, gint width, gint height)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
XRectangle rect;
|
||||
XserverRegion region;
|
||||
|
||||
stage = mutter_get_stage_for_screen (screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (screen);
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = width;
|
||||
rect.height = height;
|
||||
|
||||
region = XFixesCreateRegion (xdpy, &rect, 1);
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
||||
|
||||
XFixesDestroyRegion (xdpy, region);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_plugin_set_stage_input_region (MutterPlugin *plugin,
|
||||
XserverRegion region)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
Window xstage, xoverlay;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = mutter_get_stage_for_screen (screen);
|
||||
xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
xoverlay = mutter_get_overlay_window (screen);
|
||||
|
||||
XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
|
||||
XFixesSetWindowShapeRegion (xdpy, xoverlay, ShapeInput, 0, 0, region);
|
||||
}
|
||||
|
||||
GList *
|
||||
mutter_plugin_get_windows (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return mutter_get_windows (priv->screen);
|
||||
}
|
||||
|
||||
Display *
|
||||
mutter_plugin_get_xdisplay (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
MetaDisplay *display = meta_screen_get_display (priv->screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
|
||||
return xdpy;
|
||||
}
|
||||
|
||||
MetaScreen *
|
||||
mutter_plugin_get_screen (MutterPlugin *plugin)
|
||||
{
|
||||
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
|
||||
|
||||
return priv->screen;
|
||||
}
|
||||
|
466
src/compositor/mutter/mutter-shaped-texture.c
Executable file
466
src/compositor/mutter/mutter-shaped-texture.c
Executable file
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* shaped texture
|
||||
*
|
||||
* An actor to draw a texture clipped to a list of rectangles
|
||||
*
|
||||
* Authored By Neil Roberts <neil@linux.intel.com>
|
||||
*
|
||||
* Copyright (C) 2008 Intel Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "mutter-shaped-texture.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static void mutter_shaped_texture_dispose (GObject *object);
|
||||
static void mutter_shaped_texture_finalize (GObject *object);
|
||||
|
||||
static void mutter_shaped_texture_paint (ClutterActor *actor);
|
||||
static void mutter_shaped_texture_pick (ClutterActor *actor,
|
||||
const ClutterColor *color);
|
||||
|
||||
static void mutter_shaped_texture_dirty_mask (MutterShapedTexture *stex);
|
||||
|
||||
#ifdef HAVE_GLX_TEXTURE_PIXMAP
|
||||
G_DEFINE_TYPE (MutterShapedTexture, mutter_shaped_texture,
|
||||
CLUTTER_GLX_TYPE_TEXTURE_PIXMAP);
|
||||
#else /* HAVE_GLX_TEXTURE_PIXMAP */
|
||||
G_DEFINE_TYPE (MutterShapedTexture, mutter_shaped_texture,
|
||||
CLUTTER_X11_TYPE_TEXTURE_PIXMAP);
|
||||
#endif /* HAVE_GLX_TEXTURE_PIXMAP */
|
||||
|
||||
#define MUTTER_SHAPED_TEXTURE_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUTTER_TYPE_SHAPED_TEXTURE, \
|
||||
MutterShapedTexturePrivate))
|
||||
|
||||
struct _MutterShapedTexturePrivate
|
||||
{
|
||||
CoglHandle mask_texture;
|
||||
CoglHandle material;
|
||||
#if 1 /* see workaround comment in mutter_shaped_texture_paint */
|
||||
CoglHandle material_workaround;
|
||||
#endif
|
||||
|
||||
guint mask_width, mask_height;
|
||||
|
||||
GArray *rectangles;
|
||||
};
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_class_init (MutterShapedTextureClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
|
||||
|
||||
gobject_class->dispose = mutter_shaped_texture_dispose;
|
||||
gobject_class->finalize = mutter_shaped_texture_finalize;
|
||||
|
||||
actor_class->paint = mutter_shaped_texture_paint;
|
||||
actor_class->pick = mutter_shaped_texture_pick;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MutterShapedTexturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_init (MutterShapedTexture *self)
|
||||
{
|
||||
MutterShapedTexturePrivate *priv;
|
||||
|
||||
priv = self->priv = MUTTER_SHAPED_TEXTURE_GET_PRIVATE (self);
|
||||
|
||||
priv->rectangles = g_array_new (FALSE, FALSE, sizeof (XRectangle));
|
||||
|
||||
priv->mask_texture = COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_dispose (GObject *object)
|
||||
{
|
||||
MutterShapedTexture *self = (MutterShapedTexture *) object;
|
||||
MutterShapedTexturePrivate *priv = self->priv;
|
||||
|
||||
mutter_shaped_texture_dirty_mask (self);
|
||||
|
||||
if (priv->material != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_material_unref (priv->material);
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
}
|
||||
#if 1 /* see comment in mutter_shaped_texture_paint */
|
||||
if (priv->material_workaround != COGL_INVALID_HANDLE)
|
||||
{
|
||||
cogl_material_unref (priv->material_workaround);
|
||||
priv->material_workaround = COGL_INVALID_HANDLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
G_OBJECT_CLASS (mutter_shaped_texture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_finalize (GObject *object)
|
||||
{
|
||||
MutterShapedTexture *self = (MutterShapedTexture *) object;
|
||||
MutterShapedTexturePrivate *priv = self->priv;
|
||||
|
||||
g_array_free (priv->rectangles, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (mutter_shaped_texture_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_dirty_mask (MutterShapedTexture *stex)
|
||||
{
|
||||
MutterShapedTexturePrivate *priv = stex->priv;
|
||||
|
||||
if (priv->mask_texture != COGL_INVALID_HANDLE)
|
||||
{
|
||||
GLuint mask_gl_tex;
|
||||
GLenum mask_gl_target;
|
||||
|
||||
cogl_texture_get_gl_texture (priv->mask_texture,
|
||||
&mask_gl_tex, &mask_gl_target);
|
||||
|
||||
if (mask_gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||
glDeleteTextures (1, &mask_gl_tex);
|
||||
|
||||
cogl_texture_unref (priv->mask_texture);
|
||||
priv->mask_texture = COGL_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_ensure_mask (MutterShapedTexture *stex)
|
||||
{
|
||||
MutterShapedTexturePrivate *priv = stex->priv;
|
||||
CoglHandle paint_tex;
|
||||
guint tex_width, tex_height;
|
||||
|
||||
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
|
||||
|
||||
if (paint_tex == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
tex_width = cogl_texture_get_width (paint_tex);
|
||||
tex_height = cogl_texture_get_height (paint_tex);
|
||||
|
||||
/* If the mask texture we have was created for a different size then
|
||||
recreate it */
|
||||
if (priv->mask_texture != COGL_INVALID_HANDLE
|
||||
&& (priv->mask_width != tex_width || priv->mask_height != tex_height))
|
||||
mutter_shaped_texture_dirty_mask (stex);
|
||||
|
||||
/* If we don't have a mask texture yet then create one */
|
||||
if (priv->mask_texture == COGL_INVALID_HANDLE)
|
||||
{
|
||||
guchar *mask_data;
|
||||
const XRectangle *rect;
|
||||
GLenum paint_gl_target;
|
||||
|
||||
/* Create data for an empty image */
|
||||
mask_data = g_malloc0 (tex_width * tex_height);
|
||||
|
||||
/* Cut out a hole for each rectangle */
|
||||
for (rect = (XRectangle *) priv->rectangles->data
|
||||
+ priv->rectangles->len;
|
||||
rect-- > (XRectangle *) priv->rectangles->data;)
|
||||
{
|
||||
gint x1 = rect->x, x2 = x1 + rect->width;
|
||||
gint y1 = rect->y, y2 = y1 + rect->height;
|
||||
guchar *p;
|
||||
|
||||
/* Clip the rectangle to the size of the texture */
|
||||
x1 = CLAMP (x1, 0, (gint) tex_width - 1);
|
||||
x2 = CLAMP (x2, x1, (gint) tex_width);
|
||||
y1 = CLAMP (y1, 0, (gint) tex_height - 1);
|
||||
y2 = CLAMP (y2, y1, (gint) tex_height);
|
||||
|
||||
/* Fill the rectangle */
|
||||
for (p = mask_data + y1 * tex_width + x1;
|
||||
y1 < y2;
|
||||
y1++, p += tex_width)
|
||||
memset (p, 255, x2 - x1);
|
||||
}
|
||||
|
||||
cogl_texture_get_gl_texture (paint_tex, NULL, &paint_gl_target);
|
||||
|
||||
if (paint_gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||
{
|
||||
GLuint tex;
|
||||
|
||||
glGenTextures (1, &tex);
|
||||
glBindTexture (CGL_TEXTURE_RECTANGLE_ARB, tex);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, tex_width);
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
glTexImage2D (CGL_TEXTURE_RECTANGLE_ARB, 0,
|
||||
GL_ALPHA, tex_width, tex_height,
|
||||
0, GL_ALPHA, GL_UNSIGNED_BYTE, mask_data);
|
||||
|
||||
priv->mask_texture
|
||||
= cogl_texture_new_from_foreign (tex,
|
||||
CGL_TEXTURE_RECTANGLE_ARB,
|
||||
tex_width, tex_height,
|
||||
0, 0,
|
||||
COGL_PIXEL_FORMAT_A_8);
|
||||
}
|
||||
else
|
||||
priv->mask_texture = cogl_texture_new_from_data (tex_width, tex_height,
|
||||
-1, FALSE,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
tex_width,
|
||||
mask_data);
|
||||
|
||||
g_free (mask_data);
|
||||
|
||||
priv->mask_width = tex_width;
|
||||
priv->mask_height = tex_height;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_paint (ClutterActor *actor)
|
||||
{
|
||||
MutterShapedTexture *stex = (MutterShapedTexture *) actor;
|
||||
MutterShapedTexturePrivate *priv = stex->priv;
|
||||
CoglHandle paint_tex;
|
||||
guint tex_width, tex_height;
|
||||
ClutterActorBox alloc;
|
||||
CoglHandle material;
|
||||
#if 1 /* please see comment below about workaround */
|
||||
guint depth;
|
||||
#endif
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
|
||||
clutter_actor_realize (CLUTTER_ACTOR (stex));
|
||||
|
||||
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
|
||||
|
||||
tex_width = cogl_texture_get_width (paint_tex);
|
||||
tex_height = cogl_texture_get_height (paint_tex);
|
||||
|
||||
if (tex_width == 0 || tex_width == 0) /* no contents yet */
|
||||
return;
|
||||
|
||||
/* If there are no rectangles fallback to the regular paint
|
||||
method */
|
||||
if (priv->rectangles->len < 1)
|
||||
{
|
||||
CLUTTER_ACTOR_CLASS (mutter_shaped_texture_parent_class)
|
||||
->paint (actor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (paint_tex == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
mutter_shaped_texture_ensure_mask (stex);
|
||||
|
||||
if (priv->material == COGL_INVALID_HANDLE)
|
||||
{
|
||||
priv->material = cogl_material_new ();
|
||||
|
||||
/* Replace the RGB from layer 1 with the RGB from layer 0 */
|
||||
cogl_material_set_layer_combine_function
|
||||
(priv->material, 1,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_REPLACE);
|
||||
cogl_material_set_layer_combine_arg_src
|
||||
(priv->material, 1, 0,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
|
||||
COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS);
|
||||
|
||||
/* Modulate the alpha in layer 1 with the alpha from the
|
||||
previous layer */
|
||||
cogl_material_set_layer_combine_function
|
||||
(priv->material, 1,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE);
|
||||
cogl_material_set_layer_combine_arg_src
|
||||
(priv->material, 1, 0,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA,
|
||||
COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS);
|
||||
cogl_material_set_layer_combine_arg_src
|
||||
(priv->material, 1, 1,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA,
|
||||
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE);
|
||||
}
|
||||
material = priv->material;
|
||||
|
||||
#if 1
|
||||
/* This was added as a workaround. It seems that with the intel
|
||||
* drivers when multi-texturing using an RGB TFP texture, the
|
||||
* texture is actually setup internally as an RGBA texture, where
|
||||
* the alpha channel is mostly 0.0 so you only see a shimmer of the
|
||||
* window. This workaround forcibly defines the alpha channel as
|
||||
* 1.0. Maybe there is some clutter/cogl state that is interacting
|
||||
* with this that is being overlooked, but for now this seems to
|
||||
* work. */
|
||||
g_object_get (stex, "pixmap-depth", &depth, NULL);
|
||||
if (depth == 24)
|
||||
{
|
||||
if (priv->material_workaround == COGL_INVALID_HANDLE)
|
||||
{
|
||||
material = priv->material_workaround = cogl_material_new ();
|
||||
|
||||
/* Replace the RGB from layer 1 with the RGB from layer 0 */
|
||||
cogl_material_set_layer_combine_function
|
||||
(material, 1,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_REPLACE);
|
||||
cogl_material_set_layer_combine_arg_src
|
||||
(material, 1, 0,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
|
||||
COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS);
|
||||
|
||||
/* Use the alpha from layer 1 modulated with the alpha from
|
||||
the primary color */
|
||||
cogl_material_set_layer_combine_function
|
||||
(material, 1,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA,
|
||||
COGL_MATERIAL_LAYER_COMBINE_FUNC_MODULATE);
|
||||
cogl_material_set_layer_combine_arg_src
|
||||
(material, 1, 0,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA,
|
||||
COGL_MATERIAL_LAYER_COMBINE_SRC_PRIMARY_COLOR);
|
||||
cogl_material_set_layer_combine_arg_src
|
||||
(material, 1, 1,
|
||||
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_ALPHA,
|
||||
COGL_MATERIAL_LAYER_COMBINE_SRC_TEXTURE);
|
||||
}
|
||||
|
||||
material = priv->material_workaround;
|
||||
}
|
||||
#endif
|
||||
|
||||
cogl_material_set_layer (material, 0, paint_tex);
|
||||
cogl_material_set_layer (material, 1, priv->mask_texture);
|
||||
|
||||
{
|
||||
CoglColor color;
|
||||
cogl_color_set_from_4ub (&color, 255, 255, 255,
|
||||
clutter_actor_get_paint_opacity (actor));
|
||||
cogl_material_set_color (material, &color);
|
||||
}
|
||||
|
||||
cogl_set_source (material);
|
||||
|
||||
clutter_actor_get_allocation_box (actor, &alloc);
|
||||
cogl_rectangle (0, 0,
|
||||
CLUTTER_UNITS_TO_FLOAT (alloc.x2 - alloc.x1),
|
||||
CLUTTER_UNITS_TO_FLOAT (alloc.y2 - alloc.y1));
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_shaped_texture_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
MutterShapedTexture *stex = (MutterShapedTexture *) actor;
|
||||
MutterShapedTexturePrivate *priv = stex->priv;
|
||||
|
||||
/* If there are no rectangles then use the regular pick */
|
||||
if (priv->rectangles->len < 1)
|
||||
CLUTTER_ACTOR_CLASS (mutter_shaped_texture_parent_class)
|
||||
->pick (actor, color);
|
||||
else if (clutter_actor_should_pick_paint (actor))
|
||||
{
|
||||
CoglHandle paint_tex;
|
||||
ClutterActorBox alloc;
|
||||
guint tex_width, tex_height;
|
||||
|
||||
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
|
||||
|
||||
if (paint_tex == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
tex_width = cogl_texture_get_width (paint_tex);
|
||||
tex_height = cogl_texture_get_height (paint_tex);
|
||||
|
||||
if (tex_width == 0 || tex_width == 0) /* no contents yet */
|
||||
return;
|
||||
|
||||
mutter_shaped_texture_ensure_mask (stex);
|
||||
|
||||
cogl_set_source_color4ub (color->red, color->green, color->blue,
|
||||
color->alpha);
|
||||
|
||||
clutter_actor_get_allocation_box (actor, &alloc);
|
||||
|
||||
/* Paint the mask rectangle in the given color */
|
||||
cogl_set_source_texture (priv->mask_texture);
|
||||
cogl_rectangle_with_texture_coords (0, 0,
|
||||
CLUTTER_UNITS_TO_FLOAT (alloc.x2 - alloc.x1),
|
||||
CLUTTER_UNITS_TO_FLOAT (alloc.y2 - alloc.y1),
|
||||
0, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
mutter_shaped_texture_new (void)
|
||||
{
|
||||
ClutterActor *self = g_object_new (MUTTER_TYPE_SHAPED_TEXTURE, NULL);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
mutter_shaped_texture_clear_rectangles (MutterShapedTexture *stex)
|
||||
{
|
||||
MutterShapedTexturePrivate *priv;
|
||||
|
||||
g_return_if_fail (MUTTER_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
g_array_set_size (priv->rectangles, 0);
|
||||
mutter_shaped_texture_dirty_mask (stex);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||
}
|
||||
|
||||
void
|
||||
mutter_shaped_texture_add_rectangle (MutterShapedTexture *stex,
|
||||
const XRectangle *rect)
|
||||
{
|
||||
g_return_if_fail (MUTTER_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
mutter_shaped_texture_add_rectangles (stex, 1, rect);
|
||||
}
|
||||
|
||||
void
|
||||
mutter_shaped_texture_add_rectangles (MutterShapedTexture *stex,
|
||||
size_t num_rects,
|
||||
const XRectangle *rects)
|
||||
{
|
||||
MutterShapedTexturePrivate *priv;
|
||||
|
||||
g_return_if_fail (MUTTER_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
g_array_append_vals (priv->rectangles, rects, num_rects);
|
||||
|
||||
mutter_shaped_texture_dirty_mask (stex);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||
}
|
95
src/compositor/mutter/mutter-shaped-texture.h
Normal file
95
src/compositor/mutter/mutter-shaped-texture.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* shaped texture
|
||||
*
|
||||
* An actor to draw a texture clipped to a list of rectangles
|
||||
*
|
||||
* Authored By Neil Roberts <neil@linux.intel.com>
|
||||
*
|
||||
* Copyright (C) 2008 Intel Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __MUTTER_SHAPED_TEXTURE_H__
|
||||
#define __MUTTER_SHAPED_TEXTURE_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#ifdef HAVE_GLX_TEXTURE_PIXMAP
|
||||
#include <clutter/glx/clutter-glx.h>
|
||||
#endif /* HAVE_GLX_TEXTURE_PIXMAP */
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define MUTTER_TYPE_SHAPED_TEXTURE \
|
||||
(mutter_shaped_texture_get_type())
|
||||
#define MUTTER_SHAPED_TEXTURE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
||||
MUTTER_TYPE_SHAPED_TEXTURE, \
|
||||
MutterShapedTexture))
|
||||
#define MUTTER_SHAPED_TEXTURE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
||||
MUTTER_TYPE_SHAPED_TEXTURE, \
|
||||
MutterShapedTextureClass))
|
||||
#define MUTTER_IS_SHAPED_TEXTURE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
||||
MUTTER_TYPE_SHAPED_TEXTURE))
|
||||
#define MUTTER_IS_SHAPED_TEXTURE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
||||
MUTTER_TYPE_SHAPED_TEXTURE))
|
||||
#define MUTTER_SHAPED_TEXTURE_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
||||
MUTTER_TYPE_SHAPED_TEXTURE, \
|
||||
MutterShapedTextureClass))
|
||||
|
||||
typedef struct _MutterShapedTexture MutterShapedTexture;
|
||||
typedef struct _MutterShapedTextureClass MutterShapedTextureClass;
|
||||
typedef struct _MutterShapedTexturePrivate MutterShapedTexturePrivate;
|
||||
|
||||
struct _MutterShapedTextureClass
|
||||
{
|
||||
#ifdef HAVE_GLX_TEXTURE_PIXMAP
|
||||
ClutterGLXTexturePixmapClass parent_class;
|
||||
#else
|
||||
ClutterX11TexturePixmapClass parent_class;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _MutterShapedTexture
|
||||
{
|
||||
#ifdef HAVE_GLX_TEXTURE_PIXMAP
|
||||
ClutterGLXTexturePixmap parent;
|
||||
#else
|
||||
ClutterX11TexturePixmap parent;
|
||||
#endif
|
||||
|
||||
MutterShapedTexturePrivate *priv;
|
||||
};
|
||||
|
||||
GType mutter_shaped_texture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterActor *mutter_shaped_texture_new (void);
|
||||
|
||||
void mutter_shaped_texture_clear_rectangles (MutterShapedTexture *stex);
|
||||
|
||||
void mutter_shaped_texture_add_rectangle (MutterShapedTexture *stex,
|
||||
const XRectangle *rect);
|
||||
void mutter_shaped_texture_add_rectangles (MutterShapedTexture *stex,
|
||||
size_t num_rects,
|
||||
const XRectangle *rects);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MUTTER_SHAPED_TEXTURE_H__ */
|
22
src/compositor/mutter/plugins/Makefile.am
Normal file
22
src/compositor/mutter/plugins/Makefile.am
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
pkglibdir=@MUTTER_PLUGIN_DIR@
|
||||
|
||||
if WITH_CLUTTER
|
||||
|
||||
INCLUDES=@METACITY_CFLAGS@ -I $(top_srcdir)/src/include -DMETACITY_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMETACITY_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMETACITY_PKGDATADIR=\"$(pkgdatadir)\" -DMETACITY_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"metacity\" -DSN_API_NOT_YET_FROZEN=1 -DMETACITY_MAJOR_VERSION=$(METACITY_MAJOR_VERSION) -DMETACITY_MINOR_VERSION=$(METACITY_MINOR_VERSION) -DMETACITY_MICRO_VERSION=$(METACITY_MICRO_VERSION) -DMETACITY_CLUTTER_PLUGIN_API_VERSION=$(METACITY_CLUTTER_PLUGIN_API_VERSION) -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"
|
||||
|
||||
default_la_CFLAGS = -fPIC
|
||||
default_la_SOURCES = default.c
|
||||
default_la_LDFLAGS = -module -avoid-version -no-undefined
|
||||
default_la_LIBADD = @CLUTTER_LIBS@
|
||||
|
||||
pkglib_LTLIBRARIES = default.la
|
||||
|
||||
# post-install hook to remove the .la and .a files we are not interested in
|
||||
# (There is no way to stop libtool generating static libs locally, and we
|
||||
# cannot do this globally because of libmetacity-private.so).
|
||||
install-exec-hook:
|
||||
-rm $(DESTDIR)$(pkglibdir)/*.a
|
||||
-rm $(DESTDIR)$(pkglibdir)/*.la
|
||||
|
||||
endif
|
41
src/compositor/mutter/plugins/README
Normal file
41
src/compositor/mutter/plugins/README
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
Plugins implement effects associated with WM events, such as window map,
|
||||
minimizing, maximizing, unmaximizing, destruction and workspace switching. The
|
||||
plugin API is documented in src/include/compositor-clutter-plugin.h; in
|
||||
addition the simple plugin can be used as a reference implementation.
|
||||
|
||||
The API is intended to be generic, exposing no implementation details of the WM
|
||||
to the plugins; this will facilitate reuse without modification with another WM
|
||||
(there are plans to use the same plugin API with Matchbox 2).
|
||||
|
||||
Multiple plugins can implement the same effect and be loaded at the same time;
|
||||
however, stacking arbitrary effects in this way might not work as expected;
|
||||
this is particularly true of more complex effects, such as those for workspace
|
||||
switching.
|
||||
|
||||
Plugins are installed in ${prefix}/lib/metacity/plugins/clutter; from there the
|
||||
WM will load plugins listed in the clutter_plugins key in the Metacity gconf
|
||||
general preferences group. Each entry in preferences has the format
|
||||
|
||||
'name: optional parameters'
|
||||
|
||||
where 'name' is the name of the library without the .so suffix.
|
||||
|
||||
As noted above, additional parameters can be passed to the plugin via the
|
||||
preference key. In such case, the plugin name is immediately followed by a
|
||||
colon, separating it from the parameters. Two common parameters should be
|
||||
handled by all plugins:
|
||||
|
||||
'debug' indicates that the plugin is run in a debug mode (what exactly that
|
||||
means is left to the plugin to determine).
|
||||
|
||||
'disable' parameter indicates which effects within the plugin should be
|
||||
disabled; the format of the disable parameter is
|
||||
|
||||
'disable: effect1[, effect2];'
|
||||
|
||||
where effect1, etc., matches the effects listed in the
|
||||
compositor-clutter-plugin.h file (currently one of 'map', 'destroy',
|
||||
'maximize', 'unmaximize', 'switch-workspace'). Example 'disable:
|
||||
minimize, maximize;'.
|
||||
|
803
src/compositor/mutter/plugins/default.c
Normal file
803
src/compositor/mutter/plugins/default.c
Normal file
@@ -0,0 +1,803 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Intel Corp.
|
||||
*
|
||||
* Author: Tomas Frydrych <tf@linux.intel.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "mutter-plugin.h"
|
||||
|
||||
#include <libintl.h>
|
||||
#define _(x) dgettext (GETTEXT_PACKAGE, x)
|
||||
#define N_(x) x
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <gmodule.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DESTROY_TIMEOUT 250
|
||||
#define MINIMIZE_TIMEOUT 250
|
||||
#define MAXIMIZE_TIMEOUT 250
|
||||
#define MAP_TIMEOUT 250
|
||||
#define SWITCH_TIMEOUT 500
|
||||
|
||||
#define ACTOR_DATA_KEY "MCCP-Default-actor-data"
|
||||
|
||||
#define MUTTER_TYPE_DEFAULT_PLUGIN (mutter_default_plugin_get_type ())
|
||||
#define MUTTER_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_DEFAULT_PLUGIN, MutterDefaultPlugin))
|
||||
#define MUTTER_DEFAULT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_DEFAULT_PLUGIN, MutterDefaultPluginClass))
|
||||
#define MUTTER_IS_DEFAULT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_DEFAULT_PLUGIN_TYPE))
|
||||
#define MUTTER_IS_DEFAULT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_DEFAULT_PLUGIN))
|
||||
#define MUTTER_DEFAULT_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_DEFAULT_PLUGIN, MutterDefaultPluginClass))
|
||||
|
||||
#define MUTTER_DEFAULT_PLUGIN_GET_PRIVATE(obj) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUTTER_TYPE_DEFAULT_PLUGIN, MutterDefaultPluginPrivate))
|
||||
|
||||
typedef struct _MutterDefaultPlugin MutterDefaultPlugin;
|
||||
typedef struct _MutterDefaultPluginClass MutterDefaultPluginClass;
|
||||
typedef struct _MutterDefaultPluginPrivate MutterDefaultPluginPrivate;
|
||||
|
||||
struct _MutterDefaultPlugin
|
||||
{
|
||||
MutterPlugin parent;
|
||||
|
||||
MutterDefaultPluginPrivate *priv;
|
||||
};
|
||||
|
||||
struct _MutterDefaultPluginClass
|
||||
{
|
||||
MutterPluginClass parent_class;
|
||||
};
|
||||
|
||||
static GQuark actor_data_quark = 0;
|
||||
|
||||
static void minimize (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
static void map (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
static void destroy (MutterPlugin *plugin,
|
||||
MutterWindow *actor);
|
||||
static void maximize (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gint x, gint y, gint width, gint height);
|
||||
static void unmaximize (MutterPlugin *plugin,
|
||||
MutterWindow *actor,
|
||||
gint x, gint y, gint width, gint height);
|
||||
|
||||
static void switch_workspace (MutterPlugin *plugin,
|
||||
const GList **actors, gint from, gint to,
|
||||
MetaMotionDirection direction);
|
||||
|
||||
static void kill_effect (MutterPlugin *plugin,
|
||||
MutterWindow *actor, gulong event);
|
||||
|
||||
static const MutterPluginInfo * plugin_info (MutterPlugin *plugin);
|
||||
|
||||
MUTTER_PLUGIN_DECLARE(MutterDefaultPlugin, mutter_default_plugin);
|
||||
|
||||
/*
|
||||
* Plugin private data that we store in the .plugin_private member.
|
||||
*/
|
||||
struct _MutterDefaultPluginPrivate
|
||||
{
|
||||
/* Valid only when switch_workspace effect is in progress */
|
||||
ClutterTimeline *tml_switch_workspace1;
|
||||
ClutterTimeline *tml_switch_workspace2;
|
||||
GList **actors;
|
||||
ClutterActor *desktop1;
|
||||
ClutterActor *desktop2;
|
||||
|
||||
MutterPluginInfo info;
|
||||
|
||||
gboolean debug_mode : 1;
|
||||
};
|
||||
|
||||
/*
|
||||
* Per actor private data we attach to each actor.
|
||||
*/
|
||||
typedef struct _ActorPrivate
|
||||
{
|
||||
ClutterActor *orig_parent;
|
||||
|
||||
ClutterTimeline *tml_minimize;
|
||||
ClutterTimeline *tml_maximize;
|
||||
ClutterTimeline *tml_destroy;
|
||||
ClutterTimeline *tml_map;
|
||||
|
||||
gboolean is_minimized : 1;
|
||||
gboolean is_maximized : 1;
|
||||
} ActorPrivate;
|
||||
|
||||
/* callback data for when animations complete */
|
||||
typedef struct
|
||||
{
|
||||
ClutterActor *actor;
|
||||
MutterPlugin *plugin;
|
||||
} EffectCompleteData;
|
||||
|
||||
|
||||
static void
|
||||
mutter_default_plugin_dispose (GObject *object)
|
||||
{
|
||||
/* MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (object)->priv;
|
||||
*/
|
||||
G_OBJECT_CLASS (mutter_default_plugin_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (mutter_default_plugin_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_constructed (GObject *object)
|
||||
{
|
||||
MutterPlugin *plugin = MUTTER_PLUGIN (object);
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (object)->priv;
|
||||
|
||||
guint destroy_timeout = DESTROY_TIMEOUT;
|
||||
guint minimize_timeout = MINIMIZE_TIMEOUT;
|
||||
guint maximize_timeout = MAXIMIZE_TIMEOUT;
|
||||
guint map_timeout = MAP_TIMEOUT;
|
||||
guint switch_timeout = SWITCH_TIMEOUT;
|
||||
|
||||
if (mutter_plugin_debug_mode (plugin))
|
||||
{
|
||||
g_debug ("Plugin %s: Entering debug mode.", priv->info.name);
|
||||
|
||||
priv->debug_mode = TRUE;
|
||||
|
||||
/*
|
||||
* Double the effect duration to make them easier to observe.
|
||||
*/
|
||||
destroy_timeout *= 2;
|
||||
minimize_timeout *= 2;
|
||||
maximize_timeout *= 2;
|
||||
map_timeout *= 2;
|
||||
switch_timeout *= 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_class_init (MutterDefaultPluginClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
MutterPluginClass *plugin_class = MUTTER_PLUGIN_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = mutter_default_plugin_finalize;
|
||||
gobject_class->dispose = mutter_default_plugin_dispose;
|
||||
gobject_class->constructed = mutter_default_plugin_constructed;
|
||||
gobject_class->set_property = mutter_default_plugin_set_property;
|
||||
gobject_class->get_property = mutter_default_plugin_get_property;
|
||||
|
||||
plugin_class->map = map;
|
||||
plugin_class->minimize = minimize;
|
||||
plugin_class->maximize = maximize;
|
||||
plugin_class->unmaximize = unmaximize;
|
||||
plugin_class->destroy = destroy;
|
||||
plugin_class->switch_workspace = switch_workspace;
|
||||
plugin_class->kill_effect = kill_effect;
|
||||
plugin_class->plugin_info = plugin_info;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (MutterDefaultPluginPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
mutter_default_plugin_init (MutterDefaultPlugin *self)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv;
|
||||
|
||||
self->priv = priv = MUTTER_DEFAULT_PLUGIN_GET_PRIVATE (self);
|
||||
|
||||
priv->info.name = "Default Effects";
|
||||
priv->info.version = "0.1";
|
||||
priv->info.author = "Intel Corp.";
|
||||
priv->info.license = "GPL";
|
||||
priv->info.description = "This is an example of a plugin implementation.";
|
||||
}
|
||||
|
||||
/*
|
||||
* Actor private data accessor
|
||||
*/
|
||||
static void
|
||||
free_actor_private (gpointer data)
|
||||
{
|
||||
if (G_LIKELY (data != NULL))
|
||||
g_slice_free (ActorPrivate, data);
|
||||
}
|
||||
|
||||
static ActorPrivate *
|
||||
get_actor_private (MutterWindow *actor)
|
||||
{
|
||||
ActorPrivate *priv = g_object_get_qdata (G_OBJECT (actor), actor_data_quark);
|
||||
|
||||
if (G_UNLIKELY (actor_data_quark == 0))
|
||||
actor_data_quark = g_quark_from_static_string (ACTOR_DATA_KEY);
|
||||
|
||||
if (G_UNLIKELY (!priv))
|
||||
{
|
||||
priv = g_slice_new0 (ActorPrivate);
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (actor),
|
||||
actor_data_quark, priv,
|
||||
free_actor_private);
|
||||
}
|
||||
|
||||
return priv;
|
||||
}
|
||||
|
||||
typedef struct SwitchWorkspaceData
|
||||
{
|
||||
MutterPlugin *plugin;
|
||||
const GList **actors;
|
||||
} SwitchWorkspaceData;
|
||||
|
||||
static void
|
||||
on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
|
||||
{
|
||||
SwitchWorkspaceData *sw_data = data;
|
||||
MutterPlugin *plugin = sw_data->plugin;
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
GList *l = *((GList**)sw_data->actors);
|
||||
MutterWindow *actor_for_cb = l->data;
|
||||
|
||||
while (l)
|
||||
{
|
||||
ClutterActor *a = l->data;
|
||||
MutterWindow *mc_window = MUTTER_WINDOW (a);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
if (apriv->orig_parent)
|
||||
{
|
||||
clutter_actor_reparent (a, apriv->orig_parent);
|
||||
apriv->orig_parent = NULL;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
clutter_actor_destroy (priv->desktop1);
|
||||
clutter_actor_destroy (priv->desktop2);
|
||||
|
||||
priv->actors = NULL;
|
||||
priv->tml_switch_workspace1 = NULL;
|
||||
priv->tml_switch_workspace2 = NULL;
|
||||
priv->desktop1 = NULL;
|
||||
priv->desktop2 = NULL;
|
||||
|
||||
g_free (data);
|
||||
|
||||
mutter_plugin_effect_completed (plugin, actor_for_cb,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
}
|
||||
|
||||
static void
|
||||
switch_workspace (MutterPlugin *plugin,
|
||||
const GList **actors, gint from, gint to,
|
||||
MetaMotionDirection direction)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
GList *l;
|
||||
gint n_workspaces;
|
||||
ClutterActor *workspace0 = clutter_group_new ();
|
||||
ClutterActor *workspace1 = clutter_group_new ();
|
||||
ClutterActor *stage;
|
||||
int screen_width, screen_height;
|
||||
MetaScreen *screen = mutter_plugin_get_screen (plugin);
|
||||
SwitchWorkspaceData *sw_data = g_new (SwitchWorkspaceData, 1);
|
||||
ClutterAnimation *animation;
|
||||
|
||||
sw_data->plugin = plugin;
|
||||
sw_data->actors = actors;
|
||||
|
||||
stage = mutter_plugin_get_stage (plugin);
|
||||
|
||||
mutter_plugin_query_screen_size (plugin,
|
||||
&screen_width,
|
||||
&screen_height);
|
||||
clutter_actor_set_anchor_point (workspace1,
|
||||
screen_width,
|
||||
screen_height);
|
||||
clutter_actor_set_position (workspace1,
|
||||
screen_width,
|
||||
screen_height);
|
||||
|
||||
clutter_actor_set_scale (workspace1, 0.0, 0.0);
|
||||
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace1);
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), workspace0);
|
||||
|
||||
if (from == to)
|
||||
{
|
||||
mutter_plugin_effect_completed (plugin, NULL,
|
||||
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||
return;
|
||||
}
|
||||
|
||||
n_workspaces = meta_screen_get_n_workspaces (screen);
|
||||
|
||||
l = g_list_last (*((GList**) actors));
|
||||
|
||||
while (l)
|
||||
{
|
||||
MutterWindow *mc_window = l->data;
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
ClutterActor *window = CLUTTER_ACTOR (mc_window);
|
||||
gint win_workspace;
|
||||
|
||||
win_workspace = mutter_window_get_workspace (mc_window);
|
||||
|
||||
if (win_workspace == to || win_workspace == from)
|
||||
{
|
||||
gint x, y;
|
||||
guint w, h;
|
||||
|
||||
clutter_actor_get_position (window, &x, &y);
|
||||
clutter_actor_get_size (window, &w, &h);
|
||||
|
||||
apriv->orig_parent = clutter_actor_get_parent (window);
|
||||
|
||||
clutter_actor_reparent (window,
|
||||
win_workspace == to ? workspace1 : workspace0);
|
||||
clutter_actor_show_all (window);
|
||||
clutter_actor_raise_top (window);
|
||||
}
|
||||
else if (win_workspace < 0)
|
||||
{
|
||||
/* Sticky window */
|
||||
apriv->orig_parent = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Window on some other desktop */
|
||||
clutter_actor_hide (window);
|
||||
apriv->orig_parent = NULL;
|
||||
}
|
||||
|
||||
l = l->prev;
|
||||
}
|
||||
|
||||
priv->actors = (GList **)actors;
|
||||
priv->desktop1 = workspace0;
|
||||
priv->desktop2 = workspace1;
|
||||
|
||||
animation = clutter_actor_animate (workspace0, CLUTTER_EASE_IN_SINE,
|
||||
SWITCH_TIMEOUT,
|
||||
"scale-x", 1.0,
|
||||
"scale-y", 1.0,
|
||||
NULL);
|
||||
priv->tml_switch_workspace1 = clutter_animation_get_timeline (animation);
|
||||
g_signal_connect (priv->tml_switch_workspace1,
|
||||
"completed",
|
||||
G_CALLBACK (on_switch_workspace_effect_complete),
|
||||
sw_data);
|
||||
|
||||
animation = clutter_actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
|
||||
SWITCH_TIMEOUT,
|
||||
"scale-x", 0.0,
|
||||
"scale-y", 0.0,
|
||||
NULL);
|
||||
priv->tml_switch_workspace2 = clutter_animation_get_timeline (animation);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Minimize effect completion callback; this function restores actor state, and
|
||||
* calls the manager callback function.
|
||||
*/
|
||||
static void
|
||||
on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
|
||||
{
|
||||
/*
|
||||
* Must reverse the effect of the effect; must hide it first to ensure
|
||||
* that the restoration will not be visible.
|
||||
*/
|
||||
MutterPlugin *plugin = data->plugin;
|
||||
ActorPrivate *apriv;
|
||||
MutterWindow *mc_window = MUTTER_WINDOW (data->actor);
|
||||
|
||||
apriv = get_actor_private (MUTTER_WINDOW (data->actor));
|
||||
apriv->tml_minimize = NULL;
|
||||
|
||||
clutter_actor_hide (data->actor);
|
||||
|
||||
/* FIXME - we shouldn't assume the original scale, it should be saved
|
||||
* at the start of the effect */
|
||||
clutter_actor_set_scale (data->actor, 1.0, 1.0);
|
||||
clutter_actor_move_anchor_point_from_gravity (data->actor,
|
||||
CLUTTER_GRAVITY_NORTH_WEST);
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple minimize handler: it applies a scale effect (which must be reversed on
|
||||
* completion).
|
||||
*/
|
||||
static void
|
||||
minimize (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
apriv->is_minimized = TRUE;
|
||||
|
||||
clutter_actor_move_anchor_point_from_gravity (actor,
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
animation = clutter_actor_animate (actor,
|
||||
CLUTTER_EASE_IN_SINE,
|
||||
MINIMIZE_TIMEOUT,
|
||||
"scale-x", 0.0,
|
||||
"scale-y", 0.0,
|
||||
NULL);
|
||||
apriv->tml_minimize = clutter_animation_get_timeline (animation);
|
||||
data->plugin = plugin;
|
||||
data->actor = actor;
|
||||
g_signal_connect (apriv->tml_minimize, "completed",
|
||||
G_CALLBACK (on_minimize_effect_complete),
|
||||
data);
|
||||
|
||||
}
|
||||
else
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Minimize effect completion callback; this function restores actor state, and
|
||||
* calls the manager callback function.
|
||||
*/
|
||||
static void
|
||||
on_maximize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
|
||||
{
|
||||
/*
|
||||
* Must reverse the effect of the effect.
|
||||
*/
|
||||
MutterPlugin * plugin = data->plugin;
|
||||
MutterWindow *mc_window = MUTTER_WINDOW (data->actor);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
apriv->tml_maximize = NULL;
|
||||
|
||||
/* FIXME - don't assume the original scale was 1.0 */
|
||||
clutter_actor_set_scale (data->actor, 1.0, 1.0);
|
||||
clutter_actor_move_anchor_point_from_gravity (data->actor,
|
||||
CLUTTER_GRAVITY_NORTH_WEST);
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Nature of Maximize operation is such that it is difficult to do a visual
|
||||
* effect that would work well. Scaling, the obvious effect, does not work that
|
||||
* well, because at the end of the effect we end up with window content bigger
|
||||
* and differently laid out than in the real window; this is a proof concept.
|
||||
*
|
||||
* (Something like a sound would be more appropriate.)
|
||||
*/
|
||||
static void
|
||||
maximize (MutterPlugin *plugin,
|
||||
MutterWindow *mc_window,
|
||||
gint end_x, gint end_y, gint end_width, gint end_height)
|
||||
{
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
gdouble scale_x = 1.0;
|
||||
gdouble scale_y = 1.0;
|
||||
gint anchor_x = 0;
|
||||
gint anchor_y = 0;
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
guint width, height;
|
||||
gint x, y;
|
||||
|
||||
apriv->is_maximized = TRUE;
|
||||
|
||||
clutter_actor_get_size (actor, &width, &height);
|
||||
clutter_actor_get_position (actor, &x, &y);
|
||||
|
||||
/*
|
||||
* Work out the scale and anchor point so that the window is expanding
|
||||
* smoothly into the target size.
|
||||
*/
|
||||
scale_x = (gdouble)end_width / (gdouble) width;
|
||||
scale_y = (gdouble)end_height / (gdouble) height;
|
||||
|
||||
anchor_x = (gdouble)(x - end_x)*(gdouble)width /
|
||||
((gdouble)(end_width - width));
|
||||
anchor_y = (gdouble)(y - end_y)*(gdouble)height /
|
||||
((gdouble)(end_height - height));
|
||||
|
||||
clutter_actor_move_anchor_point (actor, anchor_x, anchor_y);
|
||||
|
||||
animation = clutter_actor_animate (actor,
|
||||
CLUTTER_EASE_IN_SINE,
|
||||
MAXIMIZE_TIMEOUT,
|
||||
"scale-x", scale_x,
|
||||
"scale-y", scale_y,
|
||||
NULL);
|
||||
apriv->tml_maximize = clutter_animation_get_timeline (animation);
|
||||
data->plugin = plugin;
|
||||
data->actor = actor;
|
||||
g_signal_connect (apriv->tml_maximize, "completed",
|
||||
G_CALLBACK (on_maximize_effect_complete),
|
||||
data);
|
||||
return;
|
||||
}
|
||||
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAXIMIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* See comments on the maximize() function.
|
||||
*
|
||||
* (Just a skeleton code.)
|
||||
*/
|
||||
static void
|
||||
unmaximize (MutterPlugin *plugin,
|
||||
MutterWindow *mc_window,
|
||||
gint end_x, gint end_y, gint end_width, gint end_height)
|
||||
{
|
||||
MetaCompWindowType type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
apriv->is_maximized = FALSE;
|
||||
}
|
||||
|
||||
/* Do this conditionally, if the effect requires completion callback. */
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_UNMAXIMIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_map_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
|
||||
{
|
||||
/*
|
||||
* Must reverse the effect of the effect.
|
||||
*/
|
||||
MutterPlugin *plugin = data->plugin;
|
||||
MutterWindow *mc_window = MUTTER_WINDOW (data->actor);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
apriv->tml_map = NULL;
|
||||
|
||||
clutter_actor_move_anchor_point_from_gravity (data->actor,
|
||||
CLUTTER_GRAVITY_NORTH_WEST);
|
||||
|
||||
/* Now notify the manager that we are done with this effect */
|
||||
mutter_plugin_effect_completed (plugin, mc_window, MUTTER_PLUGIN_MAP);
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple map handler: it applies a scale effect which must be reversed on
|
||||
* completion).
|
||||
*/
|
||||
static void
|
||||
map (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
clutter_actor_move_anchor_point_from_gravity (actor,
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
clutter_actor_set_scale (actor, 0.0, 0.0);
|
||||
clutter_actor_show (actor);
|
||||
|
||||
animation = clutter_actor_animate (actor,
|
||||
CLUTTER_EASE_IN_SINE,
|
||||
MAP_TIMEOUT,
|
||||
"scale-x", 1.0,
|
||||
"scale-y", 1.0,
|
||||
NULL);
|
||||
apriv->tml_map = clutter_animation_get_timeline (animation);
|
||||
data->actor = actor;
|
||||
data->plugin = plugin;
|
||||
g_signal_connect (apriv->tml_map, "completed",
|
||||
G_CALLBACK (on_map_effect_complete),
|
||||
data);
|
||||
|
||||
apriv->is_minimized = FALSE;
|
||||
|
||||
}
|
||||
else
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_MAP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy effect completion callback; this is a simple effect that requires no
|
||||
* further action than notifying the manager that the effect is completed.
|
||||
*/
|
||||
static void
|
||||
on_destroy_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
|
||||
{
|
||||
MutterPlugin *plugin = data->plugin;
|
||||
MutterWindow *mc_window = MUTTER_WINDOW (data->actor);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
apriv->tml_destroy = NULL;
|
||||
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_DESTROY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple TV-out like effect.
|
||||
*/
|
||||
static void
|
||||
destroy (MutterPlugin *plugin, MutterWindow *mc_window)
|
||||
{
|
||||
MetaCompWindowType type;
|
||||
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
|
||||
|
||||
type = mutter_window_get_window_type (mc_window);
|
||||
|
||||
if (type == META_COMP_WINDOW_NORMAL)
|
||||
{
|
||||
ClutterAnimation *animation;
|
||||
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
|
||||
ActorPrivate *apriv = get_actor_private (mc_window);
|
||||
|
||||
clutter_actor_move_anchor_point_from_gravity (actor,
|
||||
CLUTTER_GRAVITY_CENTER);
|
||||
|
||||
animation = clutter_actor_animate (actor,
|
||||
CLUTTER_EASE_IN_SINE,
|
||||
DESTROY_TIMEOUT,
|
||||
"scale-x", 0.0,
|
||||
"scale-y", 1.0,
|
||||
NULL);
|
||||
apriv->tml_destroy = clutter_animation_get_timeline (animation);
|
||||
data->plugin = plugin;
|
||||
data->actor = actor;
|
||||
g_signal_connect (apriv->tml_destroy, "completed",
|
||||
G_CALLBACK (on_destroy_effect_complete),
|
||||
data);
|
||||
}
|
||||
else
|
||||
mutter_plugin_effect_completed (plugin, mc_window,
|
||||
MUTTER_PLUGIN_DESTROY);
|
||||
}
|
||||
|
||||
static void
|
||||
kill_effect (MutterPlugin *plugin, MutterWindow *mc_window, gulong event)
|
||||
{
|
||||
ActorPrivate *apriv;
|
||||
|
||||
if (event & MUTTER_PLUGIN_SWITCH_WORKSPACE)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
|
||||
if (priv->tml_switch_workspace1)
|
||||
{
|
||||
clutter_timeline_stop (priv->tml_switch_workspace1);
|
||||
clutter_timeline_stop (priv->tml_switch_workspace2);
|
||||
g_signal_emit_by_name (priv->tml_switch_workspace1, "completed", NULL);
|
||||
}
|
||||
|
||||
if (!(event & ~MUTTER_PLUGIN_SWITCH_WORKSPACE))
|
||||
{
|
||||
/* Workspace switch only, nothing more to do */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
apriv = get_actor_private (mc_window);
|
||||
|
||||
if ((event & MUTTER_PLUGIN_MINIMIZE) && apriv->tml_minimize)
|
||||
{
|
||||
clutter_timeline_stop (apriv->tml_minimize);
|
||||
g_signal_emit_by_name (apriv->tml_minimize, "completed", NULL);
|
||||
}
|
||||
|
||||
if ((event & MUTTER_PLUGIN_MAXIMIZE) && apriv->tml_maximize)
|
||||
{
|
||||
clutter_timeline_stop (apriv->tml_maximize);
|
||||
g_signal_emit_by_name (apriv->tml_maximize, "completed", NULL);
|
||||
}
|
||||
|
||||
if ((event & MUTTER_PLUGIN_MAP) && apriv->tml_map)
|
||||
{
|
||||
clutter_timeline_stop (apriv->tml_map);
|
||||
g_signal_emit_by_name (apriv->tml_map, "completed", NULL);
|
||||
}
|
||||
|
||||
if ((event & MUTTER_PLUGIN_DESTROY) && apriv->tml_destroy)
|
||||
{
|
||||
clutter_timeline_stop (apriv->tml_destroy);
|
||||
g_signal_emit_by_name (apriv->tml_destroy, "completed", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static const MutterPluginInfo *
|
||||
plugin_info (MutterPlugin *plugin)
|
||||
{
|
||||
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
|
||||
|
||||
return &priv->info;
|
||||
}
|
610
src/compositor/mutter/tidy/tidy-texture-frame.c
Normal file
610
src/compositor/mutter/tidy/tidy-texture-frame.c
Normal file
@@ -0,0 +1,610 @@
|
||||
/* tidy-texture-frame.h: Expandible texture actor
|
||||
*
|
||||
* Copyright (C) 2007 OpenedHand
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:tidy-texture-frame
|
||||
* @short_description: Stretch a texture to fit the entire allocation
|
||||
*
|
||||
* #TidyTextureFrame
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "tidy-texture-frame.h"
|
||||
|
||||
#define TIDY_PARAM_READABLE \
|
||||
(G_PARAM_READABLE | \
|
||||
G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)
|
||||
|
||||
#define TIDY_PARAM_READWRITE \
|
||||
(G_PARAM_READABLE | G_PARAM_WRITABLE | \
|
||||
G_PARAM_STATIC_NICK | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_PARENT_TEXTURE,
|
||||
|
||||
PROP_LEFT,
|
||||
PROP_TOP,
|
||||
PROP_RIGHT,
|
||||
PROP_BOTTOM
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (TidyTextureFrame, tidy_texture_frame, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
#define TIDY_TEXTURE_FRAME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFramePrivate))
|
||||
|
||||
struct _TidyTextureFramePrivate
|
||||
{
|
||||
ClutterTexture *parent_texture;
|
||||
|
||||
gfloat left;
|
||||
gfloat top;
|
||||
gfloat right;
|
||||
gfloat bottom;
|
||||
|
||||
CoglHandle material;
|
||||
};
|
||||
|
||||
static void
|
||||
tidy_texture_frame_get_preferred_width (ClutterActor *self,
|
||||
ClutterUnit for_height,
|
||||
ClutterUnit *min_width_p,
|
||||
ClutterUnit *natural_width_p)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
|
||||
if (G_UNLIKELY (priv->parent_texture == NULL))
|
||||
{
|
||||
if (min_width_p)
|
||||
*min_width_p = 0;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterActorClass *klass;
|
||||
|
||||
/* by directly querying the parent texture's class implementation
|
||||
* we are going around any override mechanism the parent texture
|
||||
* might have in place, and we ask directly for the original
|
||||
* preferred width
|
||||
*/
|
||||
klass = CLUTTER_ACTOR_GET_CLASS (priv->parent_texture);
|
||||
klass->get_preferred_width (CLUTTER_ACTOR (priv->parent_texture),
|
||||
for_height,
|
||||
min_width_p,
|
||||
natural_width_p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_get_preferred_height (ClutterActor *self,
|
||||
ClutterUnit for_width,
|
||||
ClutterUnit *min_height_p,
|
||||
ClutterUnit *natural_height_p)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
|
||||
if (G_UNLIKELY (priv->parent_texture == NULL))
|
||||
{
|
||||
if (min_height_p)
|
||||
*min_height_p = 0;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterActorClass *klass;
|
||||
|
||||
/* by directly querying the parent texture's class implementation
|
||||
* we are going around any override mechanism the parent texture
|
||||
* might have in place, and we ask directly for the original
|
||||
* preferred height
|
||||
*/
|
||||
klass = CLUTTER_ACTOR_GET_CLASS (priv->parent_texture);
|
||||
klass->get_preferred_height (CLUTTER_ACTOR (priv->parent_texture),
|
||||
for_width,
|
||||
min_height_p,
|
||||
natural_height_p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_realize (ClutterActor *self)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
|
||||
if (priv->material != COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
priv->material = cogl_material_new ();
|
||||
|
||||
CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_unrealize (ClutterActor *self)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
|
||||
if (priv->material == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
cogl_material_unref (priv->material);
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
|
||||
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_paint (ClutterActor *self)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (self)->priv;
|
||||
CoglHandle cogl_texture = COGL_INVALID_HANDLE;
|
||||
ClutterActorBox box = { 0, };
|
||||
gfloat width, height;
|
||||
gfloat tex_width, tex_height;
|
||||
gfloat ex, ey;
|
||||
gfloat tx1, ty1, tx2, ty2;
|
||||
guint8 opacity;
|
||||
|
||||
/* no need to paint stuff if we don't have a texture */
|
||||
if (G_UNLIKELY (priv->parent_texture == NULL))
|
||||
return;
|
||||
|
||||
/* parent texture may have been hidden, so need to make sure it gets
|
||||
* realized
|
||||
*/
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (priv->parent_texture))
|
||||
clutter_actor_realize (CLUTTER_ACTOR (priv->parent_texture));
|
||||
|
||||
cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture);
|
||||
if (cogl_texture == COGL_INVALID_HANDLE)
|
||||
return;
|
||||
|
||||
tex_width = cogl_texture_get_width (cogl_texture);
|
||||
tex_height = cogl_texture_get_height (cogl_texture);
|
||||
|
||||
clutter_actor_get_allocation_box (self, &box);
|
||||
width = box.x2 - box.x1;
|
||||
height = box.y2 - box.y1;
|
||||
|
||||
tx1 = priv->left / tex_width;
|
||||
tx2 = (tex_width - priv->right) / tex_width;
|
||||
ty1 = priv->top / tex_height;
|
||||
ty2 = (tex_height - priv->bottom) / tex_height;
|
||||
|
||||
ex = width - priv->right;
|
||||
if (ex < 0)
|
||||
ex = priv->right; /* FIXME ? */
|
||||
|
||||
ey = height - priv->bottom;
|
||||
if (ey < 0)
|
||||
ey = priv->bottom; /* FIXME ? */
|
||||
|
||||
opacity = clutter_actor_get_paint_opacity (self);
|
||||
|
||||
g_assert (priv->material != COGL_INVALID_HANDLE);
|
||||
|
||||
/* set the source material using the parent texture's COGL handle */
|
||||
cogl_material_set_color4ub (priv->material, 255, 255, 255, opacity);
|
||||
cogl_material_set_layer (priv->material, 0, cogl_texture);
|
||||
cogl_set_source (priv->material);
|
||||
|
||||
/* top left corner */
|
||||
cogl_rectangle_with_texture_coords (0, 0, priv->left, priv->top,
|
||||
0.0, 0.0,
|
||||
tx1, ty1);
|
||||
|
||||
/* top middle */
|
||||
cogl_rectangle_with_texture_coords (priv->left, 0, ex, priv->top,
|
||||
tx1, 0.0,
|
||||
tx2, ty1);
|
||||
|
||||
/* top right */
|
||||
cogl_rectangle_with_texture_coords (ex, 0, width, priv->top,
|
||||
tx2, 0.0,
|
||||
1.0, ty1);
|
||||
|
||||
/* mid left */
|
||||
cogl_rectangle_with_texture_coords (0, priv->top, priv->left, ey,
|
||||
0.0, ty1,
|
||||
tx1, ty2);
|
||||
|
||||
/* center */
|
||||
cogl_rectangle_with_texture_coords (priv->left, priv->top, ex, ey,
|
||||
tx1, ty1,
|
||||
tx2, ty2);
|
||||
|
||||
/* mid right */
|
||||
cogl_rectangle_with_texture_coords (ex, priv->top, width, ey,
|
||||
tx2, ty1,
|
||||
1.0, ty2);
|
||||
|
||||
/* bottom left */
|
||||
cogl_rectangle_with_texture_coords (0, ey, priv->left, height,
|
||||
0.0, ty2,
|
||||
tx1, 1.0);
|
||||
|
||||
/* bottom center */
|
||||
cogl_rectangle_with_texture_coords (priv->left, ey, ex, height,
|
||||
tx1, ty2,
|
||||
tx2, 1.0);
|
||||
|
||||
/* bottom right */
|
||||
cogl_rectangle_with_texture_coords (ex, ey, width, height,
|
||||
tx2, ty2,
|
||||
1.0, 1.0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tidy_texture_frame_set_frame_internal (TidyTextureFrame *frame,
|
||||
gfloat left,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = frame->priv;
|
||||
GObject *gobject = G_OBJECT (frame);
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_object_freeze_notify (gobject);
|
||||
|
||||
if (priv->top != top)
|
||||
{
|
||||
priv->top = top;
|
||||
g_object_notify (gobject, "top");
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (priv->right != right)
|
||||
{
|
||||
priv->right = right;
|
||||
g_object_notify (gobject, "right");
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (priv->bottom != bottom)
|
||||
{
|
||||
priv->bottom = bottom;
|
||||
g_object_notify (gobject, "bottom");
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (priv->left != left)
|
||||
{
|
||||
priv->left = left;
|
||||
g_object_notify (gobject, "left");
|
||||
changed = TRUE;
|
||||
}
|
||||
|
||||
if (changed && CLUTTER_ACTOR_IS_VISIBLE (frame))
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (frame));
|
||||
|
||||
g_object_thaw_notify (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TidyTextureFrame *frame = TIDY_TEXTURE_FRAME (gobject);
|
||||
TidyTextureFramePrivate *priv = frame->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PARENT_TEXTURE:
|
||||
tidy_texture_frame_set_parent_texture (frame,
|
||||
g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_TOP:
|
||||
tidy_texture_frame_set_frame_internal (frame,
|
||||
priv->left,
|
||||
g_value_get_float (value),
|
||||
priv->right,
|
||||
priv->bottom);
|
||||
break;
|
||||
|
||||
case PROP_RIGHT:
|
||||
tidy_texture_frame_set_frame_internal (frame,
|
||||
priv->top,
|
||||
g_value_get_float (value),
|
||||
priv->bottom,
|
||||
priv->left);
|
||||
break;
|
||||
|
||||
case PROP_BOTTOM:
|
||||
tidy_texture_frame_set_frame_internal (frame,
|
||||
priv->top,
|
||||
priv->right,
|
||||
g_value_get_float (value),
|
||||
priv->left);
|
||||
break;
|
||||
|
||||
case PROP_LEFT:
|
||||
tidy_texture_frame_set_frame_internal (frame,
|
||||
priv->top,
|
||||
priv->right,
|
||||
priv->bottom,
|
||||
g_value_get_float (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (gobject)->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PARENT_TEXTURE:
|
||||
g_value_set_object (value, priv->parent_texture);
|
||||
break;
|
||||
|
||||
case PROP_LEFT:
|
||||
g_value_set_float (value, priv->left);
|
||||
break;
|
||||
|
||||
case PROP_TOP:
|
||||
g_value_set_float (value, priv->top);
|
||||
break;
|
||||
|
||||
case PROP_RIGHT:
|
||||
g_value_set_float (value, priv->right);
|
||||
break;
|
||||
|
||||
case PROP_BOTTOM:
|
||||
g_value_set_float (value, priv->bottom);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_dispose (GObject *gobject)
|
||||
{
|
||||
TidyTextureFramePrivate *priv = TIDY_TEXTURE_FRAME (gobject)->priv;
|
||||
|
||||
if (priv->parent_texture)
|
||||
{
|
||||
g_object_unref (priv->parent_texture);
|
||||
priv->parent_texture = NULL;
|
||||
}
|
||||
|
||||
if (priv->material)
|
||||
{
|
||||
cogl_material_unref (priv->material);
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (tidy_texture_frame_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_class_init (TidyTextureFrameClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (TidyTextureFramePrivate));
|
||||
|
||||
actor_class->get_preferred_width =
|
||||
tidy_texture_frame_get_preferred_width;
|
||||
actor_class->get_preferred_height =
|
||||
tidy_texture_frame_get_preferred_height;
|
||||
actor_class->realize = tidy_texture_frame_realize;
|
||||
actor_class->unrealize = tidy_texture_frame_unrealize;
|
||||
actor_class->paint = tidy_texture_frame_paint;
|
||||
|
||||
gobject_class->set_property = tidy_texture_frame_set_property;
|
||||
gobject_class->get_property = tidy_texture_frame_get_property;
|
||||
gobject_class->dispose = tidy_texture_frame_dispose;
|
||||
|
||||
pspec = g_param_spec_object ("parent-texture",
|
||||
"Parent Texture",
|
||||
"The parent ClutterTexture",
|
||||
CLUTTER_TYPE_TEXTURE,
|
||||
TIDY_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT);
|
||||
g_object_class_install_property (gobject_class, PROP_PARENT_TEXTURE, pspec);
|
||||
|
||||
pspec = g_param_spec_float ("left",
|
||||
"Left",
|
||||
"Left offset",
|
||||
0, G_MAXFLOAT,
|
||||
0,
|
||||
TIDY_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_LEFT, pspec);
|
||||
|
||||
pspec = g_param_spec_float ("top",
|
||||
"Top",
|
||||
"Top offset",
|
||||
0, G_MAXFLOAT,
|
||||
0,
|
||||
TIDY_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_TOP, pspec);
|
||||
|
||||
pspec = g_param_spec_float ("bottom",
|
||||
"Bottom",
|
||||
"Bottom offset",
|
||||
0, G_MAXFLOAT,
|
||||
0,
|
||||
TIDY_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_BOTTOM, pspec);
|
||||
|
||||
pspec = g_param_spec_float ("right",
|
||||
"Right",
|
||||
"Right offset",
|
||||
0, G_MAXFLOAT,
|
||||
0,
|
||||
TIDY_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_RIGHT, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
tidy_texture_frame_init (TidyTextureFrame *self)
|
||||
{
|
||||
TidyTextureFramePrivate *priv;
|
||||
|
||||
self->priv = priv = TIDY_TEXTURE_FRAME_GET_PRIVATE (self);
|
||||
|
||||
priv->material = COGL_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* tidy_texture_frame_new:
|
||||
* @texture: a #ClutterTexture or %NULL
|
||||
* @left: left margin preserving its content
|
||||
* @top: top margin preserving its content
|
||||
* @right: right margin preserving its content
|
||||
* @bottom: bottom margin preserving its content
|
||||
*
|
||||
* A #TidyTextureFrame is a specialized texture that efficiently clones
|
||||
* an area of the given @texture while keeping preserving portions of the
|
||||
* same texture.
|
||||
*
|
||||
* A #TidyTextureFrame can be used to make a rectangular texture fit a
|
||||
* given size without stretching its borders.
|
||||
*
|
||||
* Return value: the newly created #TidyTextureFrame
|
||||
*/
|
||||
ClutterActor*
|
||||
tidy_texture_frame_new (ClutterTexture *texture,
|
||||
gfloat left,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom)
|
||||
{
|
||||
g_return_val_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture), NULL);
|
||||
|
||||
return g_object_new (TIDY_TYPE_TEXTURE_FRAME,
|
||||
"parent-texture", texture,
|
||||
"left", left,
|
||||
"top", top,
|
||||
"right", right,
|
||||
"bottom", bottom,
|
||||
NULL);
|
||||
}
|
||||
|
||||
ClutterTexture *
|
||||
tidy_texture_frame_get_parent_texture (TidyTextureFrame *frame)
|
||||
{
|
||||
g_return_val_if_fail (TIDY_IS_TEXTURE_FRAME (frame), NULL);
|
||||
|
||||
return frame->priv->parent_texture;
|
||||
}
|
||||
|
||||
void
|
||||
tidy_texture_frame_set_parent_texture (TidyTextureFrame *frame,
|
||||
ClutterTexture *texture)
|
||||
{
|
||||
TidyTextureFramePrivate *priv;
|
||||
gboolean was_visible;
|
||||
|
||||
g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame));
|
||||
g_return_if_fail (texture == NULL || CLUTTER_IS_TEXTURE (texture));
|
||||
|
||||
priv = frame->priv;
|
||||
|
||||
was_visible = CLUTTER_ACTOR_IS_VISIBLE (frame);
|
||||
|
||||
if (priv->parent_texture == texture)
|
||||
return;
|
||||
|
||||
if (priv->parent_texture)
|
||||
{
|
||||
g_object_unref (priv->parent_texture);
|
||||
priv->parent_texture = NULL;
|
||||
|
||||
if (was_visible)
|
||||
clutter_actor_hide (CLUTTER_ACTOR (frame));
|
||||
}
|
||||
|
||||
if (texture)
|
||||
{
|
||||
priv->parent_texture = g_object_ref (texture);
|
||||
|
||||
if (was_visible && CLUTTER_ACTOR_IS_VISIBLE (priv->parent_texture))
|
||||
clutter_actor_show (CLUTTER_ACTOR (frame));
|
||||
}
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
|
||||
|
||||
g_object_notify (G_OBJECT (frame), "parent-texture");
|
||||
}
|
||||
|
||||
void
|
||||
tidy_texture_frame_set_frame (TidyTextureFrame *frame,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom,
|
||||
gfloat left)
|
||||
{
|
||||
g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame));
|
||||
|
||||
tidy_texture_frame_set_frame_internal (frame, top, right, bottom, left);
|
||||
}
|
||||
|
||||
void
|
||||
tidy_texture_frame_get_frame (TidyTextureFrame *frame,
|
||||
gfloat *top,
|
||||
gfloat *right,
|
||||
gfloat *bottom,
|
||||
gfloat *left)
|
||||
{
|
||||
TidyTextureFramePrivate *priv;
|
||||
|
||||
g_return_if_fail (TIDY_IS_TEXTURE_FRAME (frame));
|
||||
|
||||
priv = frame->priv;
|
||||
|
||||
if (top)
|
||||
*top = priv->top;
|
||||
|
||||
if (right)
|
||||
*right = priv->right;
|
||||
|
||||
if (bottom)
|
||||
*bottom = priv->bottom;
|
||||
|
||||
if (left)
|
||||
*left = priv->left;
|
||||
}
|
81
src/compositor/mutter/tidy/tidy-texture-frame.h
Normal file
81
src/compositor/mutter/tidy/tidy-texture-frame.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* tidy-texture-frame.h: Expandible texture actor
|
||||
*
|
||||
* Copyright (C) 2007, 2008 OpenedHand Ltd
|
||||
* Copyright (C) 2009 Intel Corp.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_TIDY_TEXTURE_FRAME_H
|
||||
#define _HAVE_TIDY_TEXTURE_FRAME_H
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define TIDY_TYPE_TEXTURE_FRAME (tidy_texture_frame_get_type ())
|
||||
#define TIDY_TEXTURE_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrame))
|
||||
#define TIDY_TEXTURE_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass))
|
||||
#define TIDY_IS_TEXTURE_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TIDY_TYPE_TEXTURE_FRAME))
|
||||
#define TIDY_IS_TEXTURE_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TIDY_TYPE_TEXTURE_FRAME))
|
||||
#define TIDY_TEXTURE_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TIDY_TYPE_TEXTURE_FRAME, TidyTextureFrameClass))
|
||||
|
||||
typedef struct _TidyTextureFrame TidyTextureFrame;
|
||||
typedef struct _TidyTextureFramePrivate TidyTextureFramePrivate;
|
||||
typedef struct _TidyTextureFrameClass TidyTextureFrameClass;
|
||||
|
||||
struct _TidyTextureFrame
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActor parent_instance;
|
||||
|
||||
TidyTextureFramePrivate *priv;
|
||||
};
|
||||
|
||||
struct _TidyTextureFrameClass
|
||||
{
|
||||
ClutterActorClass parent_class;
|
||||
|
||||
/* padding for future expansion */
|
||||
void (*_clutter_box_1) (void);
|
||||
void (*_clutter_box_2) (void);
|
||||
void (*_clutter_box_3) (void);
|
||||
void (*_clutter_box_4) (void);
|
||||
};
|
||||
|
||||
GType tidy_texture_frame_get_type (void) G_GNUC_CONST;
|
||||
ClutterActor * tidy_texture_frame_new (ClutterTexture *texture,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom,
|
||||
gfloat left);
|
||||
void tidy_texture_frame_set_parent_texture (TidyTextureFrame *frame,
|
||||
ClutterTexture *texture);
|
||||
ClutterTexture *tidy_texture_frame_get_parent_texture (TidyTextureFrame *frame);
|
||||
void tidy_texture_frame_set_frame (TidyTextureFrame *frame,
|
||||
gfloat top,
|
||||
gfloat right,
|
||||
gfloat bottom,
|
||||
gfloat left);
|
||||
void tidy_texture_frame_get_frame (TidyTextureFrame *frame,
|
||||
gfloat *top,
|
||||
gfloat *right,
|
||||
gfloat *bottom,
|
||||
gfloat *left);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _HAVE_TIDY_TEXTURE_FRAME_H */
|
@@ -586,7 +586,7 @@ ag_task_get_reply_and_free (AgGetPropertyTask *task,
|
||||
int *actual_format,
|
||||
unsigned long *nitems,
|
||||
unsigned long *bytesafter,
|
||||
char **prop)
|
||||
unsigned char **prop)
|
||||
{
|
||||
Display *dpy;
|
||||
|
||||
@@ -615,7 +615,7 @@ ag_task_get_reply_and_free (AgGetPropertyTask *task,
|
||||
*nitems = task->n_items;
|
||||
*bytesafter = task->bytes_after;
|
||||
|
||||
*prop = task->data; /* pass out ownership of task->data */
|
||||
*prop = (unsigned char*) task->data; /* pass out ownership of task->data */
|
||||
|
||||
SyncHandle ();
|
||||
|
||||
|
@@ -47,7 +47,7 @@ Status ag_task_get_reply_and_free (AgGetPropertyTask *task,
|
||||
int *actual_format,
|
||||
unsigned long *nitems,
|
||||
unsigned long *bytesafter,
|
||||
char **prop);
|
||||
unsigned char **prop);
|
||||
|
||||
Bool ag_task_have_reply (AgGetPropertyTask *task);
|
||||
Atom ag_task_get_property (AgGetPropertyTask *task);
|
||||
|
@@ -197,6 +197,40 @@ meta_rectangle_equal (const MetaRectangle *src1,
|
||||
(src1->height == src2->height));
|
||||
}
|
||||
|
||||
void
|
||||
meta_rectangle_union (const MetaRectangle *rect1,
|
||||
const MetaRectangle *rect2,
|
||||
MetaRectangle *dest)
|
||||
{
|
||||
int dest_x, dest_y;
|
||||
int dest_w, dest_h;
|
||||
|
||||
dest_x = rect1->x;
|
||||
dest_y = rect1->y;
|
||||
dest_w = rect1->width;
|
||||
dest_h = rect1->height;
|
||||
|
||||
if (rect2->x < dest_x)
|
||||
{
|
||||
dest_w += dest_x - rect2->x;
|
||||
dest_x = rect2->x;
|
||||
}
|
||||
if (rect2->y < dest_y)
|
||||
{
|
||||
dest_h += dest_y - rect2->y;
|
||||
dest_y = rect2->y;
|
||||
}
|
||||
if (rect2->x + rect2->width > dest_x + dest_w)
|
||||
dest_w = rect2->x + rect2->width - dest_x;
|
||||
if (rect2->y + rect2->height > dest_y + dest_h)
|
||||
dest_h = rect2->y + rect2->height - dest_y;
|
||||
|
||||
dest->x = dest_x;
|
||||
dest->y = dest_y;
|
||||
dest->width = dest_w;
|
||||
dest->height = dest_h;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_rectangle_overlap (const MetaRectangle *rect1,
|
||||
const MetaRectangle *rect2)
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include <config.h>
|
||||
#include "constraints.h"
|
||||
#include "workspace.h"
|
||||
#include "workspace-private.h"
|
||||
#include "place.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -392,7 +392,27 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
meta_window_get_work_area_for_xinerama (window,
|
||||
xinerama_info->number,
|
||||
&info->work_area_xinerama);
|
||||
info->entire_xinerama = xinerama_info->rect;
|
||||
|
||||
if (!window->fullscreen || window->fullscreen_monitors[0] == -1)
|
||||
{
|
||||
info->entire_xinerama = xinerama_info->rect;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
long monitor;
|
||||
|
||||
monitor = window->fullscreen_monitors[i];
|
||||
info->entire_xinerama =
|
||||
window->screen->xinerama_infos[monitor].rect;
|
||||
for (i = 1; i <= 3; i++)
|
||||
{
|
||||
monitor = window->fullscreen_monitors[i];
|
||||
meta_rectangle_union (&info->entire_xinerama,
|
||||
&window->screen->xinerama_infos[monitor].rect,
|
||||
&info->entire_xinerama);
|
||||
}
|
||||
}
|
||||
|
||||
cur_workspace = window->screen->active_workspace;
|
||||
info->usable_screen_region =
|
||||
@@ -784,7 +804,9 @@ constrain_fullscreen (MetaWindow *window,
|
||||
/* Determine whether constraint applies; exit if it doesn't */
|
||||
if (!window->fullscreen)
|
||||
return TRUE;
|
||||
|
||||
xinerama = info->entire_xinerama;
|
||||
|
||||
get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
|
||||
too_big = !meta_rectangle_could_fit_rect (&xinerama, &min_size);
|
||||
too_small = !meta_rectangle_could_fit_rect (&max_size, &xinerama);
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include <config.h>
|
||||
#include "core.h"
|
||||
#include "frame-private.h"
|
||||
#include "workspace.h"
|
||||
#include "workspace-private.h"
|
||||
#include "prefs.h"
|
||||
|
||||
/* Looks up the MetaWindow representing the frame of the given X window.
|
||||
@@ -145,6 +145,13 @@ meta_core_get (Display *xdisplay,
|
||||
case META_WINDOW_DOCK:
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_SPLASHSCREEN:
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
case META_WINDOW_TOOLTIP:
|
||||
case META_WINDOW_NOTIFICATION:
|
||||
case META_WINDOW_COMBO:
|
||||
case META_WINDOW_DND:
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
/* No frame */
|
||||
base_type = META_FRAME_TYPE_LAST;
|
||||
break;
|
||||
@@ -520,87 +527,87 @@ meta_core_get_menu_accelerator (MetaMenuOp menu_op,
|
||||
switch (menu_op)
|
||||
{
|
||||
case META_MENU_OP_DELETE:
|
||||
name = META_KEYBINDING_CLOSE;
|
||||
name = "close";
|
||||
break;
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
name = META_KEYBINDING_MINIMIZE;
|
||||
name = "minimize";
|
||||
break;
|
||||
case META_MENU_OP_UNMAXIMIZE:
|
||||
name = META_KEYBINDING_UNMAXIMIZE;
|
||||
name = "unmaximize";
|
||||
break;
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
name = META_KEYBINDING_MAXIMIZE;
|
||||
name = "maximize";
|
||||
break;
|
||||
case META_MENU_OP_UNSHADE:
|
||||
case META_MENU_OP_SHADE:
|
||||
name = META_KEYBINDING_TOGGLE_SHADE;
|
||||
name = "toggle_shaded";
|
||||
break;
|
||||
case META_MENU_OP_UNSTICK:
|
||||
case META_MENU_OP_STICK:
|
||||
name = META_KEYBINDING_TOGGLE_STICKY;
|
||||
name = "toggle_on_all_workspaces";
|
||||
break;
|
||||
case META_MENU_OP_ABOVE:
|
||||
case META_MENU_OP_UNABOVE:
|
||||
name = META_KEYBINDING_TOGGLE_ABOVE;
|
||||
name = "toggle_above";
|
||||
break;
|
||||
case META_MENU_OP_WORKSPACES:
|
||||
switch (workspace)
|
||||
{
|
||||
case 1:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_1;
|
||||
name = "move_to_workspace_1";
|
||||
break;
|
||||
case 2:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_2;
|
||||
name = "move_to_workspace_2";
|
||||
break;
|
||||
case 3:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_3;
|
||||
name = "move_to_workspace_3";
|
||||
break;
|
||||
case 4:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_4;
|
||||
name = "move_to_workspace_4";
|
||||
break;
|
||||
case 5:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_5;
|
||||
name = "move_to_workspace_5";
|
||||
break;
|
||||
case 6:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_6;
|
||||
name = "move_to_workspace_6";
|
||||
break;
|
||||
case 7:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_7;
|
||||
name = "move_to_workspace_7";
|
||||
break;
|
||||
case 8:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_8;
|
||||
name = "move_to_workspace_8";
|
||||
break;
|
||||
case 9:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_9;
|
||||
name = "move_to_workspace_9";
|
||||
break;
|
||||
case 10:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_10;
|
||||
name = "move_to_workspace_10";
|
||||
break;
|
||||
case 11:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_11;
|
||||
name = "move_to_workspace_11";
|
||||
break;
|
||||
case 12:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_12;
|
||||
name = "move_to_workspace_12";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case META_MENU_OP_MOVE:
|
||||
name = META_KEYBINDING_BEGIN_MOVE;
|
||||
name = "begin_move";
|
||||
break;
|
||||
case META_MENU_OP_RESIZE:
|
||||
name = META_KEYBINDING_BEGIN_RESIZE;
|
||||
name = "begin_resize";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_LEFT:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_LEFT;
|
||||
name = "move_to_workspace_left";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_RIGHT:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_RIGHT;
|
||||
name = "move_to_workspace_right";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_UP:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_UP;
|
||||
name = "move_to_workspace_up";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_DOWN:
|
||||
name = META_KEYBINDING_MOVE_WORKSPACE_DOWN;
|
||||
name = "move_to_workspace_down";
|
||||
break;
|
||||
case META_MENU_OP_RECOVER:
|
||||
/* No keybinding for this one */
|
||||
|
@@ -491,7 +491,7 @@ meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp)
|
||||
|
||||
if (w->xtransient_for == window->xwindow &&
|
||||
w->res_class &&
|
||||
g_strcasecmp (w->res_class, "metacity-dialog") == 0)
|
||||
g_ascii_strcasecmp (w->res_class, "metacity-dialog") == 0)
|
||||
{
|
||||
meta_window_activate (w, timestamp);
|
||||
break;
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "common.h"
|
||||
#include "boxes.h"
|
||||
#include "display.h"
|
||||
#include "keybindings-private.h"
|
||||
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
#include <libsn/sn.h>
|
||||
@@ -46,12 +47,9 @@
|
||||
#include <X11/extensions/sync.h>
|
||||
#endif
|
||||
|
||||
typedef struct _MetaKeyBinding MetaKeyBinding;
|
||||
typedef struct _MetaStack MetaStack;
|
||||
typedef struct _MetaUISlave MetaUISlave;
|
||||
typedef struct _MetaWorkspace MetaWorkspace;
|
||||
|
||||
typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
|
||||
typedef struct _MetaGroupPropHooks MetaGroupPropHooks;
|
||||
|
||||
typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
|
||||
@@ -75,6 +73,8 @@ typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
|
||||
|
||||
struct _MetaDisplay
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *name;
|
||||
Display *xdisplay;
|
||||
|
||||
@@ -201,10 +201,8 @@ struct _MetaDisplay
|
||||
int grab_resize_timeout_id;
|
||||
|
||||
/* Keybindings stuff */
|
||||
MetaKeyBinding *screen_bindings;
|
||||
int n_screen_bindings;
|
||||
MetaKeyBinding *window_bindings;
|
||||
int n_window_bindings;
|
||||
MetaKeyBinding *key_bindings;
|
||||
int n_key_bindings;
|
||||
int min_keycode;
|
||||
int max_keycode;
|
||||
KeySym *keymap;
|
||||
@@ -234,7 +232,8 @@ struct _MetaDisplay
|
||||
MetaWindow *window_with_menu;
|
||||
|
||||
/* Managed by window-props.c */
|
||||
MetaWindowPropHooks *prop_hooks;
|
||||
gpointer *prop_hooks_table;
|
||||
GHashTable *prop_hooks;
|
||||
|
||||
/* Managed by group-props.c */
|
||||
MetaGroupPropHooks *group_prop_hooks;
|
||||
@@ -299,6 +298,11 @@ struct _MetaDisplay
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _MetaDisplayClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
/* Xserver time can wraparound, thus comparing two timestamps needs to take
|
||||
* this into account. Here's a little macro to help out. If no wraparound
|
||||
* has occurred, this is equivalent to
|
||||
@@ -372,20 +376,6 @@ void meta_display_set_grab_op_cursor (MetaDisplay *display,
|
||||
Window grab_xwindow,
|
||||
guint32 timestamp);
|
||||
|
||||
gboolean meta_display_begin_grab_op (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
MetaGrabOp op,
|
||||
gboolean pointer_already_grabbed,
|
||||
gboolean frame_action,
|
||||
int button,
|
||||
gulong modmask,
|
||||
guint32 timestamp,
|
||||
int root_x,
|
||||
int root_y);
|
||||
void meta_display_end_grab_op (MetaDisplay *display,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_display_check_threshold_reached (MetaDisplay *display,
|
||||
int x,
|
||||
int y);
|
||||
@@ -408,9 +398,6 @@ void meta_display_increment_event_serial (MetaDisplay *display);
|
||||
|
||||
void meta_display_update_active_window_hint (MetaDisplay *display);
|
||||
|
||||
guint32 meta_display_get_current_time (MetaDisplay *display);
|
||||
guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display);
|
||||
|
||||
/* utility goo */
|
||||
const char* meta_event_mode_to_string (int m);
|
||||
const char* meta_event_detail_to_string (int d);
|
||||
@@ -430,36 +417,6 @@ void meta_display_ping_window (MetaDisplay *display,
|
||||
gboolean meta_display_window_has_pending_pings (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_TAB_LIST_NORMAL,
|
||||
META_TAB_LIST_DOCKS,
|
||||
META_TAB_LIST_GROUP
|
||||
} MetaTabList;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_TAB_SHOW_ICON, /* Alt-Tab mode */
|
||||
META_TAB_SHOW_INSTANTLY /* Alt-Esc mode */
|
||||
} MetaTabShowType;
|
||||
|
||||
GList* meta_display_get_tab_list (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
MetaScreen *screen,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
MetaWindow* meta_display_get_tab_next (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
MetaScreen *screen,
|
||||
MetaWorkspace *workspace,
|
||||
MetaWindow *window,
|
||||
gboolean backward);
|
||||
|
||||
MetaWindow* meta_display_get_tab_current (MetaDisplay *display,
|
||||
MetaTabList type,
|
||||
MetaScreen *screen,
|
||||
MetaWorkspace *workspace);
|
||||
|
||||
int meta_resize_gravity_from_grab_op (MetaGrabOp op);
|
||||
|
||||
gboolean meta_grab_op_is_moving (MetaGrabOp op);
|
||||
@@ -473,28 +430,6 @@ void meta_display_increment_focus_sentinel (MetaDisplay *display);
|
||||
void meta_display_decrement_focus_sentinel (MetaDisplay *display);
|
||||
gboolean meta_display_focus_sentinel_clear (MetaDisplay *display);
|
||||
|
||||
/* meta_display_set_input_focus_window is like XSetInputFocus, except
|
||||
* that (a) it can't detect timestamps later than the current time,
|
||||
* since Metacity isn't part of the XServer, and thus gives erroneous
|
||||
* behavior in this circumstance (so don't do it), (b) it uses
|
||||
* display->last_focus_time since we don't have access to the true
|
||||
* Xserver one, (c) it makes use of display->user_time since checking
|
||||
* whether a window should be allowed to be focused should depend
|
||||
* on user_time events (see bug 167358, comment 15 in particular)
|
||||
*/
|
||||
void meta_display_set_input_focus_window (MetaDisplay *display,
|
||||
MetaWindow *window,
|
||||
gboolean focus_frame,
|
||||
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
|
||||
*/
|
||||
void meta_display_focus_the_no_focus_window (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_display_queue_autoraise_callback (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
void meta_display_remove_autoraise_callback (MetaDisplay *display);
|
||||
|
@@ -40,11 +40,11 @@
|
||||
#include "group-props.h"
|
||||
#include "frame-private.h"
|
||||
#include "errors.h"
|
||||
#include "keybindings.h"
|
||||
#include "keybindings-private.h"
|
||||
#include "prefs.h"
|
||||
#include "resizepopup.h"
|
||||
#include "xprops.h"
|
||||
#include "workspace.h"
|
||||
#include "workspace-private.h"
|
||||
#include "bell.h"
|
||||
#include "effects.h"
|
||||
#include "compositor.h"
|
||||
@@ -127,6 +127,8 @@ typedef struct
|
||||
Window xwindow;
|
||||
} MetaAutoRaiseData;
|
||||
|
||||
G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
|
||||
|
||||
/**
|
||||
* The display we're managing. This is a singleton object. (Historically,
|
||||
* this was a list of displays, but there was never any way to add more
|
||||
@@ -163,6 +165,11 @@ static void sanity_check_timestamps (MetaDisplay *display,
|
||||
|
||||
MetaGroup* get_focussed_group (MetaDisplay *display);
|
||||
|
||||
static void
|
||||
meta_display_class_init (MetaDisplayClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for MetaPingData structs. Will destroy the
|
||||
* event source for the struct as well.
|
||||
@@ -298,6 +305,13 @@ disable_compositor (MetaDisplay *display)
|
||||
display->compositor = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_display_init (MetaDisplay *disp)
|
||||
{
|
||||
/* Some stuff could go in here that's currently in _open,
|
||||
* but it doesn't really matter. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new display, sets it up, initialises all the X extensions
|
||||
* we will need, and adds it to the list of displays.
|
||||
@@ -340,7 +354,7 @@ meta_display_open (void)
|
||||
XSynchronize (xdisplay, True);
|
||||
|
||||
g_assert (the_display == NULL);
|
||||
the_display = g_new (MetaDisplay, 1);
|
||||
the_display = g_object_new (META_TYPE_DISPLAY, NULL);
|
||||
|
||||
the_display->closing = 0;
|
||||
|
||||
@@ -719,7 +733,7 @@ meta_display_open (void)
|
||||
/* We don't composite the windows here because they will be composited
|
||||
faster with the call to meta_screen_manage_all_windows further down
|
||||
the code */
|
||||
if (meta_prefs_get_compositing_manager ())
|
||||
if (1) /* meta_prefs_get_compositing_manager ()) FIXME */
|
||||
enable_compositor (the_display, FALSE);
|
||||
|
||||
meta_display_grab (the_display);
|
||||
@@ -903,7 +917,7 @@ meta_display_close (MetaDisplay *display,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Must be after all calls to meta_window_free() since they
|
||||
/* Must be after all calls to meta_window_unmanage() since they
|
||||
* unregister windows
|
||||
*/
|
||||
g_hash_table_destroy (display->window_ids);
|
||||
@@ -923,8 +937,7 @@ meta_display_close (MetaDisplay *display,
|
||||
if (display->compositor)
|
||||
meta_compositor_destroy (display->compositor);
|
||||
|
||||
g_free (display);
|
||||
display = NULL;
|
||||
g_object_unref (display);
|
||||
|
||||
meta_quit (META_EXIT_SUCCESS);
|
||||
}
|
||||
@@ -1669,7 +1682,7 @@ event_callback (XEvent *event,
|
||||
if (!unmodified)
|
||||
begin_move = TRUE;
|
||||
}
|
||||
else if (!unmodified && event->xbutton.button == 2)
|
||||
else if (!unmodified && event->xbutton.button == meta_prefs_get_mouse_button_resize())
|
||||
{
|
||||
if (window->has_resize_func)
|
||||
{
|
||||
@@ -1718,7 +1731,7 @@ event_callback (XEvent *event,
|
||||
event->xbutton.y_root);
|
||||
}
|
||||
}
|
||||
else if (event->xbutton.button == 3)
|
||||
else if (event->xbutton.button == meta_prefs_get_mouse_button_menu())
|
||||
{
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
@@ -1992,7 +2005,7 @@ event_callback (XEvent *event,
|
||||
else
|
||||
{
|
||||
/* Unmanage destroyed window */
|
||||
meta_window_free (window, timestamp);
|
||||
meta_window_unmanage (window, timestamp);
|
||||
window = NULL;
|
||||
}
|
||||
}
|
||||
@@ -2020,11 +2033,12 @@ event_callback (XEvent *event,
|
||||
"Window %s withdrawn\n",
|
||||
window->desc);
|
||||
|
||||
meta_effect_run_close (window, NULL, NULL);
|
||||
if (!window->override_redirect)
|
||||
meta_effect_run_close (window, NULL, NULL);
|
||||
|
||||
/* Unmanage withdrawn window */
|
||||
window->withdrawn = TRUE;
|
||||
meta_window_free (window, timestamp);
|
||||
meta_window_unmanage (window, timestamp);
|
||||
window = NULL;
|
||||
}
|
||||
else
|
||||
@@ -2045,6 +2059,15 @@ event_callback (XEvent *event,
|
||||
}
|
||||
break;
|
||||
case MapNotify:
|
||||
/* NB: override redirect windows wont cause a map request so we
|
||||
* watch out for map notifies against any root windows too if a
|
||||
* compositor is enabled: */
|
||||
if (display->compositor && window == NULL
|
||||
&& meta_display_screen_for_root (display, event->xmap.event))
|
||||
{
|
||||
window = meta_window_new (display, event->xmap.window,
|
||||
FALSE);
|
||||
}
|
||||
break;
|
||||
case MapRequest:
|
||||
if (window == NULL)
|
||||
@@ -2073,29 +2096,32 @@ event_callback (XEvent *event,
|
||||
case ReparentNotify:
|
||||
break;
|
||||
case ConfigureNotify:
|
||||
/* Handle screen resize */
|
||||
{
|
||||
MetaScreen *screen;
|
||||
if (window && window->override_redirect)
|
||||
meta_window_configure_notify (window, &event->xconfigure);
|
||||
else
|
||||
/* Handle screen resize */
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
screen = meta_display_screen_for_root (display,
|
||||
event->xconfigure.window);
|
||||
screen = meta_display_screen_for_root (display,
|
||||
event->xconfigure.window);
|
||||
|
||||
if (screen != NULL)
|
||||
{
|
||||
if (screen != NULL)
|
||||
{
|
||||
#ifdef HAVE_RANDR
|
||||
/* do the resize the official way */
|
||||
XRRUpdateConfiguration (event);
|
||||
/* do the resize the official way */
|
||||
XRRUpdateConfiguration (event);
|
||||
#else
|
||||
/* poke around in Xlib */
|
||||
screen->xscreen->width = event->xconfigure.width;
|
||||
screen->xscreen->height = event->xconfigure.height;
|
||||
/* poke around in Xlib */
|
||||
screen->xscreen->width = event->xconfigure.width;
|
||||
screen->xscreen->height = event->xconfigure.height;
|
||||
#endif
|
||||
|
||||
meta_screen_resize (screen,
|
||||
event->xconfigure.width,
|
||||
event->xconfigure.height);
|
||||
}
|
||||
}
|
||||
|
||||
meta_screen_resize (screen,
|
||||
event->xconfigure.width,
|
||||
event->xconfigure.height);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ConfigureRequest:
|
||||
/* This comment and code is found in both twm and fvwm */
|
||||
@@ -2397,9 +2423,10 @@ event_callback (XEvent *event,
|
||||
|
||||
if (display->compositor)
|
||||
{
|
||||
meta_compositor_process_event (display->compositor,
|
||||
event,
|
||||
window);
|
||||
if (meta_compositor_process_event (display->compositor,
|
||||
event,
|
||||
window))
|
||||
filter_out_event = TRUE;
|
||||
}
|
||||
|
||||
display->current_time = CurrentTime;
|
||||
@@ -3264,9 +3291,10 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
|
||||
if (display->grab_op != META_GRAB_OP_NONE)
|
||||
{
|
||||
meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n",
|
||||
op, window ? window->desc : "none", display->grab_op,
|
||||
display->grab_window ? display->grab_window->desc : "none");
|
||||
if (window)
|
||||
meta_warning ("Attempt to perform window operation %u on window %s when operation %u on %s already in effect\n",
|
||||
op, window->desc, display->grab_op,
|
||||
display->grab_window ? display->grab_window->desc : "none");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -3540,8 +3568,11 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) ||
|
||||
display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING)
|
||||
{
|
||||
meta_ui_tab_popup_free (display->grab_screen->tab_popup);
|
||||
display->grab_screen->tab_popup = NULL;
|
||||
if (display->grab_screen->tab_popup)
|
||||
{
|
||||
meta_ui_tab_popup_free (display->grab_screen->tab_popup);
|
||||
display->grab_screen->tab_popup = NULL;
|
||||
}
|
||||
|
||||
/* If the ungrab here causes an EnterNotify, ignore it for
|
||||
* sloppy focus
|
||||
@@ -4814,7 +4845,7 @@ meta_display_unmanage_windows_for_screen (MetaDisplay *display,
|
||||
tmp = winlist;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
meta_window_free (tmp->data, timestamp);
|
||||
meta_window_unmanage (tmp->data, timestamp);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
@@ -4920,8 +4951,11 @@ prefs_changed_callback (MetaPreference pref,
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
meta_display_grab_focus_window_button (display, w);
|
||||
meta_display_grab_window_buttons (display, w->xwindow);
|
||||
if (w->type != META_WINDOW_DOCK)
|
||||
{
|
||||
meta_display_grab_focus_window_button (display, w);
|
||||
meta_display_grab_window_buttons (display, w->xwindow);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
@@ -5183,3 +5217,10 @@ meta_display_get_shape_event_base (MetaDisplay *display)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Atom meta_display_get_atom (MetaDisplay *display, MetaAtom meta_atom)
|
||||
{
|
||||
Atom *atoms = & display->atom_WM_PROTOCOLS;
|
||||
|
||||
return atoms[meta_atom - 1];
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include "edge-resistance.h"
|
||||
#include "boxes.h"
|
||||
#include "display-private.h"
|
||||
#include "workspace.h"
|
||||
#include "workspace-private.h"
|
||||
|
||||
/* A simple macro for whether a given window's edges are potentially
|
||||
* relevant for resistance/snapping during a move/resize operation
|
||||
@@ -985,8 +985,8 @@ meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display)
|
||||
cur_window_iter = cur_window_iter->next;
|
||||
}
|
||||
/* Put 'em in bottom to top order */
|
||||
rem_windows = g_slist_reverse (obscuring_windows);
|
||||
rem_win_stacking = g_slist_reverse (window_stacking);
|
||||
rem_windows = obscuring_windows = g_slist_reverse (obscuring_windows);
|
||||
rem_win_stacking = window_stacking = g_slist_reverse (window_stacking);
|
||||
|
||||
/*
|
||||
* 3rd: loop over the windows again, this time getting the edges from
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "frame-private.h"
|
||||
#include "bell.h"
|
||||
#include "errors.h"
|
||||
#include "keybindings.h"
|
||||
#include "keybindings-private.h"
|
||||
|
||||
#ifdef HAVE_RENDER
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#define META_GROUP_PROPS_H
|
||||
|
||||
#include "group.h"
|
||||
#include "window-private.h"
|
||||
|
||||
void meta_group_reload_property (MetaGroup *group,
|
||||
Atom property);
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "util.h"
|
||||
#include "group-private.h"
|
||||
#include "group-props.h"
|
||||
#include "window-private.h"
|
||||
#include "window.h"
|
||||
|
||||
static MetaGroup*
|
||||
@@ -272,3 +273,13 @@ meta_group_property_notify (MetaGroup *group,
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
meta_group_get_size (MetaGroup *group)
|
||||
{
|
||||
if (!group)
|
||||
return 0;
|
||||
|
||||
return group->refcount;
|
||||
}
|
||||
|
||||
|
@@ -225,11 +225,12 @@ read_rgb_icon (MetaDisplay *display,
|
||||
gulong nitems;
|
||||
gulong bytes_after;
|
||||
int result, err;
|
||||
gulong *data;
|
||||
guchar *data;
|
||||
gulong *best;
|
||||
int w, h;
|
||||
gulong *best_mini;
|
||||
int mini_w, mini_h;
|
||||
gulong *data_as_long;
|
||||
|
||||
meta_error_trap_push_with_return (display);
|
||||
type = None;
|
||||
@@ -239,8 +240,7 @@ read_rgb_icon (MetaDisplay *display,
|
||||
display->atom__NET_WM_ICON,
|
||||
0, G_MAXLONG,
|
||||
False, XA_CARDINAL, &type, &format, &nitems,
|
||||
&bytes_after, ((guchar **)&data));
|
||||
|
||||
&bytes_after, &data);
|
||||
err = meta_error_trap_pop_with_return (display, TRUE);
|
||||
|
||||
if (err != Success ||
|
||||
@@ -253,7 +253,9 @@ read_rgb_icon (MetaDisplay *display,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!find_best_size (data, nitems,
|
||||
data_as_long = (gulong *)data;
|
||||
|
||||
if (!find_best_size (data_as_long, nitems,
|
||||
ideal_width, ideal_height,
|
||||
&w, &h, &best))
|
||||
{
|
||||
@@ -261,7 +263,7 @@ read_rgb_icon (MetaDisplay *display,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!find_best_size (data, nitems,
|
||||
if (!find_best_size (data_as_long, nitems,
|
||||
ideal_mini_width, ideal_mini_height,
|
||||
&mini_w, &mini_h, &best_mini))
|
||||
{
|
||||
@@ -464,6 +466,7 @@ get_kwm_win_icon (MetaDisplay *display,
|
||||
int format;
|
||||
gulong nitems;
|
||||
gulong bytes_after;
|
||||
guchar *data;
|
||||
Pixmap *icons;
|
||||
int err, result;
|
||||
|
||||
@@ -478,7 +481,8 @@ get_kwm_win_icon (MetaDisplay *display,
|
||||
False,
|
||||
display->atom__KWM_WIN_ICON,
|
||||
&type, &format, &nitems,
|
||||
&bytes_after, (guchar **)&icons);
|
||||
&bytes_after, &data);
|
||||
icons = (Pixmap *)data;
|
||||
|
||||
err = meta_error_trap_pop_with_return (display, TRUE);
|
||||
if (err != Success ||
|
||||
@@ -817,30 +821,14 @@ meta_read_icons (MetaScreen *screen,
|
||||
if (icon_cache->want_fallback &&
|
||||
icon_cache->origin < USING_FALLBACK_ICON)
|
||||
{
|
||||
GdkPixbuf *fallback_icon;
|
||||
GdkPixbuf *fallback_mini_icon;
|
||||
|
||||
fallback_icon = NULL;
|
||||
fallback_mini_icon = NULL;
|
||||
get_fallback_icons (screen,
|
||||
iconp,
|
||||
ideal_width,
|
||||
ideal_height,
|
||||
mini_iconp,
|
||||
ideal_mini_width,
|
||||
ideal_mini_height);
|
||||
|
||||
meta_ui_get_fallback_icons(&fallback_icon, &fallback_mini_icon);
|
||||
|
||||
if (fallback_icon == NULL || fallback_mini_icon == NULL)
|
||||
{
|
||||
get_fallback_icons (screen,
|
||||
iconp,
|
||||
ideal_width,
|
||||
ideal_height,
|
||||
mini_iconp,
|
||||
ideal_mini_width,
|
||||
ideal_mini_height);
|
||||
}
|
||||
|
||||
if (fallback_icon != NULL)
|
||||
*iconp = fallback_icon;
|
||||
if (fallback_mini_icon != NULL)
|
||||
*mini_iconp = fallback_mini_icon;
|
||||
|
||||
replace_cache (icon_cache, USING_FALLBACK_ICON,
|
||||
*iconp, *mini_iconp);
|
||||
|
||||
|
@@ -26,11 +26,10 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_KEYBINDINGS_H
|
||||
#define META_KEYBINDINGS_H
|
||||
#ifndef META_KEYBINDINGS_PRIVATE_H
|
||||
#define META_KEYBINDINGS_PRIVATE_H
|
||||
|
||||
#include "display-private.h"
|
||||
#include "window.h"
|
||||
#include "keybindings.h"
|
||||
|
||||
void meta_display_init_keys (MetaDisplay *display);
|
||||
void meta_display_shutdown_keys (MetaDisplay *display);
|
File diff suppressed because it is too large
Load Diff
184
src/core/main.c
184
src/core/main.c
@@ -52,8 +52,10 @@
|
||||
#include "ui.h"
|
||||
#include "session.h"
|
||||
#include "prefs.h"
|
||||
#include "compositor.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
@@ -66,6 +68,11 @@
|
||||
#include <locale.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The exit code we'll return to our parent process when we eventually die.
|
||||
*/
|
||||
@@ -213,12 +220,14 @@ typedef struct
|
||||
gchar *save_file;
|
||||
gchar *display_name;
|
||||
gchar *client_id;
|
||||
gchar *mutter_plugins;
|
||||
gboolean replace_wm;
|
||||
gboolean disable_sm;
|
||||
gboolean print_version;
|
||||
gboolean sync;
|
||||
gboolean composite;
|
||||
gboolean no_composite;
|
||||
gboolean no_tab_popup;
|
||||
} MetaArguments;
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
@@ -240,11 +249,11 @@ typedef struct
|
||||
* \param argv Pointer to the array of arguments Metacity was given
|
||||
* \param meta_args The result of parsing the arguments.
|
||||
**/
|
||||
static void
|
||||
static GOptionContext *
|
||||
meta_parse_options (int *argc, char ***argv,
|
||||
MetaArguments *meta_args)
|
||||
{
|
||||
MetaArguments my_args = {NULL, NULL, NULL,
|
||||
MetaArguments my_args = {NULL, NULL, NULL, NULL,
|
||||
FALSE, FALSE, FALSE, FALSE, FALSE};
|
||||
GOptionEntry options[] = {
|
||||
{
|
||||
@@ -300,6 +309,20 @@ meta_parse_options (int *argc, char ***argv,
|
||||
N_("Turn compositing off"),
|
||||
NULL
|
||||
},
|
||||
#ifdef WITH_CLUTTER
|
||||
{
|
||||
"mutter-plugins", 0, 0, G_OPTION_ARG_STRING,
|
||||
&my_args.mutter_plugins,
|
||||
N_("Comma-separated list of compositor plugins"),
|
||||
"PLUGINS"
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"no-tab-popup", 0, 0, G_OPTION_ARG_NONE,
|
||||
&my_args.no_tab_popup,
|
||||
N_("Whether window popup/frame should be shown when cycling windows."),
|
||||
NULL
|
||||
},
|
||||
{NULL}
|
||||
};
|
||||
GOptionContext *ctx;
|
||||
@@ -307,24 +330,103 @@ meta_parse_options (int *argc, char ***argv,
|
||||
|
||||
ctx = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (ctx, options, "metacity");
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
/*
|
||||
* This function is only available in clutter >= 0.8.2
|
||||
*/
|
||||
#if CLUTTER_CHECK_VERSION(0,8,2)
|
||||
g_option_context_add_group (ctx, clutter_get_option_group_without_init ());
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (!g_option_context_parse (ctx, argc, argv, &error))
|
||||
{
|
||||
g_print ("metacity: %s\n", error->message);
|
||||
exit(1);
|
||||
}
|
||||
g_option_context_free (ctx);
|
||||
|
||||
/* Return the parsed options through the meta_args param. */
|
||||
*meta_args = my_args;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
/* Metacity is responsible for pulling events off the X queue, so Clutter
|
||||
* doesn't need (and shouldn't) run its normal event source which polls
|
||||
* the X fd, but we do have to deal with dispatching events that accumulate
|
||||
* in the clutter queue. This happens, for example, when clutter generate
|
||||
* enter/leave events on mouse motion - several events are queued in the
|
||||
* clutter queue but only one dispatched. It could also happen because of
|
||||
* explicit calls to clutter_event_put(). We add a very simple custom
|
||||
* event loop source which is simply responsible for pulling events off
|
||||
* of the queue and dispatching them before we block for new events.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
event_prepare (GSource *source,
|
||||
gint *timeout_)
|
||||
{
|
||||
*timeout_ = -1;
|
||||
|
||||
return clutter_events_pending ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_check (GSource *source)
|
||||
{
|
||||
return clutter_events_pending ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterEvent *event = clutter_event_get ();
|
||||
if (event)
|
||||
clutter_do_event (event);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GSourceFuncs event_funcs = {
|
||||
event_prepare,
|
||||
event_check,
|
||||
event_dispatch
|
||||
};
|
||||
|
||||
static void
|
||||
meta_clutter_init (GOptionContext *ctx, int *argc, char ***argv)
|
||||
{
|
||||
clutter_x11_set_display (gdk_display);
|
||||
clutter_x11_disable_event_retrieval ();
|
||||
|
||||
if (CLUTTER_INIT_SUCCESS == clutter_init (argc, argv))
|
||||
{
|
||||
meta_compositor_can_use_clutter__ = 1;
|
||||
|
||||
GSource *source = g_source_new (&event_funcs, sizeof (GSource));
|
||||
g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message ("Unable to initialize Clutter.\n");
|
||||
meta_compositor_can_use_clutter__ = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Selects which display Metacity should use. It first tries to use
|
||||
* display_name as the display. If display_name is NULL then
|
||||
* try to use the environment variable METACITY_DISPLAY. If that
|
||||
* also is NULL, use the default - :0.0
|
||||
*/
|
||||
static
|
||||
void meta_select_display (gchar *display_name)
|
||||
static void
|
||||
meta_select_display (gchar *display_name)
|
||||
{
|
||||
gchar *envVar = "";
|
||||
if (display_name)
|
||||
@@ -335,6 +437,23 @@ void meta_select_display (gchar *display_name)
|
||||
/* DO NOT FREE envVar, putenv() sucks */
|
||||
putenv (envVar);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_finalize (void)
|
||||
{
|
||||
meta_display_close (meta_get_display (),
|
||||
CurrentTime); /* I doubt correct timestamps matter here */
|
||||
|
||||
meta_session_shutdown ();
|
||||
}
|
||||
|
||||
static void
|
||||
sigterm_handler (int signum)
|
||||
{
|
||||
meta_finalize ();
|
||||
|
||||
exit (meta_exit_code);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is where the story begins. It parses commandline options and
|
||||
@@ -358,6 +477,10 @@ main (int argc, char **argv)
|
||||
"Pango", "GLib-GObject", "GThread"
|
||||
};
|
||||
guint i;
|
||||
GOptionContext *ctx;
|
||||
|
||||
if (!g_thread_supported ())
|
||||
g_thread_init (NULL);
|
||||
|
||||
if (setlocale (LC_ALL, "") == NULL)
|
||||
meta_warning ("Locale not understood by C library, internationalization will not work\n");
|
||||
@@ -375,13 +498,20 @@ main (int argc, char **argv)
|
||||
g_strerror (errno));
|
||||
#endif
|
||||
|
||||
act.sa_handler = &sigterm_handler;
|
||||
if (sigaction (SIGTERM, &act, NULL) < 0)
|
||||
g_printerr ("Failed to register SIGTERM handler: %s\n",
|
||||
g_strerror (errno));
|
||||
|
||||
if (g_getenv ("METACITY_VERBOSE"))
|
||||
meta_set_verbose (TRUE);
|
||||
if (g_getenv ("METACITY_DEBUG"))
|
||||
meta_set_debugging (TRUE);
|
||||
|
||||
if (g_get_home_dir ())
|
||||
chdir (g_get_home_dir ());
|
||||
if (chdir (g_get_home_dir ()) < 0)
|
||||
meta_warning ("Could not change to home directory %s.\n",
|
||||
g_get_home_dir ());
|
||||
|
||||
meta_print_self_identity ();
|
||||
|
||||
@@ -390,7 +520,7 @@ main (int argc, char **argv)
|
||||
textdomain (GETTEXT_PACKAGE);
|
||||
|
||||
/* Parse command line arguments.*/
|
||||
meta_parse_options (&argc, &argv, &meta_args);
|
||||
ctx = meta_parse_options (&argc, &argv, &meta_args);
|
||||
|
||||
meta_set_syncing (meta_args.sync || (g_getenv ("METACITY_SYNC") != NULL));
|
||||
|
||||
@@ -411,6 +541,15 @@ main (int argc, char **argv)
|
||||
|
||||
meta_ui_init (&argc, &argv);
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
/*
|
||||
* Clutter can only be initialized after the UI.
|
||||
*/
|
||||
meta_clutter_init (ctx, &argc, &argv);
|
||||
#endif
|
||||
|
||||
g_option_context_free (ctx);
|
||||
|
||||
/* must be after UI init so we can override GDK handlers */
|
||||
meta_errors_init ();
|
||||
|
||||
@@ -499,16 +638,39 @@ main (int argc, char **argv)
|
||||
if (meta_args.composite || meta_args.no_composite)
|
||||
meta_prefs_set_compositing_manager (meta_args.composite);
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
if (meta_args.mutter_plugins)
|
||||
{
|
||||
char **plugins = g_strsplit (meta_args.mutter_plugins, ",", -1);
|
||||
char **plugin;
|
||||
GSList *plugins_list = NULL;
|
||||
|
||||
for (plugin = plugins; *plugin; plugin++)
|
||||
{
|
||||
g_strstrip (*plugin);
|
||||
plugins_list = g_slist_prepend (plugins_list, *plugin);
|
||||
}
|
||||
|
||||
plugins_list = g_slist_reverse (plugins_list);
|
||||
meta_prefs_override_clutter_plugins (plugins_list);
|
||||
|
||||
g_slist_free(plugins_list);
|
||||
g_strfreev (plugins);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (meta_args.no_tab_popup)
|
||||
{
|
||||
meta_prefs_override_no_tab_popup (TRUE);
|
||||
}
|
||||
|
||||
if (!meta_display_open ())
|
||||
meta_exit (META_EXIT_ERROR);
|
||||
|
||||
g_main_loop_run (meta_main_loop);
|
||||
|
||||
meta_display_close (meta_get_display (),
|
||||
CurrentTime); /* I doubt correct timestamps matter here */
|
||||
meta_finalize ();
|
||||
|
||||
meta_session_shutdown ();
|
||||
|
||||
if (meta_restart_after_quit)
|
||||
{
|
||||
GError *err;
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include "place.h"
|
||||
#include "workspace.h"
|
||||
#include "prefs.h"
|
||||
#include <gdk/gdkregion.h>
|
||||
#include <gdk/gdk.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -394,6 +394,14 @@ rectangle_overlaps_some_window (MetaRectangle *rect,
|
||||
case META_WINDOW_DESKTOP:
|
||||
case META_WINDOW_DIALOG:
|
||||
case META_WINDOW_MODAL_DIALOG:
|
||||
/* override redirect window types: */
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
case META_WINDOW_TOOLTIP:
|
||||
case META_WINDOW_NOTIFICATION:
|
||||
case META_WINDOW_COMBO:
|
||||
case META_WINDOW_DND:
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
break;
|
||||
|
||||
case META_WINDOW_NORMAL:
|
||||
@@ -680,6 +688,14 @@ meta_window_place (MetaWindow *window,
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_MENU:
|
||||
case META_WINDOW_UTILITY:
|
||||
/* override redirect window types: */
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
case META_WINDOW_TOOLTIP:
|
||||
case META_WINDOW_NOTIFICATION:
|
||||
case META_WINDOW_COMBO:
|
||||
case META_WINDOW_DND:
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
goto done_no_constraints;
|
||||
}
|
||||
|
||||
@@ -713,6 +729,14 @@ meta_window_place (MetaWindow *window,
|
||||
case META_WINDOW_TOOLBAR:
|
||||
case META_WINDOW_MENU:
|
||||
case META_WINDOW_UTILITY:
|
||||
/* override redirect window types: */
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
case META_WINDOW_TOOLTIP:
|
||||
case META_WINDOW_NOTIFICATION:
|
||||
case META_WINDOW_COMBO:
|
||||
case META_WINDOW_DND:
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
if (window->size_hints.flags & PPosition)
|
||||
{
|
||||
meta_topic (META_DEBUG_PLACEMENT,
|
||||
|
688
src/core/prefs.c
688
src/core/prefs.c
@@ -63,13 +63,21 @@
|
||||
|
||||
#define KEY_WORKSPACE_NAME_PREFIX "/apps/metacity/workspace_names/name_"
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
#define KEY_CLUTTER_DISABLED "/apps/metacity/general/clutter_disabled"
|
||||
#define KEY_CLUTTER_PLUGINS "/apps/metacity/general/clutter_plugins"
|
||||
#endif
|
||||
|
||||
#define KEY_LIVE_HIDDEN_WINDOWS "/apps/metacity/general/live_hidden_windows"
|
||||
|
||||
#define KEY_NO_TAB_POPUP "/apps/metacity/general/no_tab_popup"
|
||||
|
||||
#ifdef HAVE_GCONF
|
||||
static GConfClient *default_client = NULL;
|
||||
static GList *changes = NULL;
|
||||
static guint changed_idle;
|
||||
#endif
|
||||
static GList *listeners = NULL;
|
||||
#endif
|
||||
|
||||
static gboolean use_system_font = FALSE;
|
||||
static PangoFontDescription *titlebar_font = NULL;
|
||||
@@ -94,6 +102,7 @@ static gboolean gnome_animations = TRUE;
|
||||
static char *cursor_theme = NULL;
|
||||
static int cursor_size = 24;
|
||||
static gboolean compositing_manager = FALSE;
|
||||
static gboolean resize_with_right_button = FALSE;
|
||||
|
||||
static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH;
|
||||
static MetaButtonLayout button_layout;
|
||||
@@ -105,20 +114,26 @@ static char *terminal_command = NULL;
|
||||
|
||||
static char *workspace_names[MAX_REASONABLE_WORKSPACES] = { NULL, };
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
static gboolean clutter_disabled = FALSE;
|
||||
static gboolean clutter_plugins_overridden = FALSE;
|
||||
static GSList *clutter_plugins = NULL;
|
||||
#endif
|
||||
|
||||
static gboolean live_hidden_windows = FALSE;
|
||||
|
||||
static gboolean no_tab_popup = FALSE;
|
||||
|
||||
#ifdef HAVE_GCONF
|
||||
static gboolean handle_preference_update_enum (const gchar *key, GConfValue *value);
|
||||
|
||||
static gboolean update_window_binding (const char *name,
|
||||
const char *value);
|
||||
static gboolean update_screen_binding (const char *name,
|
||||
const char *value);
|
||||
static gboolean update_key_binding (const char *name,
|
||||
const char *value);
|
||||
static gboolean find_and_update_list_binding (MetaKeyPref *bindings,
|
||||
const char *name,
|
||||
GSList *value);
|
||||
static gboolean update_window_list_binding (const char *name,
|
||||
GSList *value);
|
||||
static gboolean update_screen_list_binding (const char *name,
|
||||
GSList *value);
|
||||
static gboolean update_key_list_binding (const char *name,
|
||||
GSList *value);
|
||||
static gboolean update_command (const char *name,
|
||||
const char *value);
|
||||
static gboolean update_workspace_name (const char *name,
|
||||
@@ -407,6 +422,28 @@ static MetaBoolPreference preferences_bool[] =
|
||||
&compositing_manager,
|
||||
FALSE,
|
||||
},
|
||||
{ "/apps/metacity/general/resize_with_right_button",
|
||||
META_PREF_RESIZE_WITH_RIGHT_BUTTON,
|
||||
&resize_with_right_button,
|
||||
FALSE,
|
||||
},
|
||||
#ifdef WITH_CLUTTER
|
||||
{ "/apps/metacity/general/clutter_disabled",
|
||||
META_PREF_CLUTTER_DISABLED,
|
||||
&clutter_disabled,
|
||||
FALSE,
|
||||
},
|
||||
#endif
|
||||
{ "/apps/metacity/general/live_hidden_windows",
|
||||
META_PREF_LIVE_HIDDEN_WINDOWS,
|
||||
&live_hidden_windows,
|
||||
FALSE,
|
||||
},
|
||||
{ "/apps/metacity/general/no_tab_popup",
|
||||
META_PREF_NO_TAB_POPUP,
|
||||
&no_tab_popup,
|
||||
FALSE,
|
||||
},
|
||||
{ NULL, 0, NULL, FALSE },
|
||||
};
|
||||
|
||||
@@ -540,7 +577,13 @@ handle_preference_init_string (void)
|
||||
value = gconf_client_get_string (default_client,
|
||||
cursor->key,
|
||||
&error);
|
||||
cleanup_error (&error);
|
||||
|
||||
if (error || !value)
|
||||
{
|
||||
cleanup_error (&error);
|
||||
++cursor;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cursor->handler)
|
||||
{
|
||||
@@ -650,8 +693,11 @@ handle_preference_update_enum (const gchar *key, GConfValue *value)
|
||||
* we might consider reverting invalid keys to their original values.
|
||||
* (We know the old value, so we can look up a suitable string in
|
||||
* the symtab.)
|
||||
*
|
||||
* (Empty comment follows so the translators don't see this.)
|
||||
*/
|
||||
|
||||
|
||||
/* */
|
||||
meta_warning (_("GConf key '%s' is set to an invalid value\n"),
|
||||
key);
|
||||
return TRUE;
|
||||
@@ -977,6 +1023,7 @@ meta_prefs_remove_listener (MetaPrefsChangedFunc func,
|
||||
/* Initialisation. */
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef HAVE_GCONF
|
||||
/* @@@ again, use glib's ability to tell you the size of the array */
|
||||
static gchar *gconf_dirs_we_are_interested_in[] = {
|
||||
"/apps/metacity",
|
||||
@@ -986,6 +1033,7 @@ static gchar *gconf_dirs_we_are_interested_in[] = {
|
||||
"/desktop/gnome/interface",
|
||||
NULL,
|
||||
};
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_prefs_init (void)
|
||||
@@ -1018,6 +1066,14 @@ meta_prefs_init (void)
|
||||
handle_preference_init_string ();
|
||||
handle_preference_init_int ();
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
if (!clutter_plugins_overridden)
|
||||
clutter_plugins = gconf_client_get_list (default_client, KEY_CLUTTER_PLUGINS,
|
||||
GCONF_VALUE_STRING, &err);
|
||||
|
||||
cleanup_error (&err);
|
||||
#endif
|
||||
|
||||
/* @@@ Is there any reason we don't do the add_dir here? */
|
||||
for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
|
||||
*gconf_dir_cursor!=NULL;
|
||||
@@ -1088,17 +1144,13 @@ change_notify (GConfClient *client,
|
||||
while (preference_update_handler[i]!=NULL)
|
||||
{
|
||||
if (preference_update_handler[i] (key, value))
|
||||
goto out; /* Get rid of this when we're done with the if */
|
||||
goto out; /* Get rid of this eventually */
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Otherwise, use the enormous if statement. We'll move entries
|
||||
* out of here as it becomes possible to deal with them in a
|
||||
* more general way.
|
||||
*/
|
||||
|
||||
if (g_str_has_prefix (key, KEY_WINDOW_BINDINGS_PREFIX))
|
||||
|
||||
if (g_str_has_prefix (key, KEY_WINDOW_BINDINGS_PREFIX) ||
|
||||
g_str_has_prefix (key, KEY_SCREEN_BINDINGS_PREFIX))
|
||||
{
|
||||
if (g_str_has_suffix (key, KEY_LIST_BINDINGS_SUFFIX))
|
||||
{
|
||||
@@ -1113,8 +1165,8 @@ change_notify (GConfClient *client,
|
||||
|
||||
list = value ? gconf_value_get_list (value) : NULL;
|
||||
|
||||
if (update_window_list_binding (key, list))
|
||||
queue_changed (META_PREF_WINDOW_KEYBINDINGS);
|
||||
if (update_key_list_binding (key, list))
|
||||
queue_changed (META_PREF_KEYBINDINGS);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1129,43 +1181,8 @@ change_notify (GConfClient *client,
|
||||
|
||||
str = value ? gconf_value_get_string (value) : NULL;
|
||||
|
||||
if (update_window_binding (key, str))
|
||||
queue_changed (META_PREF_WINDOW_KEYBINDINGS);
|
||||
}
|
||||
}
|
||||
else if (g_str_has_prefix (key, KEY_SCREEN_BINDINGS_PREFIX))
|
||||
{
|
||||
if (g_str_has_suffix (key, KEY_LIST_BINDINGS_SUFFIX))
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
if (value && value->type != GCONF_VALUE_LIST)
|
||||
{
|
||||
meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
|
||||
key);
|
||||
goto out;
|
||||
}
|
||||
|
||||
list = value ? gconf_value_get_list (value) : NULL;
|
||||
|
||||
if (update_screen_list_binding (key, list))
|
||||
queue_changed (META_PREF_SCREEN_KEYBINDINGS);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *str;
|
||||
|
||||
if (value && value->type != GCONF_VALUE_STRING)
|
||||
{
|
||||
meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
|
||||
key);
|
||||
goto out;
|
||||
}
|
||||
|
||||
str = value ? gconf_value_get_string (value) : NULL;
|
||||
|
||||
if (update_screen_binding (key, str))
|
||||
queue_changed (META_PREF_SCREEN_KEYBINDINGS);
|
||||
if (update_key_binding (key, str))
|
||||
queue_changed (META_PREF_KEYBINDINGS);
|
||||
}
|
||||
}
|
||||
else if (g_str_has_prefix (key, KEY_COMMAND_PREFIX))
|
||||
@@ -1200,6 +1217,25 @@ change_notify (GConfClient *client,
|
||||
if (update_workspace_name (key, str))
|
||||
queue_changed (META_PREF_WORKSPACE_NAMES);
|
||||
}
|
||||
#ifdef WITH_CLUTTER
|
||||
else if (g_str_equal (key, KEY_CLUTTER_PLUGINS) && !clutter_plugins_overridden)
|
||||
{
|
||||
GError *err = NULL;
|
||||
GSList *l;
|
||||
|
||||
l = gconf_client_get_list (default_client, KEY_CLUTTER_PLUGINS,
|
||||
GCONF_VALUE_STRING, &err);
|
||||
|
||||
if (!l)
|
||||
{
|
||||
cleanup_error (&err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
clutter_plugins = l;
|
||||
queue_changed (META_PREF_CLUTTER_PLUGINS);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
|
||||
@@ -1324,15 +1360,16 @@ titlebar_handler (MetaPreference pref,
|
||||
const gchar *string_value,
|
||||
gboolean *inform_listeners)
|
||||
{
|
||||
PangoFontDescription *new_desc;
|
||||
PangoFontDescription *new_desc = NULL;
|
||||
|
||||
new_desc = pango_font_description_from_string (string_value);
|
||||
if (string_value)
|
||||
new_desc = pango_font_description_from_string (string_value);
|
||||
|
||||
if (new_desc == NULL)
|
||||
{
|
||||
meta_warning (_("Could not parse font description "
|
||||
"\"%s\" from GConf key %s\n"),
|
||||
string_value,
|
||||
string_value ? string_value : "(null)",
|
||||
KEY_TITLEBAR_FONT);
|
||||
|
||||
*inform_listeners = FALSE;
|
||||
@@ -1364,6 +1401,8 @@ theme_name_handler (MetaPreference pref,
|
||||
const gchar *string_value,
|
||||
gboolean *inform_listeners)
|
||||
{
|
||||
g_free (current_theme);
|
||||
|
||||
/* Fallback crackrock */
|
||||
if (string_value == NULL)
|
||||
current_theme = g_strdup ("Atlanta");
|
||||
@@ -1381,7 +1420,7 @@ mouse_button_mods_handler (MetaPreference pref,
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Mouse button modifier has new gconf value \"%s\"\n",
|
||||
string_value);
|
||||
if (meta_ui_parse_modifier (string_value, &mods))
|
||||
if (string_value && meta_ui_parse_modifier (string_value, &mods))
|
||||
{
|
||||
mouse_button_mods = mods;
|
||||
}
|
||||
@@ -1476,16 +1515,17 @@ button_layout_handler (MetaPreference pref,
|
||||
gboolean *inform_listeners)
|
||||
{
|
||||
MetaButtonLayout new_layout;
|
||||
char **sides;
|
||||
char **sides = NULL;
|
||||
int i;
|
||||
|
||||
/* We need to ignore unknown button functions, for
|
||||
* compat with future versions
|
||||
*/
|
||||
|
||||
sides = g_strsplit (string_value, ":", 2);
|
||||
if (string_value)
|
||||
sides = g_strsplit (string_value, ":", 2);
|
||||
|
||||
if (sides[0] != NULL)
|
||||
if (sides != NULL && sides[0] != NULL)
|
||||
{
|
||||
char **buttons;
|
||||
int b;
|
||||
@@ -1545,7 +1585,7 @@ button_layout_handler (MetaPreference pref,
|
||||
g_strfreev (buttons);
|
||||
}
|
||||
|
||||
if (sides[0] != NULL && sides[1] != NULL)
|
||||
if (sides != NULL && sides[0] != NULL && sides[1] != NULL)
|
||||
{
|
||||
char **buttons;
|
||||
int b;
|
||||
@@ -1717,11 +1757,8 @@ meta_preference_to_string (MetaPreference pref)
|
||||
case META_PREF_APPLICATION_BASED:
|
||||
return "APPLICATION_BASED";
|
||||
|
||||
case META_PREF_SCREEN_KEYBINDINGS:
|
||||
return "SCREEN_KEYBINDINGS";
|
||||
|
||||
case META_PREF_WINDOW_KEYBINDINGS:
|
||||
return "WINDOW_KEYBINDINGS";
|
||||
case META_PREF_KEYBINDINGS:
|
||||
return "KEYBINDINGS";
|
||||
|
||||
case META_PREF_DISABLE_WORKAROUNDS:
|
||||
return "DISABLE_WORKAROUNDS";
|
||||
@@ -1779,6 +1816,19 @@ meta_preference_to_string (MetaPreference pref)
|
||||
|
||||
case META_PREF_COMPOSITING_MANAGER:
|
||||
return "COMPOSITING_MANAGER";
|
||||
|
||||
case META_PREF_RESIZE_WITH_RIGHT_BUTTON:
|
||||
return "RESIZE_WITH_RIGHT_BUTTON";
|
||||
#ifdef WITH_CLUTTER
|
||||
case META_PREF_CLUTTER_DISABLED:
|
||||
return "CLUTTER_DISABLED";
|
||||
case META_PREF_CLUTTER_PLUGINS:
|
||||
return "CLUTTER_PLUGINS";
|
||||
#endif
|
||||
case META_PREF_LIVE_HIDDEN_WINDOWS:
|
||||
return "LIVE_HIDDEN_WINDOWS";
|
||||
case META_PREF_NO_TAB_POPUP:
|
||||
return "NO_TAB_POPUP";
|
||||
}
|
||||
|
||||
return "(unknown)";
|
||||
@@ -1815,249 +1865,88 @@ meta_prefs_set_num_workspaces (int n_workspaces)
|
||||
#endif /* HAVE_GCONF */
|
||||
}
|
||||
|
||||
/* Indexes must correspond to MetaKeybindingAction */
|
||||
static MetaKeyPref screen_bindings[] = {
|
||||
{ META_KEYBINDING_WORKSPACE_1, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_2, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_3, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_4, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_5, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_6, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_7, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_8, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_9, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_10, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_11, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_12, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_LEFT, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_RIGHT, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_UP, NULL, FALSE },
|
||||
{ META_KEYBINDING_WORKSPACE_DOWN, NULL, FALSE },
|
||||
{ META_KEYBINDING_SWITCH_GROUP, NULL, TRUE },
|
||||
{ META_KEYBINDING_SWITCH_GROUP_BACKWARD, NULL, TRUE },
|
||||
{ META_KEYBINDING_SWITCH_WINDOWS, NULL, TRUE },
|
||||
{ META_KEYBINDING_SWITCH_WINDOWS_BACKWARD, NULL, TRUE },
|
||||
{ META_KEYBINDING_SWITCH_PANELS, NULL, TRUE },
|
||||
{ META_KEYBINDING_SWITCH_PANELS_BACKWARD, NULL, TRUE },
|
||||
{ META_KEYBINDING_CYCLE_GROUP, NULL, TRUE },
|
||||
{ META_KEYBINDING_CYCLE_GROUP_BACKWARD, NULL, TRUE },
|
||||
{ META_KEYBINDING_CYCLE_WINDOWS, NULL, TRUE },
|
||||
{ META_KEYBINDING_CYCLE_WINDOWS_BACKWARD, NULL, TRUE },
|
||||
{ META_KEYBINDING_CYCLE_PANELS, NULL, TRUE },
|
||||
{ META_KEYBINDING_CYCLE_PANELS_BACKWARD, NULL, TRUE },
|
||||
{ META_KEYBINDING_SHOW_DESKTOP, NULL, FALSE },
|
||||
{ META_KEYBINDING_PANEL_MAIN_MENU, NULL, FALSE },
|
||||
{ META_KEYBINDING_PANEL_RUN_DIALOG, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_1, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_2, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_3, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_4, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_5, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_6, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_7, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_8, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_9, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_10, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_11, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_12, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_13, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_14, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_15, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_16, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_17, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_18, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_19, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_20, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_21, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_22, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_23, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_24, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_25, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_26, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_27, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_28, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_29, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_30, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_31, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_32, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_SCREENSHOT, NULL, FALSE },
|
||||
{ META_KEYBINDING_COMMAND_WIN_SCREENSHOT, NULL, FALSE },
|
||||
{ META_KEYBINDING_RUN_COMMAND_TERMINAL, NULL, FALSE },
|
||||
{ META_KEYBINDING_SET_SPEW_MARK, NULL, FALSE },
|
||||
{ NULL, NULL, FALSE}
|
||||
};
|
||||
|
||||
static MetaKeyPref window_bindings[] = {
|
||||
{ META_KEYBINDING_WINDOW_MENU, NULL, FALSE },
|
||||
{ META_KEYBINDING_TOGGLE_FULLSCREEN, NULL, FALSE },
|
||||
{ META_KEYBINDING_TOGGLE_MAXIMIZE, NULL, FALSE },
|
||||
{ META_KEYBINDING_TOGGLE_ABOVE, NULL, FALSE },
|
||||
{ META_KEYBINDING_MAXIMIZE, NULL, FALSE },
|
||||
{ META_KEYBINDING_UNMAXIMIZE, NULL, FALSE },
|
||||
{ META_KEYBINDING_TOGGLE_SHADE, NULL, FALSE },
|
||||
{ META_KEYBINDING_MINIMIZE, NULL, FALSE },
|
||||
{ META_KEYBINDING_CLOSE, NULL, FALSE },
|
||||
{ META_KEYBINDING_BEGIN_MOVE, NULL, FALSE },
|
||||
{ META_KEYBINDING_BEGIN_RESIZE, NULL, FALSE },
|
||||
{ META_KEYBINDING_TOGGLE_STICKY, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_1, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_2, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_3, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_4, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_5, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_6, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_7, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_8, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_9, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_10, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_11, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_12, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_LEFT, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_RIGHT, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_UP, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_DOWN, NULL, FALSE },
|
||||
{ META_KEYBINDING_RAISE_OR_LOWER, NULL, FALSE },
|
||||
{ META_KEYBINDING_RAISE, NULL, FALSE },
|
||||
{ META_KEYBINDING_LOWER, NULL, FALSE },
|
||||
{ META_KEYBINDING_MAXIMIZE_VERTICALLY, NULL, FALSE },
|
||||
{ META_KEYBINDING_MAXIMIZE_HORIZONTALLY, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_TO_CORNER_NW, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_TO_CORNER_NE, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_TO_CORNER_SW, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_TO_CORNER_SE, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_TO_SIDE_N, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_TO_SIDE_S, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_TO_SIDE_E, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_TO_SIDE_W, NULL, FALSE },
|
||||
{ META_KEYBINDING_MOVE_TO_CENTER, NULL, FALSE },
|
||||
#define keybind(name, handler, param, flags, stroke, description) \
|
||||
{ #name, NULL, !!(flags & BINDING_REVERSES), !!(flags & BINDING_PER_WINDOW) },
|
||||
static MetaKeyPref key_bindings[] = {
|
||||
#include "all-keybindings.h"
|
||||
{ NULL, NULL, FALSE }
|
||||
};
|
||||
#undef keybind
|
||||
|
||||
#ifndef HAVE_GCONF
|
||||
|
||||
/**
|
||||
* A type to map names of keybindings (such as "switch_windows")
|
||||
* to the binding strings themselves (such as "<Alt>Tab").
|
||||
* It exists only when GConf is turned off in ./configure and
|
||||
* functions as a sort of ersatz GConf.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
const char *keybinding;
|
||||
} MetaSimpleKeyMapping;
|
||||
|
||||
/* Name field must occur in the same order as screen_bindings, though entries
|
||||
* can be skipped
|
||||
/* FIXME: This would be neater if the array only contained entries whose
|
||||
* default keystroke was non-null. You COULD do this by defining
|
||||
* ONLY_BOUND_BY_DEFAULT around various blocks at the cost of making
|
||||
* the bindings file way more complicated. However, we could stop this being
|
||||
* data and move it into code. Then the compiler would optimise away
|
||||
* the problem lines.
|
||||
*/
|
||||
static MetaSimpleKeyMapping screen_string_bindings[] = {
|
||||
{ META_KEYBINDING_WORKSPACE_LEFT, "<Control><Alt>Left" },
|
||||
{ META_KEYBINDING_WORKSPACE_RIGHT, "<Control><Alt>Right" },
|
||||
{ META_KEYBINDING_WORKSPACE_UP, "<Control><Alt>Up" },
|
||||
{ META_KEYBINDING_WORKSPACE_DOWN, "<Control><Alt>Down" },
|
||||
{ META_KEYBINDING_SWITCH_WINDOWS, "<Alt>Tab" },
|
||||
{ META_KEYBINDING_SWITCH_PANELS, "<Control><Alt>Tab" },
|
||||
{ META_KEYBINDING_CYCLE_GROUP, "<Alt>F6" },
|
||||
{ META_KEYBINDING_CYCLE_WINDOWS, "<Alt>Escape" },
|
||||
{ META_KEYBINDING_CYCLE_PANELS, "<Control><Alt>Escape" },
|
||||
{ META_KEYBINDING_SHOW_DESKTOP, "<Control><Alt>d" },
|
||||
{ META_KEYBINDING_PANEL_MAIN_MENU, "<Alt>F1" },
|
||||
{ META_KEYBINDING_PANEL_RUN_DIALOG, "<Alt>F2" },
|
||||
{ META_KEYBINDING_COMMAND_SCREENSHOT, "Print" },
|
||||
{ META_KEYBINDING_COMMAND_WIN_SCREENSHOT, "<Alt>Print" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* Name field must occur in the same order as window_bindings, though entries
|
||||
* can be skipped
|
||||
*/
|
||||
static MetaSimpleKeyMapping window_string_bindings[] = {
|
||||
{ META_KEYBINDING_WINDOW_MENU, "<Alt>Print" },
|
||||
{ META_KEYBINDING_MAXIMIZE, "<Alt>F10" },
|
||||
{ META_KEYBINDING_UNMAXIMIZE, "<Alt>F5" },
|
||||
{ META_KEYBINDING_MINIMIZE, "<Alt>F9" },
|
||||
{ META_KEYBINDING_CLOSE, "<Alt>F4" },
|
||||
{ META_KEYBINDING_BEGIN_MOVE, "<Alt>F7" },
|
||||
{ META_KEYBINDING_BEGIN_RESIZE, "<Alt>F8" },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_LEFT, "<Control><Shift><Alt>Left" },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_RIGHT, "<Control><Shift><Alt>Right" },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_UP, "<Control><Shift><Alt>Up" },
|
||||
{ META_KEYBINDING_MOVE_WORKSPACE_DOWN, "<Control><Shift><Alt>Down" },
|
||||
{ NULL, NULL }
|
||||
#define keybind(name, handler, param, flags, stroke, description) \
|
||||
{ #name, stroke },
|
||||
|
||||
static MetaSimpleKeyMapping key_string_bindings[] = {
|
||||
#include "all-keybindings.h"
|
||||
{ NULL, NULL }
|
||||
};
|
||||
#undef keybind
|
||||
|
||||
#endif /* NOT HAVE_GCONF */
|
||||
|
||||
static void
|
||||
init_bindings (void)
|
||||
{
|
||||
#ifdef HAVE_GCONF
|
||||
int i;
|
||||
#ifdef HAVE_GCONF
|
||||
int i = 0;
|
||||
GError *err;
|
||||
|
||||
i = 0;
|
||||
while (window_bindings[i].name)
|
||||
|
||||
while (key_bindings[i].name)
|
||||
{
|
||||
GSList *list_val, *tmp;
|
||||
char *str_val;
|
||||
char *key;
|
||||
|
||||
key = g_strconcat (KEY_WINDOW_BINDINGS_PREFIX, "/",
|
||||
window_bindings[i].name, NULL);
|
||||
|
||||
|
||||
key = g_strconcat (key_bindings[i].per_window?
|
||||
KEY_WINDOW_BINDINGS_PREFIX:
|
||||
KEY_SCREEN_BINDINGS_PREFIX,
|
||||
"/",
|
||||
key_bindings[i].name, NULL);
|
||||
|
||||
err = NULL;
|
||||
str_val = gconf_client_get_string (default_client, key, &err);
|
||||
cleanup_error (&err);
|
||||
|
||||
update_binding (&window_bindings[i], str_val);
|
||||
update_binding (&key_bindings[i], str_val);
|
||||
|
||||
g_free (str_val);
|
||||
g_free (key);
|
||||
|
||||
key = g_strconcat (KEY_WINDOW_BINDINGS_PREFIX, "/",
|
||||
window_bindings[i].name,
|
||||
key = g_strconcat (key_bindings[i].per_window?
|
||||
KEY_WINDOW_BINDINGS_PREFIX:
|
||||
KEY_SCREEN_BINDINGS_PREFIX,
|
||||
"/",
|
||||
key_bindings[i].name,
|
||||
KEY_LIST_BINDINGS_SUFFIX, NULL);
|
||||
|
||||
err = NULL;
|
||||
|
||||
list_val = gconf_client_get_list (default_client, key, GCONF_VALUE_STRING, &err);
|
||||
cleanup_error (&err);
|
||||
|
||||
update_list_binding (&window_bindings[i], list_val, META_LIST_OF_STRINGS);
|
||||
|
||||
tmp = list_val;
|
||||
while (tmp)
|
||||
{
|
||||
g_free (tmp->data);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
g_slist_free (list_val);
|
||||
g_free (key);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (screen_bindings[i].name)
|
||||
{
|
||||
GSList *list_val, *tmp;
|
||||
char *str_val;
|
||||
char *key;
|
||||
|
||||
key = g_strconcat (KEY_SCREEN_BINDINGS_PREFIX, "/",
|
||||
screen_bindings[i].name, NULL);
|
||||
|
||||
err = NULL;
|
||||
str_val = gconf_client_get_string (default_client, key, &err);
|
||||
cleanup_error (&err);
|
||||
|
||||
update_binding (&screen_bindings[i], str_val);
|
||||
|
||||
g_free (str_val);
|
||||
g_free (key);
|
||||
|
||||
key = g_strconcat (KEY_SCREEN_BINDINGS_PREFIX, "/",
|
||||
screen_bindings[i].name,
|
||||
KEY_LIST_BINDINGS_SUFFIX, NULL);
|
||||
|
||||
err = NULL;
|
||||
|
||||
list_val = gconf_client_get_list (default_client, key, GCONF_VALUE_STRING, &err);
|
||||
cleanup_error (&err);
|
||||
|
||||
update_list_binding (&screen_bindings[i], list_val, META_LIST_OF_STRINGS);
|
||||
|
||||
update_list_binding (&key_bindings[i], list_val, META_LIST_OF_STRINGS);
|
||||
|
||||
tmp = list_val;
|
||||
while (tmp)
|
||||
@@ -2073,36 +1962,20 @@ init_bindings (void)
|
||||
#else /* HAVE_GCONF */
|
||||
int i = 0;
|
||||
int which = 0;
|
||||
while (window_string_bindings[i].name)
|
||||
while (key_string_bindings[i].name)
|
||||
{
|
||||
/* Find which window_bindings entry this window_string_bindings entry
|
||||
* corresponds to.
|
||||
*/
|
||||
while (strcmp(window_bindings[which].name,
|
||||
window_string_bindings[i].name) != 0)
|
||||
if (key_string_bindings[i].keybinding == NULL) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (strcmp(key_bindings[which].name,
|
||||
key_string_bindings[i].name) != 0)
|
||||
which++;
|
||||
|
||||
/* Set the binding */
|
||||
update_binding (&window_bindings[which],
|
||||
window_string_bindings[i].keybinding);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
which = 0;
|
||||
while (screen_string_bindings[i].name)
|
||||
{
|
||||
/* Find which window_bindings entry this window_string_bindings entry
|
||||
* corresponds to.
|
||||
*/
|
||||
while (strcmp(screen_bindings[which].name,
|
||||
screen_string_bindings[i].name) != 0)
|
||||
which++;
|
||||
|
||||
/* Set the binding */
|
||||
update_binding (&screen_bindings[which],
|
||||
screen_string_bindings[i].keybinding);
|
||||
update_binding (&key_bindings[which],
|
||||
key_string_bindings[i].keybinding);
|
||||
|
||||
++i;
|
||||
}
|
||||
@@ -2189,7 +2062,7 @@ update_binding (MetaKeyPref *binding,
|
||||
MetaVirtualModifier mods;
|
||||
MetaKeyCombo *combo;
|
||||
gboolean changed;
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Binding \"%s\" has new gconf value \"%s\"\n",
|
||||
binding->name, value ? value : "none");
|
||||
@@ -2222,8 +2095,8 @@ update_binding (MetaKeyPref *binding,
|
||||
|
||||
#ifdef HAVE_GCONF
|
||||
/* Bug 329676: Bindings which can be shifted must not have no modifiers,
|
||||
* nor only SHIFT as a modifier.
|
||||
*/
|
||||
* nor only SHIFT as a modifier.
|
||||
*/
|
||||
|
||||
if (binding->add_shift &&
|
||||
0 != keysym &&
|
||||
@@ -2257,6 +2130,11 @@ update_binding (MetaKeyPref *binding,
|
||||
binding->name,
|
||||
old_setting);
|
||||
|
||||
/* FIXME: add_shift is currently screen_bindings only, but
|
||||
* there's no really good reason it should always be.
|
||||
* So we shouldn't blindly add KEY_SCREEN_BINDINGS_PREFIX
|
||||
* onto here.
|
||||
*/
|
||||
key = g_strconcat (KEY_SCREEN_BINDINGS_PREFIX, "/",
|
||||
binding->name, NULL);
|
||||
|
||||
@@ -2460,17 +2338,10 @@ find_and_update_binding (MetaKeyPref *bindings,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_window_binding (const char *name,
|
||||
update_key_binding (const char *name,
|
||||
const char *value)
|
||||
{
|
||||
return find_and_update_binding (window_bindings, name, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_screen_binding (const char *name,
|
||||
const char *value)
|
||||
{
|
||||
return find_and_update_binding (screen_bindings, name, value);
|
||||
return find_and_update_binding (key_bindings, name, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2503,17 +2374,10 @@ find_and_update_list_binding (MetaKeyPref *bindings,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_window_list_binding (const char *name,
|
||||
update_key_list_binding (const char *name,
|
||||
GSList *value)
|
||||
{
|
||||
return find_and_update_list_binding (window_bindings, name, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_screen_list_binding (const char *name,
|
||||
GSList *value)
|
||||
{
|
||||
return find_and_update_list_binding (screen_bindings, name, value);
|
||||
return find_and_update_list_binding (key_bindings, name, value);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2816,20 +2680,12 @@ meta_prefs_get_visual_bell_type (void)
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_get_screen_bindings (const MetaKeyPref **bindings,
|
||||
meta_prefs_get_key_bindings (const MetaKeyPref **bindings,
|
||||
int *n_bindings)
|
||||
{
|
||||
|
||||
*bindings = screen_bindings;
|
||||
*n_bindings = (int) G_N_ELEMENTS (screen_bindings) - 1;
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_get_window_bindings (const MetaKeyPref **bindings,
|
||||
int *n_bindings)
|
||||
{
|
||||
*bindings = window_bindings;
|
||||
*n_bindings = (int) G_N_ELEMENTS (window_bindings) - 1;
|
||||
*bindings = key_bindings;
|
||||
*n_bindings = (int) G_N_ELEMENTS (key_bindings) - 1;
|
||||
}
|
||||
|
||||
MetaActionTitlebar
|
||||
@@ -2885,10 +2741,10 @@ meta_prefs_get_keybinding_action (const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = G_N_ELEMENTS (screen_bindings) - 2; /* -2 for dummy entry at end */
|
||||
i = G_N_ELEMENTS (key_bindings) - 2; /* -2 for dummy entry at end */
|
||||
while (i >= 0)
|
||||
{
|
||||
if (strcmp (screen_bindings[i].name, name) == 0)
|
||||
if (strcmp (key_bindings[i].name, name) == 0)
|
||||
return (MetaKeyBindingAction) i;
|
||||
|
||||
--i;
|
||||
@@ -2908,12 +2764,13 @@ meta_prefs_get_window_binding (const char *name,
|
||||
{
|
||||
int i;
|
||||
|
||||
i = G_N_ELEMENTS (window_bindings) - 2; /* -2 for dummy entry at end */
|
||||
i = G_N_ELEMENTS (key_bindings) - 2; /* -2 for dummy entry at end */
|
||||
while (i >= 0)
|
||||
{
|
||||
if (strcmp (window_bindings[i].name, name) == 0)
|
||||
if (key_bindings[i].per_window &&
|
||||
strcmp (key_bindings[i].name, name) == 0)
|
||||
{
|
||||
GSList *s = window_bindings[i].bindings;
|
||||
GSList *s = key_bindings[i].bindings;
|
||||
|
||||
while (s)
|
||||
{
|
||||
@@ -2946,9 +2803,22 @@ meta_prefs_get_compositing_manager (void)
|
||||
return compositing_manager;
|
||||
}
|
||||
|
||||
guint
|
||||
meta_prefs_get_mouse_button_resize (void)
|
||||
{
|
||||
return resize_with_right_button ? 3: 2;
|
||||
}
|
||||
|
||||
guint
|
||||
meta_prefs_get_mouse_button_menu (void)
|
||||
{
|
||||
return resize_with_right_button ? 2: 3;
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_set_compositing_manager (gboolean whether)
|
||||
{
|
||||
#ifdef HAVE_GCONF
|
||||
GError *err = NULL;
|
||||
|
||||
gconf_client_set_bool (default_client,
|
||||
@@ -2962,6 +2832,144 @@ meta_prefs_set_compositing_manager (gboolean whether)
|
||||
err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
#else
|
||||
compositing_manager = whether;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WITH_CLUTTER
|
||||
gboolean
|
||||
meta_prefs_get_clutter_disabled (void)
|
||||
{
|
||||
return clutter_disabled;
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_set_clutter_disabled (gboolean whether)
|
||||
{
|
||||
#ifdef HAVE_GCONF
|
||||
GError *err = NULL;
|
||||
|
||||
gconf_client_set_bool (default_client,
|
||||
KEY_CLUTTER_DISABLED,
|
||||
whether,
|
||||
&err);
|
||||
|
||||
if (err)
|
||||
{
|
||||
meta_warning (_("Error setting clutter status status: %s\n"),
|
||||
err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
#else
|
||||
clutter_disabled = whether;
|
||||
#endif
|
||||
}
|
||||
|
||||
GSList *
|
||||
meta_prefs_get_clutter_plugins (void)
|
||||
{
|
||||
return clutter_plugins;
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_set_clutter_plugins (GSList *list)
|
||||
{
|
||||
GError *err = NULL;
|
||||
|
||||
gconf_client_set_list (default_client,
|
||||
KEY_CLUTTER_PLUGINS,
|
||||
GCONF_VALUE_STRING,
|
||||
list,
|
||||
&err);
|
||||
|
||||
if (err)
|
||||
{
|
||||
meta_warning (_("Error setting clutter plugin list: %s\n"),
|
||||
err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_override_clutter_plugins (GSList *list)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
clutter_plugins_overridden = TRUE;
|
||||
clutter_plugins = NULL;
|
||||
|
||||
for (l = list; l; l = l->next)
|
||||
clutter_plugins = g_slist_prepend (clutter_plugins, g_strdup(l->data));
|
||||
|
||||
clutter_plugins = g_slist_reverse (clutter_plugins);
|
||||
}
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_live_hidden_windows (void)
|
||||
{
|
||||
#if 0
|
||||
return live_hidden_windows;
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_set_live_hidden_windows (gboolean whether)
|
||||
{
|
||||
#ifdef HAVE_GCONF
|
||||
GError *err = NULL;
|
||||
|
||||
gconf_client_set_bool (default_client,
|
||||
KEY_LIVE_HIDDEN_WINDOWS,
|
||||
whether,
|
||||
&err);
|
||||
|
||||
if (err)
|
||||
{
|
||||
meta_warning (_("Error setting live hidden windows status status: %s\n"),
|
||||
err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
#else
|
||||
live_hidden_windows = whether;
|
||||
#endif
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_prefs_get_no_tab_popup (void)
|
||||
{
|
||||
return no_tab_popup;
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_set_no_tab_popup (gboolean whether)
|
||||
{
|
||||
#ifdef HAVE_GCONF
|
||||
GError *err = NULL;
|
||||
|
||||
gconf_client_set_bool (default_client,
|
||||
KEY_NO_TAB_POPUP,
|
||||
whether,
|
||||
&err);
|
||||
|
||||
if (err)
|
||||
{
|
||||
meta_warning (_("Error setting no tab popup status: %s\n"),
|
||||
err->message);
|
||||
g_error_free (err);
|
||||
}
|
||||
#else
|
||||
no_tab_popup = whether;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
meta_prefs_override_no_tab_popup (gboolean whether)
|
||||
{
|
||||
no_tab_popup = whether;
|
||||
}
|
||||
|
||||
#ifndef HAVE_GCONF
|
||||
|
195
src/core/schema-bindings.c
Normal file
195
src/core/schema-bindings.c
Normal file
@@ -0,0 +1,195 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008 Thomas Thurman
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/** \file Schema bindings generator.
|
||||
*
|
||||
* This program simply takes the items given in the binding list in
|
||||
* all-keybindings.h and turns them into a portion of
|
||||
* the GConf .schemas file.
|
||||
*
|
||||
* FIXME: also need to make 50-metacity-desktop-key.xml
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include "config.h"
|
||||
|
||||
#define _(x) x
|
||||
|
||||
static void single_stanza (gboolean is_window, const char *name,
|
||||
const char *default_value,
|
||||
gboolean can_reverse,
|
||||
const char *description);
|
||||
|
||||
char *about_keybindings, *about_reversible_keybindings;
|
||||
|
||||
char *source_filename, *target_filename;
|
||||
FILE *source_file, *target_file;
|
||||
|
||||
static void
|
||||
single_stanza (gboolean is_window, const char *name,
|
||||
const char *default_value,
|
||||
gboolean can_reverse,
|
||||
const char *description)
|
||||
{
|
||||
char *keybinding_type = is_window? "window": "global";
|
||||
char *escaped_default_value, *escaped_description;
|
||||
|
||||
if (description==NULL)
|
||||
return; /* it must be undocumented, so it can't go in this table */
|
||||
|
||||
escaped_description = g_markup_escape_text (description, -1);
|
||||
escaped_default_value = default_value==NULL? "disabled":
|
||||
g_markup_escape_text (default_value, -1);
|
||||
|
||||
fprintf (target_file, " <schema>\n");
|
||||
fprintf (target_file, " <key>/schemas/apps/metacity/%s_keybindings/%s</key>\n",
|
||||
keybinding_type, name);
|
||||
fprintf (target_file, " <applyto>/apps/metacity/%s_keybindings/%s</applyto>\n",
|
||||
keybinding_type, name);
|
||||
fprintf (target_file, " <owner>metacity</owner>\n");
|
||||
fprintf (target_file, " <type>string</type>\n");
|
||||
fprintf (target_file, " <default>%s</default>\n", escaped_default_value);
|
||||
|
||||
fprintf (target_file, " <locale name=\"C\">\n");
|
||||
fprintf (target_file, " <short>%s</short>\n", description);
|
||||
fprintf (target_file, " <long>%s</long>\n",
|
||||
can_reverse? about_reversible_keybindings:
|
||||
about_keybindings);
|
||||
fprintf (target_file, " </locale>\n");
|
||||
fprintf (target_file, " </schema>\n\n");
|
||||
|
||||
g_free (escaped_description);
|
||||
|
||||
if (default_value!=NULL)
|
||||
g_free (escaped_default_value);
|
||||
}
|
||||
|
||||
static void produce_bindings ();
|
||||
|
||||
static void
|
||||
produce_bindings ()
|
||||
{
|
||||
/* 10240 is ridiculous overkill; we're writing the input file and
|
||||
* the lines are always 80 chars or less.
|
||||
*/
|
||||
char buffer[10240];
|
||||
|
||||
source_file = fopen(source_filename, "r");
|
||||
|
||||
if (!source_file)
|
||||
{
|
||||
g_error ("Cannot compile without %s: %s\n",
|
||||
source_filename, strerror (errno));
|
||||
}
|
||||
|
||||
target_file = fopen(target_filename, "w");
|
||||
|
||||
if (!target_file)
|
||||
{
|
||||
g_error ("Cannot create %s: %s\n",
|
||||
target_filename, strerror (errno));
|
||||
}
|
||||
|
||||
while (fgets (buffer, sizeof (buffer), source_file))
|
||||
{
|
||||
if (strstr (buffer, "<!-- GENERATED -->"))
|
||||
break;
|
||||
|
||||
fprintf (target_file, "%s", buffer);
|
||||
}
|
||||
|
||||
if (!feof (source_file))
|
||||
{
|
||||
#define keybind(name, handler, param, flags, stroke, description) \
|
||||
single_stanza ( \
|
||||
flags & BINDING_PER_WINDOW, \
|
||||
#name, \
|
||||
stroke, \
|
||||
flags & BINDING_REVERSES, \
|
||||
description);
|
||||
#include "all-keybindings.h"
|
||||
#undef keybind
|
||||
}
|
||||
|
||||
while (fgets (buffer, sizeof (buffer), source_file))
|
||||
fprintf (target_file, "%s", buffer);
|
||||
|
||||
if (fclose (source_file)!=0)
|
||||
{
|
||||
g_error ("Cannot close %s: %s\n",
|
||||
source_filename, strerror (errno));
|
||||
}
|
||||
|
||||
if (fclose (target_file)!=0)
|
||||
{
|
||||
g_error ("Cannot close %s: %s\n",
|
||||
target_filename, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (argc!=3)
|
||||
{
|
||||
g_error ("Syntax: %s <source.in.in> <target.in>\n", argv[0]);
|
||||
}
|
||||
|
||||
source_filename = argv[1];
|
||||
target_filename = argv[2];
|
||||
|
||||
/* Translators: Please don't translate "Control", "Shift", etc, since these
|
||||
* are hardcoded (in gtk/gtkaccelgroup.c; it's not metacity's fault).
|
||||
* "disabled" must also stay as it is.
|
||||
*/
|
||||
about_keybindings = g_markup_escape_text(_( \
|
||||
"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n\n"\
|
||||
"The parser is fairly liberal and allows "\
|
||||
"lower or upper case, and also abbreviations such as \"<Ctl>\" and " \
|
||||
"\"<Ctrl>\". If you set the option to the special string " \
|
||||
"\"disabled\", then there will be no keybinding for this action."),
|
||||
-1);
|
||||
|
||||
about_reversible_keybindings = g_markup_escape_text(_( \
|
||||
"The format looks like \"<Control>a\" or <Shift><Alt>F1\".\n\n"\
|
||||
"The parser is fairly liberal and allows "\
|
||||
"lower or upper case, and also abbreviations such as \"<Ctl>\" and " \
|
||||
"\"<Ctrl>\". If you set the option to the special string " \
|
||||
"\"disabled\", then there will be no keybinding for this action.\n\n"\
|
||||
"This keybinding may be reversed by holding down the \"shift\" key; "
|
||||
"therefore, \"shift\" cannot be one of the keys it uses."),
|
||||
-1);
|
||||
|
||||
produce_bindings ();
|
||||
|
||||
g_free (about_keybindings);
|
||||
g_free (about_reversible_keybindings);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* eof schema-bindings.c */
|
||||
|
@@ -69,6 +69,8 @@ typedef enum
|
||||
|
||||
struct _MetaScreen
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
MetaDisplay *display;
|
||||
int number;
|
||||
char *screen_name;
|
||||
@@ -132,6 +134,16 @@ struct _MetaScreen
|
||||
|
||||
/* Managed by compositor.c */
|
||||
gpointer compositor_data;
|
||||
|
||||
/* Instead of unmapping withdrawn windows we can leave them mapped
|
||||
* and restack them below a guard window. When using a compositor
|
||||
* this allows us to provide live previews of unmapped windows */
|
||||
Window guard_window;
|
||||
};
|
||||
|
||||
struct _MetaScreenClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
MetaScreen* meta_screen_new (MetaDisplay *display,
|
||||
@@ -146,11 +158,6 @@ void meta_screen_foreach_window (MetaScreen *scree
|
||||
void meta_screen_queue_frame_redraws (MetaScreen *screen);
|
||||
void meta_screen_queue_window_resizes (MetaScreen *screen);
|
||||
|
||||
int meta_screen_get_n_workspaces (MetaScreen *screen);
|
||||
|
||||
MetaWorkspace* meta_screen_get_workspace_by_index (MetaScreen *screen,
|
||||
int index);
|
||||
|
||||
void meta_screen_set_cursor (MetaScreen *screen,
|
||||
MetaCursor cursor);
|
||||
void meta_screen_update_cursor (MetaScreen *screen);
|
||||
|
@@ -33,8 +33,8 @@
|
||||
#include "window-private.h"
|
||||
#include "frame-private.h"
|
||||
#include "prefs.h"
|
||||
#include "workspace.h"
|
||||
#include "keybindings.h"
|
||||
#include "workspace-private.h"
|
||||
#include "keybindings-private.h"
|
||||
#include "stack.h"
|
||||
#include "xprops.h"
|
||||
#include "compositor.h"
|
||||
@@ -69,6 +69,82 @@ static void meta_screen_sn_event (SnMonitorEvent *event,
|
||||
void *user_data);
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_N_WORKSPACES = 1
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaScreen, meta_screen, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
meta_screen_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
#if 0
|
||||
MetaScreen *screen = META_SCREEN (object);
|
||||
#endif
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaScreen *screen = META_SCREEN (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_N_WORKSPACES:
|
||||
g_value_set_int (value, meta_screen_get_n_workspaces (screen));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_finalize (GObject *object)
|
||||
{
|
||||
/* Actual freeing done in meta_screen_free() for now */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_class_init (MetaScreenClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->get_property = meta_screen_get_property;
|
||||
object_class->set_property = meta_screen_set_property;
|
||||
object_class->finalize = meta_screen_finalize;
|
||||
|
||||
pspec = g_param_spec_int ("n-workspaces",
|
||||
"N Workspaces",
|
||||
"Number of workspaces",
|
||||
1, G_MAXINT, 1,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_N_WORKSPACES,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_screen_init (MetaScreen *screen)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
set_wm_check_hint (MetaScreen *screen)
|
||||
{
|
||||
@@ -311,6 +387,38 @@ reload_xinerama_infos (MetaScreen *screen)
|
||||
g_assert (screen->xinerama_infos != NULL);
|
||||
}
|
||||
|
||||
/* The guard window allows us to leave minimized windows mapped so
|
||||
* that compositor code may provide live previews of them.
|
||||
* Instead of being unmapped/withdrawn, they get pushed underneath
|
||||
* the guard window. */
|
||||
static Window
|
||||
create_guard_window (Display *xdisplay, MetaScreen *screen)
|
||||
{
|
||||
XSetWindowAttributes attributes;
|
||||
Window guard_window;
|
||||
|
||||
attributes.event_mask = NoEventMask;
|
||||
attributes.override_redirect = True;
|
||||
attributes.background_pixel = BlackPixel (xdisplay, screen->number);
|
||||
|
||||
guard_window =
|
||||
XCreateWindow (xdisplay,
|
||||
screen->xroot,
|
||||
0, /* x */
|
||||
0, /* y */
|
||||
screen->rect.width,
|
||||
screen->rect.height,
|
||||
0, /* border width */
|
||||
CopyFromParent, /* depth */
|
||||
CopyFromParent, /* class */
|
||||
CopyFromParent, /* visual */
|
||||
CWEventMask|CWOverrideRedirect|CWBackPixel,
|
||||
&attributes);
|
||||
XLowerWindow (xdisplay, guard_window);
|
||||
XMapWindow (xdisplay, guard_window);
|
||||
return guard_window;
|
||||
}
|
||||
|
||||
MetaScreen*
|
||||
meta_screen_new (MetaDisplay *display,
|
||||
int number,
|
||||
@@ -456,7 +564,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen = g_new (MetaScreen, 1);
|
||||
screen = g_object_new (META_TYPE_SCREEN, NULL);
|
||||
screen->closing = 0;
|
||||
|
||||
screen->display = display;
|
||||
@@ -490,6 +598,8 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->vertical_workspaces = FALSE;
|
||||
screen->starting_corner = META_SCREEN_TOPLEFT;
|
||||
screen->compositor_data = NULL;
|
||||
|
||||
screen->guard_window = create_guard_window (xdisplay, screen);
|
||||
|
||||
{
|
||||
XFontStruct *font_info;
|
||||
@@ -684,7 +794,8 @@ meta_screen_free (MetaScreen *screen,
|
||||
g_free (screen->xinerama_infos);
|
||||
|
||||
g_free (screen->screen_name);
|
||||
g_free (screen);
|
||||
|
||||
g_object_unref (screen);
|
||||
|
||||
XFlush (display->xdisplay);
|
||||
meta_display_ungrab (display);
|
||||
@@ -756,19 +867,6 @@ meta_screen_manage_all_windows (MetaScreen *screen)
|
||||
|
||||
window = meta_window_new_with_attrs (screen->display, info->xwindow, TRUE,
|
||||
&info->attrs);
|
||||
if (info->xwindow == screen->no_focus_window ||
|
||||
info->xwindow == screen->flash_window ||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
info->xwindow == screen->wm_cm_selection_window ||
|
||||
#endif
|
||||
info->xwindow == screen->wm_sn_selection_window) {
|
||||
meta_verbose ("Not managing our own windows\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (screen->display->compositor)
|
||||
meta_compositor_add_window (screen->display->compositor, window,
|
||||
info->xwindow, &info->attrs);
|
||||
}
|
||||
meta_stack_thaw (screen->stack);
|
||||
|
||||
@@ -783,38 +881,20 @@ meta_screen_composite_all_windows (MetaScreen *screen)
|
||||
{
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
MetaDisplay *display;
|
||||
GList *windows, *list;
|
||||
GSList *windows, *tmp;
|
||||
|
||||
display = screen->display;
|
||||
if (!display->compositor)
|
||||
return;
|
||||
|
||||
windows = list_windows (screen);
|
||||
|
||||
windows = meta_display_list_windows (display);
|
||||
for (tmp = windows; tmp != NULL; tmp = tmp->next)
|
||||
meta_compositor_add_window (display->compositor, tmp->data);
|
||||
g_slist_free (windows);
|
||||
|
||||
/* trigger a stack_sync_to_server: */
|
||||
meta_stack_freeze (screen->stack);
|
||||
|
||||
for (list = windows; list != NULL; list = list->next)
|
||||
{
|
||||
WindowInfo *info = list->data;
|
||||
|
||||
if (info->xwindow == screen->no_focus_window ||
|
||||
info->xwindow == screen->flash_window ||
|
||||
info->xwindow == screen->wm_sn_selection_window ||
|
||||
info->xwindow == screen->wm_cm_selection_window) {
|
||||
meta_verbose ("Not managing our own windows\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
meta_compositor_add_window (display->compositor,
|
||||
meta_display_lookup_x_window (display,
|
||||
info->xwindow),
|
||||
info->xwindow, &info->attrs);
|
||||
}
|
||||
|
||||
meta_stack_thaw (screen->stack);
|
||||
|
||||
g_list_foreach (windows, (GFunc)g_free, NULL);
|
||||
g_list_free (windows);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1071,6 +1151,93 @@ set_desktop_viewport_hint (MetaScreen *screen)
|
||||
meta_error_trap_pop (screen->display, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
|
||||
guint32 timestamp)
|
||||
{
|
||||
GList *l;
|
||||
MetaWorkspace *neighbour = NULL;
|
||||
GList *next = NULL;
|
||||
|
||||
l = screen->workspaces;
|
||||
while (l)
|
||||
{
|
||||
MetaWorkspace *w = l->data;
|
||||
|
||||
if (w == workspace)
|
||||
{
|
||||
if (l->next)
|
||||
next = l->next;
|
||||
|
||||
if (l->prev)
|
||||
neighbour = l->prev->data;
|
||||
else if (l->next)
|
||||
neighbour = l->next->data;
|
||||
else
|
||||
{
|
||||
/* Cannot remove the only workspace! */
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
if (!neighbour)
|
||||
return;
|
||||
|
||||
meta_workspace_relocate_windows (workspace, neighbour);
|
||||
|
||||
if (workspace == screen->active_workspace)
|
||||
meta_workspace_activate (neighbour, timestamp);
|
||||
|
||||
/* This also removes the workspace from the screens list */
|
||||
meta_workspace_remove (workspace);
|
||||
|
||||
set_number_of_spaces_hint (screen, g_list_length (screen->workspaces));
|
||||
|
||||
l = next;
|
||||
while (l)
|
||||
{
|
||||
MetaWorkspace *w = l->data;
|
||||
|
||||
meta_workspace_update_window_hints (w);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
meta_screen_queue_workarea_recalc (screen);
|
||||
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
}
|
||||
|
||||
MetaWorkspace *
|
||||
meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWorkspace *w;
|
||||
|
||||
/* This also adds the workspace to the screen list */
|
||||
w = meta_workspace_new (screen);
|
||||
|
||||
if (!w)
|
||||
return NULL;
|
||||
|
||||
if (activate)
|
||||
meta_workspace_activate (w, timestamp);
|
||||
|
||||
set_number_of_spaces_hint (screen, g_list_length (screen->workspaces));
|
||||
|
||||
meta_screen_queue_workarea_recalc (screen);
|
||||
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
update_num_workspaces (MetaScreen *screen,
|
||||
guint32 timestamp)
|
||||
@@ -1135,7 +1302,7 @@ update_num_workspaces (MetaScreen *screen,
|
||||
MetaWorkspace *w = tmp->data;
|
||||
|
||||
g_assert (w->windows == NULL);
|
||||
meta_workspace_free (w);
|
||||
meta_workspace_remove (w);
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
@@ -1151,6 +1318,8 @@ update_num_workspaces (MetaScreen *screen,
|
||||
set_number_of_spaces_hint (screen, new_num);
|
||||
|
||||
meta_screen_queue_workarea_recalc (screen);
|
||||
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1352,11 +1521,12 @@ meta_screen_ensure_tab_popup (MetaScreen *screen,
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
screen->tab_popup = meta_ui_tab_popup_new (entries,
|
||||
screen->number,
|
||||
len,
|
||||
5, /* FIXME */
|
||||
TRUE);
|
||||
if (!meta_prefs_get_no_tab_popup ())
|
||||
screen->tab_popup = meta_ui_tab_popup_new (entries,
|
||||
screen->number,
|
||||
len,
|
||||
5, /* FIXME */
|
||||
TRUE);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
g_object_unref (entries[i].icon);
|
||||
@@ -1378,7 +1548,7 @@ meta_screen_ensure_workspace_popup (MetaScreen *screen)
|
||||
int n_workspaces;
|
||||
int current_workspace;
|
||||
|
||||
if (screen->tab_popup)
|
||||
if (screen->tab_popup || meta_prefs_get_no_tab_popup ())
|
||||
return;
|
||||
|
||||
current_workspace = meta_workspace_index (screen->active_workspace);
|
||||
@@ -2284,6 +2454,10 @@ meta_screen_resize (MetaScreen *screen,
|
||||
reload_xinerama_infos (screen);
|
||||
set_desktop_geometry_hint (screen);
|
||||
|
||||
if (screen->display->compositor)
|
||||
meta_compositor_sync_screen_size (screen->display->compositor,
|
||||
screen, width, height);
|
||||
|
||||
/* Queue a resize on all the windows */
|
||||
meta_screen_foreach_window (screen, meta_screen_resize_func, 0);
|
||||
}
|
||||
@@ -2800,3 +2974,26 @@ meta_screen_unset_cm_selection (MetaScreen *screen)
|
||||
XSetSelectionOwner (screen->display->xdisplay, a, None, CurrentTime);
|
||||
}
|
||||
#endif /* HAVE_COMPOSITE_EXTENSIONS */
|
||||
|
||||
GList *
|
||||
meta_screen_get_workspaces (MetaScreen *screen)
|
||||
{
|
||||
return screen->workspaces;
|
||||
}
|
||||
|
||||
int
|
||||
meta_screen_get_active_workspace_index (MetaScreen *screen)
|
||||
{
|
||||
MetaWorkspace *active = screen->active_workspace;
|
||||
|
||||
if (!active)
|
||||
return -1;
|
||||
|
||||
return meta_workspace_index (active);
|
||||
}
|
||||
|
||||
MetaWorkspace *
|
||||
meta_screen_get_active_workspace (MetaScreen *screen)
|
||||
{
|
||||
return screen->active_workspace;
|
||||
}
|
||||
|
@@ -698,6 +698,20 @@ window_type_to_string (MetaWindowType type)
|
||||
return "splashscreen";
|
||||
case META_WINDOW_UTILITY:
|
||||
return "utility";
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
return "dropdown_menu";
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
return "popup_menu";
|
||||
case META_WINDOW_TOOLTIP:
|
||||
return "tooltip";
|
||||
case META_WINDOW_NOTIFICATION:
|
||||
return "notification";
|
||||
case META_WINDOW_COMBO:
|
||||
return "combo";
|
||||
case META_WINDOW_DND:
|
||||
return "dnd";
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
return "override_redirect";
|
||||
}
|
||||
|
||||
return "";
|
||||
@@ -1191,8 +1205,8 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
_("Unknown attribute %s on <metacity_session> element"),
|
||||
name);
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "metacity_session");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1266,8 +1280,8 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
_("Unknown attribute %s on <window> element"),
|
||||
name);
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "window");
|
||||
session_info_free (pd->info);
|
||||
pd->info = NULL;
|
||||
return;
|
||||
@@ -1298,8 +1312,8 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
_("Unknown attribute %s on <window> element"),
|
||||
name);
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "window");
|
||||
session_info_free (pd->info);
|
||||
pd->info = NULL;
|
||||
return;
|
||||
@@ -1370,8 +1384,8 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
_("Unknown attribute %s on <maximized> element"),
|
||||
name);
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "maximized");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1430,8 +1444,8 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
_("Unknown attribute %s on <geometry> element"),
|
||||
name);
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "geometry");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -35,6 +35,10 @@
|
||||
#include "prefs.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
#include "compositor.h"
|
||||
#endif
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#define WINDOW_HAS_TRANSIENT_TYPE(w) \
|
||||
@@ -240,7 +244,13 @@ get_standalone_layer (MetaWindow *window)
|
||||
{
|
||||
MetaStackLayer layer;
|
||||
gboolean focused_transient = FALSE;
|
||||
|
||||
|
||||
if (window->hidden)
|
||||
{
|
||||
layer = META_LAYER_DESKTOP;
|
||||
return layer;
|
||||
}
|
||||
|
||||
switch (window->type)
|
||||
{
|
||||
case META_WINDOW_DESKTOP:
|
||||
@@ -255,6 +265,14 @@ get_standalone_layer (MetaWindow *window)
|
||||
layer = META_LAYER_DOCK;
|
||||
break;
|
||||
|
||||
case META_WINDOW_DROPDOWN_MENU:
|
||||
case META_WINDOW_POPUP_MENU:
|
||||
case META_WINDOW_TOOLTIP:
|
||||
case META_WINDOW_NOTIFICATION:
|
||||
case META_WINDOW_COMBO:
|
||||
case META_WINDOW_OVERRIDE_OTHER:
|
||||
layer = META_LAYER_OVERRIDE_REDIRECT;
|
||||
break;
|
||||
default:
|
||||
meta_window_foreach_transient (window,
|
||||
is_focused_foreach,
|
||||
@@ -306,9 +324,12 @@ get_maximum_layer_in_group (MetaWindow *window)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
layer = get_standalone_layer (w);
|
||||
if (layer > max)
|
||||
max = layer;
|
||||
if (!w->override_redirect)
|
||||
{
|
||||
layer = get_standalone_layer (w);
|
||||
if (layer > max)
|
||||
max = layer;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
@@ -329,7 +350,8 @@ compute_layer (MetaWindow *window)
|
||||
* windows getting in fullscreen layer if any terminal is
|
||||
* fullscreen.
|
||||
*/
|
||||
if (WINDOW_HAS_TRANSIENT_TYPE(window) &&
|
||||
if (window->layer != META_LAYER_DESKTOP &&
|
||||
WINDOW_HAS_TRANSIENT_TYPE(window) &&
|
||||
(window->xtransient_for == None ||
|
||||
window->transient_parent_is_root_window))
|
||||
{
|
||||
@@ -520,7 +542,8 @@ create_constraints (Constraint **constraints,
|
||||
MetaWindow *group_window = tmp2->data;
|
||||
|
||||
if (!WINDOW_IN_STACK (group_window) ||
|
||||
w->screen != group_window->screen)
|
||||
w->screen != group_window->screen ||
|
||||
group_window->override_redirect)
|
||||
{
|
||||
tmp2 = tmp2->next;
|
||||
continue;
|
||||
@@ -854,7 +877,6 @@ stack_do_relayer (MetaStack *stack)
|
||||
meta_topic (META_DEBUG_STACK,
|
||||
"Window %s moved from layer %u to %u\n",
|
||||
w->desc, old_layer, w->layer);
|
||||
|
||||
stack->need_resort = TRUE;
|
||||
stack->need_constrain = TRUE;
|
||||
/* don't need to constrain as constraining
|
||||
@@ -1051,6 +1073,8 @@ stack_sync_to_server (MetaStack *stack)
|
||||
GArray *stacked;
|
||||
GArray *root_children_stacked;
|
||||
GList *tmp;
|
||||
GArray *all_hidden;
|
||||
int n_override_redirect = 0;
|
||||
|
||||
/* Bail out if frozen */
|
||||
if (stack->freeze_count > 0)
|
||||
@@ -1059,6 +1083,10 @@ stack_sync_to_server (MetaStack *stack)
|
||||
meta_topic (META_DEBUG_STACK, "Syncing window stack to server\n");
|
||||
|
||||
stack_ensure_sorted (stack);
|
||||
|
||||
meta_compositor_sync_stack (stack->screen->display->compositor,
|
||||
stack->screen,
|
||||
stack->sorted);
|
||||
|
||||
/* Create stacked xwindow arrays.
|
||||
* Painfully, "stacked" is in bottom-to-top order for the
|
||||
@@ -1067,36 +1095,52 @@ stack_sync_to_server (MetaStack *stack)
|
||||
*/
|
||||
stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||
root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||
all_hidden = g_array_new (FALSE, FALSE, sizeof (Window));
|
||||
|
||||
/* The screen guard window sits above all hidden windows and acts as
|
||||
* a barrier to input reaching these windows. */
|
||||
g_array_append_val (all_hidden, stack->screen->guard_window);
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "Top to bottom: ");
|
||||
meta_push_no_msg_prefix ();
|
||||
|
||||
tmp = stack->sorted;
|
||||
while (tmp != NULL)
|
||||
|
||||
for (tmp = stack->sorted; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
MetaWindow *w;
|
||||
|
||||
w = tmp->data;
|
||||
MetaWindow *w = tmp->data;
|
||||
Window top_level_window;
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "%u:%d - %s ",
|
||||
w->layer, w->stack_position, w->desc);
|
||||
|
||||
/* remember, stacked is in reverse order (bottom to top) */
|
||||
g_array_prepend_val (stacked, w->xwindow);
|
||||
|
||||
/* build XRestackWindows() array from top to bottom */
|
||||
if (w->frame)
|
||||
g_array_append_val (root_children_stacked, w->frame->xwindow);
|
||||
if (w->override_redirect)
|
||||
n_override_redirect++;
|
||||
else
|
||||
g_array_append_val (root_children_stacked, w->xwindow);
|
||||
g_array_prepend_val (stacked, w->xwindow);
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "%u:%d - %s ", w->layer, w->stack_position, w->desc);
|
||||
|
||||
tmp = tmp->next;
|
||||
if (w->frame)
|
||||
top_level_window = w->frame->xwindow;
|
||||
else
|
||||
top_level_window = w->xwindow;
|
||||
|
||||
/* We don't restack hidden windows along with the rest, though they are
|
||||
* reflected in the _NET hints. Hidden windows all get pushed below
|
||||
* the screens fullscreen guard_window. */
|
||||
if (w->hidden)
|
||||
{
|
||||
g_array_append_val (all_hidden, top_level_window);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* build XRestackWindows() array from top to bottom */
|
||||
g_array_append_val (root_children_stacked, top_level_window);
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "\n");
|
||||
meta_pop_no_msg_prefix ();
|
||||
|
||||
/* All windows should be in some stacking order */
|
||||
if (stacked->len != stack->windows->len)
|
||||
if (stacked->len != stack->windows->len - n_override_redirect)
|
||||
meta_bug ("%u windows stacked, %u windows exist in stack\n",
|
||||
stacked->len, stack->windows->len);
|
||||
|
||||
@@ -1207,6 +1251,13 @@ stack_sync_to_server (MetaStack *stack)
|
||||
}
|
||||
}
|
||||
|
||||
/* Push hidden windows to the bottom of the stack under the guard window */
|
||||
XLowerWindow (stack->screen->display->xdisplay, stack->screen->guard_window);
|
||||
XRestackWindows (stack->screen->display->xdisplay,
|
||||
(Window *)all_hidden->data,
|
||||
all_hidden->len);
|
||||
g_array_free (all_hidden, TRUE);
|
||||
|
||||
meta_error_trap_pop (stack->screen->display, FALSE);
|
||||
/* on error, a window was destroyed; it should eventually
|
||||
* get removed from the stacking list when we unmanage it
|
||||
|
@@ -49,14 +49,15 @@
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_LAYER_DESKTOP = 0,
|
||||
META_LAYER_BOTTOM = 1,
|
||||
META_LAYER_NORMAL = 2,
|
||||
META_LAYER_TOP = 4, /* Same as DOCK; see EWMH and bug 330717 */
|
||||
META_LAYER_DOCK = 4,
|
||||
META_LAYER_FULLSCREEN = 5,
|
||||
META_LAYER_FOCUSED_WINDOW = 6,
|
||||
META_LAYER_LAST = 7
|
||||
META_LAYER_DESKTOP = 0,
|
||||
META_LAYER_BOTTOM = 1,
|
||||
META_LAYER_NORMAL = 2,
|
||||
META_LAYER_TOP = 4, /* Same as DOCK; see EWMH and bug 330717 */
|
||||
META_LAYER_DOCK = 4,
|
||||
META_LAYER_FULLSCREEN = 5,
|
||||
META_LAYER_FOCUSED_WINDOW = 6,
|
||||
META_LAYER_OVERRIDE_REDIRECT = 7,
|
||||
META_LAYER_LAST = 8
|
||||
} MetaStackLayer;
|
||||
|
||||
/**
|
||||
|
@@ -187,7 +187,7 @@ try_get_reply (Display *xdisplay,
|
||||
int actual_format;
|
||||
unsigned long n_items;
|
||||
unsigned long bytes_after;
|
||||
char *data;
|
||||
unsigned char *data;
|
||||
char *name;
|
||||
struct timeval current_time;
|
||||
|
||||
@@ -421,7 +421,7 @@ run_speed_comparison (Display *xdisplay,
|
||||
int actual_format;
|
||||
unsigned long n_items;
|
||||
unsigned long bytes_after;
|
||||
char *data;
|
||||
unsigned char *data;
|
||||
|
||||
assert (ag_task_have_reply (task));
|
||||
|
||||
|
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#define _POSIX_C_SOURCE /* for fdopen() */
|
||||
#define _POSIX_C_SOURCE 200112L /* for fdopen() */
|
||||
|
||||
#include <config.h>
|
||||
#include "util.h"
|
||||
@@ -537,3 +537,75 @@ meta_gravity_to_string (int gravity)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_show_dialog (const char *type,
|
||||
const char *message,
|
||||
const char *timeout,
|
||||
const gint screen_number,
|
||||
const char **columns,
|
||||
const char **entries)
|
||||
{
|
||||
GError *error = NULL;
|
||||
char *screen_number_text = g_strdup_printf("%d", screen_number);
|
||||
|
||||
/*
|
||||
We want:
|
||||
|
||||
zenity --display X --screen S --title Metacity --error --text "There was an error running <tt>terminal</tt>:\n\nYour computer is on fire."
|
||||
** with no pipes
|
||||
|
||||
zenity --display X --screen S --title Metacity --question --text "<big><b><tt>%s</tt> is not responding.</b></big>\n\n<i>You may choose to wait a short while for it to continue or force the application to quit entirely.</i>"
|
||||
|
||||
zenity --display X --screen S --title Metacity --list --timeout 240 --text "These windows do not support \"save current setup\" and will have to be restarted manually next time you log in." --column "Window" --column "Class" "Firefox" "foo" "Duke Nukem Forever" "bar"
|
||||
*/
|
||||
|
||||
const char **argvl;
|
||||
int i=0;
|
||||
GPid child_pid;
|
||||
|
||||
argvl = g_malloc(sizeof (char*) *
|
||||
(9 + (timeout?2:0))
|
||||
);
|
||||
|
||||
argvl[i++] = "zenity";
|
||||
argvl[i++] = type;
|
||||
argvl[i++] = "--screen";
|
||||
argvl[i++] = screen_number_text;
|
||||
argvl[i++] = "--title";
|
||||
/* Translators: This is the title used on dialog boxes */
|
||||
argvl[i++] = _("Metacity");
|
||||
argvl[i++] = "--text";
|
||||
argvl[i++] = message;
|
||||
|
||||
if (timeout)
|
||||
{
|
||||
argvl[i++] = "--timeout";
|
||||
argvl[i++] = timeout;
|
||||
}
|
||||
|
||||
argvl[i] = NULL;
|
||||
|
||||
g_spawn_async_with_pipes (
|
||||
"/",
|
||||
(char**) argvl, /* ugh */
|
||||
NULL,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL,
|
||||
&child_pid,
|
||||
NULL, NULL, NULL,
|
||||
&error
|
||||
);
|
||||
|
||||
g_free (argvl);
|
||||
g_free (screen_number_text);
|
||||
|
||||
if (error)
|
||||
{
|
||||
meta_warning ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
/* eof util.c */
|
||||
|
||||
|
@@ -43,31 +43,11 @@
|
||||
#include <X11/Xutil.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
typedef struct _MetaGroup MetaGroup;
|
||||
typedef struct _MetaWindowQueue MetaWindowQueue;
|
||||
|
||||
typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window,
|
||||
void *data);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_WINDOW_NORMAL,
|
||||
META_WINDOW_DESKTOP,
|
||||
META_WINDOW_DOCK,
|
||||
META_WINDOW_DIALOG,
|
||||
META_WINDOW_MODAL_DIALOG,
|
||||
META_WINDOW_TOOLBAR,
|
||||
META_WINDOW_MENU,
|
||||
META_WINDOW_UTILITY,
|
||||
META_WINDOW_SPLASHSCREEN
|
||||
} MetaWindowType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_MAXIMIZE_HORIZONTAL = 1 << 0,
|
||||
META_MAXIMIZE_VERTICAL = 1 << 1
|
||||
} MetaMaximizeFlags;
|
||||
|
||||
typedef enum {
|
||||
META_CLIENT_TYPE_UNKNOWN = 0,
|
||||
META_CLIENT_TYPE_APPLICATION = 1,
|
||||
@@ -85,6 +65,8 @@ typedef enum {
|
||||
|
||||
struct _MetaWindow
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
MetaDisplay *display;
|
||||
MetaScreen *screen;
|
||||
MetaWorkspace *workspace;
|
||||
@@ -129,6 +111,9 @@ struct _MetaWindow
|
||||
/* Initial timestamp property */
|
||||
guint32 initial_timestamp;
|
||||
|
||||
/* Whether this is an override redirect window or not */
|
||||
guint override_redirect : 1;
|
||||
|
||||
/* Whether we're maximized */
|
||||
guint maximized_horizontally : 1;
|
||||
guint maximized_vertically : 1;
|
||||
@@ -143,6 +128,12 @@ struct _MetaWindow
|
||||
|
||||
/* Whether we're fullscreen */
|
||||
guint fullscreen : 1;
|
||||
|
||||
/* Area to cover when in fullscreen mode. If _NET_WM_FULLSCREEN_MONITORS has
|
||||
* been overridden (via a client message), the window will cover the union of
|
||||
* these monitors. If not, this is the single monitor which the window's
|
||||
* origin is on. */
|
||||
long fullscreen_monitors[4];
|
||||
|
||||
/* Whether we're trying to constrain the window to be fully onscreen */
|
||||
guint require_fully_onscreen : 1;
|
||||
@@ -169,6 +160,11 @@ struct _MetaWindow
|
||||
*/
|
||||
guint mapped : 1;
|
||||
|
||||
/* Whether window has been hidden from view by lowering it to the bottom
|
||||
* of window stack.
|
||||
*/
|
||||
guint hidden : 1;
|
||||
|
||||
/* Iconic is the state in WM_STATE; happens for workspaces/shading
|
||||
* in addition to minimize
|
||||
*/
|
||||
@@ -247,7 +243,7 @@ struct _MetaWindow
|
||||
/* Has this window not ever been shown yet? */
|
||||
guint showing_for_first_time : 1;
|
||||
|
||||
/* Are we in meta_window_free()? */
|
||||
/* Are we in meta_window_unmanage()? */
|
||||
guint unmanaging : 1;
|
||||
|
||||
/* Are we in meta_window_new()? */
|
||||
@@ -362,6 +358,19 @@ struct _MetaWindow
|
||||
|
||||
/* maintained by group.c */
|
||||
MetaGroup *group;
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
GObject *compositor_private;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _MetaWindowClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (*workspace_changed) (MetaWindow *window, int old_workspace);
|
||||
void (*focus) (MetaWindow *window);
|
||||
void (*raised) (MetaWindow *window);
|
||||
};
|
||||
|
||||
/* These differ from window->has_foo_func in that they consider
|
||||
@@ -387,7 +396,7 @@ MetaWindow* meta_window_new_with_attrs (MetaDisplay *display,
|
||||
Window xwindow,
|
||||
gboolean must_be_viewable,
|
||||
XWindowAttributes *attrs);
|
||||
void meta_window_free (MetaWindow *window,
|
||||
void meta_window_unmanage (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
void meta_window_calc_showing (MetaWindow *window);
|
||||
void meta_window_queue (MetaWindow *window,
|
||||
@@ -412,14 +421,14 @@ void meta_window_change_workspace (MetaWindow *window,
|
||||
void meta_window_stick (MetaWindow *window);
|
||||
void meta_window_unstick (MetaWindow *window);
|
||||
|
||||
void meta_window_activate (MetaWindow *window,
|
||||
guint32 current_time);
|
||||
void meta_window_activate_with_workspace (MetaWindow *window,
|
||||
guint32 current_time,
|
||||
MetaWorkspace *workspace);
|
||||
void meta_window_make_fullscreen_internal (MetaWindow *window);
|
||||
void meta_window_make_fullscreen (MetaWindow *window);
|
||||
void meta_window_unmake_fullscreen (MetaWindow *window);
|
||||
void meta_window_update_fullscreen_monitors (MetaWindow *window,
|
||||
unsigned long top,
|
||||
unsigned long bottom,
|
||||
unsigned long left,
|
||||
unsigned long right);
|
||||
|
||||
/* args to move are window pos, not frame pos */
|
||||
void meta_window_move (MetaWindow *window,
|
||||
@@ -443,9 +452,6 @@ void meta_window_resize_with_gravity (MetaWindow *window,
|
||||
int gravity);
|
||||
|
||||
|
||||
/* Return whether the window would be showing if we were on its workspace */
|
||||
gboolean meta_window_showing_on_its_workspace (MetaWindow *window);
|
||||
|
||||
/* Return whether the window should be currently mapped */
|
||||
gboolean meta_window_should_be_showing (MetaWindow *window);
|
||||
|
||||
@@ -482,8 +488,6 @@ void meta_window_get_geometry (MetaWindow *window,
|
||||
int *y,
|
||||
int *width,
|
||||
int *height);
|
||||
void meta_window_get_outer_rect (const MetaWindow *window,
|
||||
MetaRectangle *rect);
|
||||
void meta_window_get_xor_rect (MetaWindow *window,
|
||||
const MetaRectangle *grab_wireframe_rect,
|
||||
MetaRectangle *xor_rect);
|
||||
@@ -601,9 +605,8 @@ void meta_window_update_layer (MetaWindow *window);
|
||||
gboolean meta_window_get_icon_geometry (MetaWindow *window,
|
||||
MetaRectangle *rect);
|
||||
|
||||
const char* meta_window_get_startup_id (MetaWindow *window);
|
||||
|
||||
void meta_window_recalc_features (MetaWindow *window);
|
||||
|
||||
void meta_window_recalc_window_type (MetaWindow *window);
|
||||
|
||||
void meta_window_stack_just_below (MetaWindow *window,
|
||||
@@ -618,4 +621,7 @@ void meta_window_unset_demands_attention (MetaWindow *window);
|
||||
|
||||
void meta_window_update_icon_now (MetaWindow *window);
|
||||
|
||||
void meta_window_update_role (MetaWindow *window);
|
||||
void meta_window_update_net_wm_type (MetaWindow *window);
|
||||
|
||||
#endif
|
||||
|
@@ -9,13 +9,15 @@
|
||||
* Note that all the meta_window_reload_propert* functions require a
|
||||
* round trip to the server.
|
||||
*
|
||||
* \bug Not all the properties have moved over from their original
|
||||
* handler in window.c yet.
|
||||
* The guts of this system are in meta_display_init_window_prop_hooks().
|
||||
* Reading this function will give you insight into how this all fits
|
||||
* together.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
|
||||
* Copyright (C) 2004, 2005 Elijah Newren
|
||||
* Copyright (C) 2009 Thomas Thurman
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@@ -50,59 +52,64 @@
|
||||
#define HOST_NAME_MAX 255
|
||||
#endif
|
||||
|
||||
typedef void (* InitValueFunc) (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value);
|
||||
typedef void (* ReloadValueFunc) (MetaWindow *window,
|
||||
MetaPropValue *value);
|
||||
MetaPropValue *value,
|
||||
gboolean initial);
|
||||
|
||||
struct _MetaWindowPropHooks
|
||||
typedef struct MetaWindowPropHooks
|
||||
{
|
||||
Atom property;
|
||||
InitValueFunc init_func;
|
||||
MetaPropValueType type;
|
||||
ReloadValueFunc reload_func;
|
||||
};
|
||||
} MetaWindowPropHooks;
|
||||
|
||||
static void init_prop_value (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value);
|
||||
static void reload_prop_value (MetaWindow *window,
|
||||
MetaPropValue *value);
|
||||
MetaPropValue *value,
|
||||
gboolean initial);
|
||||
static MetaWindowPropHooks* find_hooks (MetaDisplay *display,
|
||||
Atom property);
|
||||
|
||||
|
||||
void
|
||||
meta_window_reload_property (MetaWindow *window,
|
||||
Atom property)
|
||||
Atom property,
|
||||
gboolean initial)
|
||||
{
|
||||
meta_window_reload_properties (window, &property, 1);
|
||||
meta_window_reload_properties (window, &property, 1, initial);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_reload_properties (MetaWindow *window,
|
||||
const Atom *properties,
|
||||
int n_properties)
|
||||
int n_properties,
|
||||
gboolean initial)
|
||||
{
|
||||
meta_window_reload_properties_from_xwindow (window,
|
||||
window->xwindow,
|
||||
properties,
|
||||
n_properties);
|
||||
n_properties,
|
||||
initial);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_reload_property_from_xwindow (MetaWindow *window,
|
||||
Window xwindow,
|
||||
Atom property)
|
||||
Atom property,
|
||||
gboolean initial)
|
||||
{
|
||||
meta_window_reload_properties_from_xwindow (window, xwindow, &property, 1);
|
||||
meta_window_reload_properties_from_xwindow (window, xwindow, &property, 1,
|
||||
initial);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_reload_properties_from_xwindow (MetaWindow *window,
|
||||
Window xwindow,
|
||||
const Atom *properties,
|
||||
int n_properties)
|
||||
int n_properties,
|
||||
gboolean initial)
|
||||
{
|
||||
int i;
|
||||
MetaPropValue *values;
|
||||
@@ -125,7 +132,7 @@ meta_window_reload_properties_from_xwindow (MetaWindow *window,
|
||||
i = 0;
|
||||
while (i < n_properties)
|
||||
{
|
||||
reload_prop_value (window, &values[i]);
|
||||
reload_prop_value (window, &values[i], initial);
|
||||
|
||||
++i;
|
||||
}
|
||||
@@ -141,39 +148,35 @@ init_prop_value (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
MetaWindowPropHooks *hooks;
|
||||
MetaWindowPropHooks *hooks = find_hooks (display, property);
|
||||
|
||||
if (!hooks || hooks->type == META_PROP_VALUE_INVALID)
|
||||
{
|
||||
value->type = META_PROP_VALUE_INVALID;
|
||||
value->atom = None;
|
||||
|
||||
hooks = find_hooks (display, property);
|
||||
if (hooks && hooks->init_func != NULL)
|
||||
(* hooks->init_func) (display, property, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
value->type = hooks->type;
|
||||
value->atom = property;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reload_prop_value (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
MetaWindowPropHooks *hooks;
|
||||
MetaWindowPropHooks *hooks = find_hooks (window->display, value->atom);
|
||||
|
||||
hooks = find_hooks (window->display, value->atom);
|
||||
if (hooks && hooks->reload_func != NULL)
|
||||
(* hooks->reload_func) (window, value);
|
||||
}
|
||||
|
||||
static void
|
||||
init_wm_client_machine (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_STRING;
|
||||
value->atom = display->atom_WM_CLIENT_MACHINE;
|
||||
(* hooks->reload_func) (window, value, initial);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_wm_client_machine (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
g_free (window->wm_client_machine);
|
||||
window->wm_client_machine = NULL;
|
||||
@@ -186,17 +189,68 @@ reload_wm_client_machine (MetaWindow *window,
|
||||
}
|
||||
|
||||
static void
|
||||
init_net_wm_pid (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
complain_about_broken_client (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
value->type = META_PROP_VALUE_CARDINAL;
|
||||
value->atom = display->atom__NET_WM_PID;
|
||||
meta_warning ("Broken client! Window %s changed client leader window or SM client ID\n",
|
||||
window->desc);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_window_type (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
meta_window_update_net_wm_type (window);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_icon (MetaWindow *window,
|
||||
Atom atom)
|
||||
{
|
||||
meta_icon_cache_property_changed (&window->icon_cache,
|
||||
window->display,
|
||||
atom);
|
||||
meta_window_queue(window, META_QUEUE_UPDATE_ICON);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_icon (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
reload_icon (window, window->display->atom__NET_WM_ICON);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_kwm_win_icon (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
reload_icon (window, window->display->atom__KWM_WIN_ICON);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_struts (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
meta_window_update_struts (window);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_wm_window_role (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
meta_window_update_role (window);
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_pid (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -214,18 +268,10 @@ reload_net_wm_pid (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_net_wm_user_time (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_CARDINAL;
|
||||
value->atom = display->atom__NET_WM_USER_TIME;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_user_time (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -234,18 +280,10 @@ reload_net_wm_user_time (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_net_wm_user_time_window (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_WINDOW;
|
||||
value->atom = display->atom__NET_WM_USER_TIME_WINDOW;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_user_time_window (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -293,7 +331,8 @@ reload_net_wm_user_time_window (MetaWindow *window,
|
||||
meta_window_reload_property_from_xwindow (
|
||||
window,
|
||||
window->user_time_window,
|
||||
window->display->atom__NET_WM_USER_TIME);
|
||||
window->display->atom__NET_WM_USER_TIME,
|
||||
initial);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -384,20 +423,14 @@ set_window_title (MetaWindow *window,
|
||||
meta_ui_set_frame_title (window->screen->ui,
|
||||
window->frame->xwindow,
|
||||
window->title);
|
||||
}
|
||||
|
||||
static void
|
||||
init_net_wm_name (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_UTF8;
|
||||
value->atom = display->atom__NET_WM_NAME;
|
||||
if (modified)
|
||||
g_object_notify (G_OBJECT (window), "title");
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_name (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -411,22 +444,15 @@ reload_net_wm_name (MetaWindow *window,
|
||||
{
|
||||
set_window_title (window, NULL);
|
||||
window->using_net_wm_name = FALSE;
|
||||
if (!initial)
|
||||
meta_window_reload_property (window, XA_WM_NAME, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_wm_name (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_TEXT_PROPERTY;
|
||||
value->atom = XA_WM_NAME;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_wm_name (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (window->using_net_wm_name)
|
||||
{
|
||||
@@ -461,18 +487,10 @@ set_icon_title (MetaWindow *window,
|
||||
window->using_net_wm_visible_icon_name = modified;
|
||||
}
|
||||
|
||||
static void
|
||||
init_net_wm_icon_name (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_UTF8;
|
||||
value->atom = display->atom__NET_WM_ICON_NAME;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_icon_name (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -486,22 +504,15 @@ reload_net_wm_icon_name (MetaWindow *window,
|
||||
{
|
||||
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
|
||||
init_wm_icon_name (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_TEXT_PROPERTY;
|
||||
value->atom = XA_WM_ICON_NAME;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_wm_icon_name (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (window->using_net_wm_icon_name)
|
||||
{
|
||||
@@ -523,18 +534,10 @@ reload_wm_icon_name (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_net_wm_state (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_ATOM_LIST;
|
||||
value->atom = display->atom__NET_WM_STATE;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_state (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -542,6 +545,13 @@ reload_net_wm_state (MetaWindow *window,
|
||||
* clients don't change the property.
|
||||
*/
|
||||
|
||||
if (!initial) {
|
||||
/* no, they DON'T change the property */
|
||||
meta_verbose ("Ignoring _NET_WM_STATE: we should be the one who set "
|
||||
"the property in the first place\n");
|
||||
return;
|
||||
}
|
||||
|
||||
window->shaded = FALSE;
|
||||
window->maximized_horizontally = FALSE;
|
||||
window->maximized_vertically = FALSE;
|
||||
@@ -573,13 +583,21 @@ reload_net_wm_state (MetaWindow *window,
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER)
|
||||
window->wm_state_skip_pager = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_FULLSCREEN)
|
||||
window->fullscreen = TRUE;
|
||||
{
|
||||
if (!window->fullscreen)
|
||||
{
|
||||
window->fullscreen = TRUE;
|
||||
g_object_notify (G_OBJECT (window), "fullscreen");
|
||||
}
|
||||
}
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE)
|
||||
window->wm_state_above = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_BELOW)
|
||||
window->wm_state_below = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION)
|
||||
window->wm_state_demands_attention = TRUE;
|
||||
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_STICKY)
|
||||
window->on_all_workspaces = TRUE;
|
||||
|
||||
++i;
|
||||
}
|
||||
@@ -590,20 +608,13 @@ reload_net_wm_state (MetaWindow *window,
|
||||
meta_window_recalc_window_type (window);
|
||||
}
|
||||
|
||||
static void
|
||||
init_mwm_hints (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_MOTIF_HINTS;
|
||||
value->atom = display->atom__MOTIF_WM_HINTS;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_mwm_hints (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
MotifWmHints *hints;
|
||||
gboolean old_decorated = window->decorated;
|
||||
|
||||
window->mwm_decorated = TRUE;
|
||||
window->mwm_border_only = FALSE;
|
||||
@@ -720,21 +731,16 @@ reload_mwm_hints (MetaWindow *window,
|
||||
META_QUEUE_MOVE_RESIZE |
|
||||
/* because ensure/destroy frame may unmap: */
|
||||
META_QUEUE_CALC_SHOWING);
|
||||
|
||||
if (old_decorated != window->decorated)
|
||||
g_object_notify (G_OBJECT (window), "decorated");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_wm_class (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_CLASS_HINT;
|
||||
value->atom = XA_WM_CLASS;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_wm_class (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (window->res_class)
|
||||
g_free (window->res_class);
|
||||
@@ -759,18 +765,10 @@ reload_wm_class (MetaWindow *window,
|
||||
window->res_name ? window->res_name : "none");
|
||||
}
|
||||
|
||||
static void
|
||||
init_net_wm_desktop (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_CARDINAL;
|
||||
value->atom = display->atom__NET_WM_DESKTOP;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_wm_desktop (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -782,18 +780,10 @@ reload_net_wm_desktop (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_net_startup_id (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_UTF8;
|
||||
value->atom = display->atom__NET_STARTUP_ID;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_net_startup_id (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
guint32 timestamp = window->net_wm_user_time;
|
||||
MetaWorkspace *workspace = NULL;
|
||||
@@ -828,18 +818,10 @@ reload_net_startup_id (MetaWindow *window,
|
||||
window->desc);
|
||||
}
|
||||
|
||||
static void
|
||||
init_update_counter (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_SYNC_COUNTER;
|
||||
value->atom = display->atom__NET_WM_SYNC_REQUEST_COUNTER;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_update_counter (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -853,17 +835,6 @@ reload_update_counter (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_normal_hints (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_SIZE_HINTS;
|
||||
value->atom = XA_WM_NORMAL_HINTS;
|
||||
}
|
||||
|
||||
|
||||
#define FLAG_TOGGLED_ON(old,new,flag) \
|
||||
(((old)->flags & (flag)) == 0 && \
|
||||
((new)->flags & (flag)) != 0)
|
||||
@@ -1268,7 +1239,8 @@ meta_set_normal_hints (MetaWindow *window,
|
||||
|
||||
static void
|
||||
reload_normal_hints (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -1283,22 +1255,16 @@ reload_normal_hints (MetaWindow *window,
|
||||
spew_size_hints_differences (&old_hints, &window->size_hints);
|
||||
|
||||
meta_window_recalc_features (window);
|
||||
|
||||
if (!initial)
|
||||
meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_wm_protocols (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_ATOM_LIST;
|
||||
value->atom = display->atom_WM_PROTOCOLS;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_wm_protocols (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1329,18 +1295,10 @@ reload_wm_protocols (MetaWindow *window,
|
||||
window->desc);
|
||||
}
|
||||
|
||||
static void
|
||||
init_wm_hints (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_WM_HINTS;
|
||||
value->atom = XA_WM_HINTS;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_wm_hints (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
Window old_group_leader;
|
||||
|
||||
@@ -1394,18 +1352,10 @@ reload_wm_hints (MetaWindow *window,
|
||||
meta_window_queue (window, META_QUEUE_UPDATE_ICON | META_QUEUE_MOVE_RESIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
init_transient_for (MetaDisplay *display,
|
||||
Atom property,
|
||||
MetaPropValue *value)
|
||||
{
|
||||
value->type = META_PROP_VALUE_WINDOW;
|
||||
value->atom = XA_WM_TRANSIENT_FOR;
|
||||
}
|
||||
|
||||
static void
|
||||
reload_transient_for (MetaWindow *window,
|
||||
MetaPropValue *value)
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
window->xtransient_for = None;
|
||||
|
||||
@@ -1451,184 +1401,90 @@ reload_transient_for (MetaWindow *window,
|
||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
||||
}
|
||||
|
||||
#define N_HOOKS 26
|
||||
|
||||
/**
|
||||
* Initialises the property hooks system. Each row in the table named "hooks"
|
||||
* represents an action to take when a property is found on a newly-created
|
||||
* window, or when a property changes its value.
|
||||
*
|
||||
* The first column shows which atom the row concerns.
|
||||
* The second gives the type of the property data. The property will be
|
||||
* queried for its new value, unless the type is given as
|
||||
* META_PROP_VALUE_INVALID, in which case nothing will be queried.
|
||||
* The third column gives the name of a callback which gets called with the
|
||||
* new value. (If the new value was not retrieved because the second column
|
||||
* was META_PROP_VALUE_INVALID, the callback still gets called anyway.)
|
||||
* This value may be NULL, in which case no callback will be called.
|
||||
*/
|
||||
void
|
||||
meta_display_init_window_prop_hooks (MetaDisplay *display)
|
||||
{
|
||||
int i;
|
||||
MetaWindowPropHooks *hooks;
|
||||
MetaWindowPropHooks hooks[] = {
|
||||
{ display->atom_WM_STATE, META_PROP_VALUE_INVALID, NULL },
|
||||
{ display->atom_WM_CLIENT_MACHINE, META_PROP_VALUE_STRING, reload_wm_client_machine },
|
||||
{ display->atom__NET_WM_PID, META_PROP_VALUE_CARDINAL, reload_net_wm_pid },
|
||||
{ display->atom__NET_WM_USER_TIME, META_PROP_VALUE_CARDINAL, reload_net_wm_user_time },
|
||||
{ display->atom__NET_WM_NAME, META_PROP_VALUE_UTF8, reload_net_wm_name },
|
||||
{ XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name },
|
||||
{ display->atom__NET_WM_ICON, META_PROP_VALUE_INVALID, reload_net_wm_icon },
|
||||
{ display->atom__KWM_WIN_ICON, META_PROP_VALUE_INVALID, reload_kwm_win_icon },
|
||||
{ display->atom__NET_WM_ICON_NAME, META_PROP_VALUE_UTF8, reload_net_wm_icon_name },
|
||||
{ XA_WM_ICON_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_icon_name },
|
||||
{ display->atom__NET_WM_STATE, META_PROP_VALUE_ATOM_LIST, reload_net_wm_state },
|
||||
{ display->atom__MOTIF_WM_HINTS, META_PROP_VALUE_MOTIF_HINTS, reload_mwm_hints },
|
||||
{ display->atom__NET_WM_ICON_GEOMETRY, META_PROP_VALUE_INVALID, NULL },
|
||||
{ XA_WM_CLASS, META_PROP_VALUE_CLASS_HINT, reload_wm_class },
|
||||
{ display->atom_WM_CLIENT_LEADER, META_PROP_VALUE_INVALID, complain_about_broken_client },
|
||||
{ display->atom_SM_CLIENT_ID, META_PROP_VALUE_INVALID, complain_about_broken_client },
|
||||
{ display->atom_WM_WINDOW_ROLE, META_PROP_VALUE_INVALID, reload_wm_window_role },
|
||||
{ display->atom__NET_WM_WINDOW_TYPE, META_PROP_VALUE_INVALID, reload_net_wm_window_type },
|
||||
{ display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop },
|
||||
{ display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts },
|
||||
{ display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts },
|
||||
{ display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id },
|
||||
{ display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER, reload_update_counter },
|
||||
{ XA_WM_NORMAL_HINTS, META_PROP_VALUE_SIZE_HINTS, reload_normal_hints },
|
||||
{ display->atom_WM_PROTOCOLS, META_PROP_VALUE_ATOM_LIST, reload_wm_protocols },
|
||||
{ XA_WM_HINTS, META_PROP_VALUE_WM_HINTS, reload_wm_hints },
|
||||
{ XA_WM_TRANSIENT_FOR, META_PROP_VALUE_WINDOW, reload_transient_for },
|
||||
{ display->atom__NET_WM_USER_TIME_WINDOW, META_PROP_VALUE_WINDOW, reload_net_wm_user_time_window },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
MetaWindowPropHooks *table = g_memdup (hooks, sizeof (hooks)),
|
||||
*cursor = table;
|
||||
|
||||
g_assert (display->prop_hooks == NULL);
|
||||
|
||||
display->prop_hooks = g_new0 (MetaWindowPropHooks, N_HOOKS);
|
||||
hooks = display->prop_hooks;
|
||||
|
||||
i = 0;
|
||||
display->prop_hooks_table = (gpointer) table;
|
||||
display->prop_hooks = g_hash_table_new (NULL, NULL);
|
||||
|
||||
hooks[i].property = display->atom_WM_STATE;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom_WM_CLIENT_MACHINE;
|
||||
hooks[i].init_func = init_wm_client_machine;
|
||||
hooks[i].reload_func = reload_wm_client_machine;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_PID;
|
||||
hooks[i].init_func = init_net_wm_pid;
|
||||
hooks[i].reload_func = reload_net_wm_pid;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_USER_TIME;
|
||||
hooks[i].init_func = init_net_wm_user_time;
|
||||
hooks[i].reload_func = reload_net_wm_user_time;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_NAME;
|
||||
hooks[i].init_func = init_net_wm_name;
|
||||
hooks[i].reload_func = reload_net_wm_name;
|
||||
++i;
|
||||
|
||||
hooks[i].property = XA_WM_NAME;
|
||||
hooks[i].init_func = init_wm_name;
|
||||
hooks[i].reload_func = reload_wm_name;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_ICON_NAME;
|
||||
hooks[i].init_func = init_net_wm_icon_name;
|
||||
hooks[i].reload_func = reload_net_wm_icon_name;
|
||||
++i;
|
||||
|
||||
hooks[i].property = XA_WM_ICON_NAME;
|
||||
hooks[i].init_func = init_wm_icon_name;
|
||||
hooks[i].reload_func = reload_wm_icon_name;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_STATE;
|
||||
hooks[i].init_func = init_net_wm_state;
|
||||
hooks[i].reload_func = reload_net_wm_state;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__MOTIF_WM_HINTS;
|
||||
hooks[i].init_func = init_mwm_hints;
|
||||
hooks[i].reload_func = reload_mwm_hints;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_ICON_GEOMETRY;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = XA_WM_CLASS;
|
||||
hooks[i].init_func = init_wm_class;
|
||||
hooks[i].reload_func = reload_wm_class;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom_WM_CLIENT_LEADER;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom_SM_CLIENT_ID;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom_WM_WINDOW_ROLE;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_WINDOW_TYPE;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_DESKTOP;
|
||||
hooks[i].init_func = init_net_wm_desktop;
|
||||
hooks[i].reload_func = reload_net_wm_desktop;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_STRUT;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_STRUT_PARTIAL;
|
||||
hooks[i].init_func = NULL;
|
||||
hooks[i].reload_func = NULL;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_STARTUP_ID;
|
||||
hooks[i].init_func = init_net_startup_id;
|
||||
hooks[i].reload_func = reload_net_startup_id;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_SYNC_REQUEST_COUNTER;
|
||||
hooks[i].init_func = init_update_counter;
|
||||
hooks[i].reload_func = reload_update_counter;
|
||||
++i;
|
||||
|
||||
hooks[i].property = XA_WM_NORMAL_HINTS;
|
||||
hooks[i].init_func = init_normal_hints;
|
||||
hooks[i].reload_func = reload_normal_hints;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom_WM_PROTOCOLS;
|
||||
hooks[i].init_func = init_wm_protocols;
|
||||
hooks[i].reload_func = reload_wm_protocols;
|
||||
++i;
|
||||
|
||||
hooks[i].property = XA_WM_HINTS;
|
||||
hooks[i].init_func = init_wm_hints;
|
||||
hooks[i].reload_func = reload_wm_hints;
|
||||
++i;
|
||||
|
||||
hooks[i].property = XA_WM_TRANSIENT_FOR;
|
||||
hooks[i].init_func = init_transient_for;
|
||||
hooks[i].reload_func = reload_transient_for;
|
||||
++i;
|
||||
|
||||
hooks[i].property = display->atom__NET_WM_USER_TIME_WINDOW;
|
||||
hooks[i].init_func = init_net_wm_user_time_window;
|
||||
hooks[i].reload_func = reload_net_wm_user_time_window;
|
||||
++i;
|
||||
|
||||
if (i != N_HOOKS)
|
||||
while (cursor->property)
|
||||
{
|
||||
g_error ("Initialized %d hooks should have been %d\n", i, N_HOOKS);
|
||||
/* Atoms are safe to use with GINT_TO_POINTER because it's safe with
|
||||
* anything 32 bits or less, and atoms are 32 bits with the top three
|
||||
* bits clear. (Scheifler & Gettys, 2e, p372)
|
||||
*/
|
||||
g_hash_table_insert (display->prop_hooks,
|
||||
GINT_TO_POINTER (cursor->property),
|
||||
cursor);
|
||||
cursor++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_free_window_prop_hooks (MetaDisplay *display)
|
||||
{
|
||||
g_assert (display->prop_hooks != NULL);
|
||||
|
||||
g_free (display->prop_hooks);
|
||||
g_hash_table_unref (display->prop_hooks);
|
||||
display->prop_hooks = NULL;
|
||||
|
||||
g_free (display->prop_hooks_table);
|
||||
display->prop_hooks_table = NULL;
|
||||
}
|
||||
|
||||
static MetaWindowPropHooks*
|
||||
find_hooks (MetaDisplay *display,
|
||||
Atom property)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* FIXME we could sort the array and do binary search or
|
||||
* something
|
||||
*/
|
||||
|
||||
i = 0;
|
||||
while (i < N_HOOKS)
|
||||
{
|
||||
if (display->prop_hooks[i].property == property)
|
||||
return &display->prop_hooks[i];
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return g_hash_table_lookup (display->prop_hooks,
|
||||
GINT_TO_POINTER (property));
|
||||
}
|
||||
|
@@ -43,7 +43,8 @@
|
||||
* \param property A single X atom.
|
||||
*/
|
||||
void meta_window_reload_property (MetaWindow *window,
|
||||
Atom property);
|
||||
Atom property,
|
||||
gboolean initial);
|
||||
|
||||
|
||||
/**
|
||||
@@ -57,7 +58,8 @@ void meta_window_reload_property (MetaWindow *window,
|
||||
*/
|
||||
void meta_window_reload_properties (MetaWindow *window,
|
||||
const Atom *properties,
|
||||
int n_properties);
|
||||
int n_properties,
|
||||
gboolean initial);
|
||||
|
||||
/**
|
||||
* Requests the current values of a single property for a given
|
||||
@@ -72,7 +74,8 @@ void meta_window_reload_properties (MetaWindow *window,
|
||||
void meta_window_reload_property_from_xwindow
|
||||
(MetaWindow *window,
|
||||
Window xwindow,
|
||||
Atom property);
|
||||
Atom property,
|
||||
gboolean initial);
|
||||
|
||||
/**
|
||||
* Requests the current values of a set of properties for a given
|
||||
@@ -89,7 +92,8 @@ void meta_window_reload_properties_from_xwindow
|
||||
(MetaWindow *window,
|
||||
Window xwindow,
|
||||
const Atom *properties,
|
||||
int n_properties);
|
||||
int n_properties,
|
||||
gboolean initial);
|
||||
|
||||
/**
|
||||
* Initialises the hooks used for the reload_propert* functions
|
||||
|
1944
src/core/window.c
1944
src/core/window.c
File diff suppressed because it is too large
Load Diff
@@ -30,24 +30,15 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_WORKSPACE_H
|
||||
#define META_WORKSPACE_H
|
||||
#ifndef META_WORKSPACE_PRIVATE_H
|
||||
#define META_WORKSPACE_PRIVATE_H
|
||||
|
||||
#include "workspace.h"
|
||||
#include "window-private.h"
|
||||
|
||||
/* Negative to avoid conflicting with real workspace
|
||||
* numbers
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_MOTION_UP = -1,
|
||||
META_MOTION_DOWN = -2,
|
||||
META_MOTION_LEFT = -3,
|
||||
META_MOTION_RIGHT = -4
|
||||
} MetaMotionDirection;
|
||||
|
||||
struct _MetaWorkspace
|
||||
{
|
||||
GObject parent_instance;
|
||||
MetaScreen *screen;
|
||||
|
||||
GList *windows;
|
||||
@@ -59,6 +50,7 @@ struct _MetaWorkspace
|
||||
MetaRectangle *work_area_xinerama;
|
||||
GList *screen_region;
|
||||
GList **xinerama_region;
|
||||
gint n_xinerama_regions;
|
||||
GList *screen_edges;
|
||||
GList *xinerama_edges;
|
||||
GSList *all_struts;
|
||||
@@ -67,20 +59,19 @@ struct _MetaWorkspace
|
||||
guint showing_desktop : 1;
|
||||
};
|
||||
|
||||
struct _MetaWorkspaceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
MetaWorkspace* meta_workspace_new (MetaScreen *screen);
|
||||
void meta_workspace_free (MetaWorkspace *workspace);
|
||||
void meta_workspace_remove (MetaWorkspace *workspace);
|
||||
void meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window);
|
||||
void meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window);
|
||||
void meta_workspace_relocate_windows (MetaWorkspace *workspace,
|
||||
MetaWorkspace *new_home);
|
||||
void meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
MetaWindow *focus_this,
|
||||
guint32 timestamp);
|
||||
void meta_workspace_activate (MetaWorkspace *workspace,
|
||||
guint32 timestamp);
|
||||
int meta_workspace_index (MetaWorkspace *workspace);
|
||||
GList* meta_workspace_list_windows (MetaWorkspace *workspace);
|
||||
|
||||
void meta_workspace_invalidate_work_area (MetaWorkspace *workspace);
|
||||
@@ -89,8 +80,6 @@ void meta_workspace_invalidate_work_area (MetaWorkspace *workspace);
|
||||
void meta_workspace_get_work_area_for_xinerama (MetaWorkspace *workspace,
|
||||
int which_xinerama,
|
||||
MetaRectangle *area);
|
||||
void meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
|
||||
MetaRectangle *area);
|
||||
GList* meta_workspace_get_onscreen_region (MetaWorkspace *workspace);
|
||||
GList* meta_workspace_get_onxinerama_region (MetaWorkspace *workspace,
|
||||
int which_xinerama);
|
@@ -25,11 +25,23 @@
|
||||
|
||||
#include <config.h>
|
||||
#include "workspace.h"
|
||||
#include "workspace-private.h"
|
||||
#include "errors.h"
|
||||
#include "prefs.h"
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
#include "compositor.h"
|
||||
#endif
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
#include <string.h>
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_N_WINDOWS,
|
||||
};
|
||||
|
||||
void meta_workspace_queue_calc_showing (MetaWorkspace *workspace);
|
||||
static void set_active_space_hint (MetaScreen *screen);
|
||||
static void focus_ancestor_or_mru_window (MetaWorkspace *workspace,
|
||||
@@ -39,6 +51,78 @@ static void free_this (gpointer candidate,
|
||||
gpointer dummy);
|
||||
static void workspace_free_struts (MetaWorkspace *workspace);
|
||||
|
||||
G_DEFINE_TYPE (MetaWorkspace, meta_workspace, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
meta_workspace_finalize (GObject *object)
|
||||
{
|
||||
/* Actual freeing done in meta_workspace_remove() for now */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_workspace_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_workspace_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaWorkspace *ws = META_WORKSPACE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_N_WINDOWS:
|
||||
/*
|
||||
* This is reliable, but not very efficient; should we store
|
||||
* the list lenth ?
|
||||
*/
|
||||
g_value_set_uint (value, g_list_length (ws->windows));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_workspace_class_init (MetaWorkspaceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
|
||||
object_class->finalize = meta_workspace_finalize;
|
||||
object_class->get_property = meta_workspace_get_property;
|
||||
object_class->set_property = meta_workspace_set_property;
|
||||
|
||||
pspec = g_param_spec_uint ("n-windows",
|
||||
"N Windows",
|
||||
"Number of windows",
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_N_WINDOWS,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_workspace_init (MetaWorkspace *workspace)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_add_to_list (MetaScreen *screen, MetaWindow *window, gpointer data)
|
||||
{
|
||||
@@ -53,7 +137,7 @@ meta_workspace_new (MetaScreen *screen)
|
||||
{
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
workspace = g_new (MetaWorkspace, 1);
|
||||
workspace = g_object_new (META_TYPE_WORKSPACE, NULL);
|
||||
|
||||
workspace->screen = screen;
|
||||
workspace->screen->workspaces =
|
||||
@@ -106,7 +190,7 @@ workspace_free_struts (MetaWorkspace *workspace)
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_free (MetaWorkspace *workspace)
|
||||
meta_workspace_remove (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *tmp;
|
||||
MetaScreen *screen;
|
||||
@@ -162,7 +246,7 @@ meta_workspace_free (MetaWorkspace *workspace)
|
||||
meta_rectangle_free_list_and_elements (workspace->xinerama_edges);
|
||||
}
|
||||
|
||||
g_free (workspace);
|
||||
g_object_unref (workspace);
|
||||
|
||||
/* don't bother to reset names, pagers can just ignore
|
||||
* extra ones
|
||||
@@ -200,6 +284,7 @@ meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
}
|
||||
|
||||
workspace->windows = g_list_prepend (workspace->windows, window);
|
||||
|
||||
window->workspace = workspace;
|
||||
|
||||
meta_window_set_current_workspace_hint (window);
|
||||
@@ -216,6 +301,8 @@ meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
* the relevant struts
|
||||
*/
|
||||
meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
g_object_notify (G_OBJECT (workspace), "n-windows");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -262,6 +349,8 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
* the relevant struts
|
||||
*/
|
||||
meta_window_queue (window, META_QUEUE_CALC_SHOWING|META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
g_object_notify (G_OBJECT (workspace), "n-windows");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -300,7 +389,19 @@ meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
|
||||
tmp = workspace->windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING);
|
||||
if (meta_prefs_get_live_hidden_windows ())
|
||||
{
|
||||
/*
|
||||
* When we hide rather than unmap windows, we need the show/hide
|
||||
* status of the window to be recalculated *before* we call the
|
||||
* compositor switch_workspace hook.
|
||||
*/
|
||||
meta_window_calc_showing (tmp->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_window_queue (tmp->data, META_QUEUE_CALC_SHOWING);
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
@@ -383,6 +484,60 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
|
||||
meta_workspace_focus_default_window (workspace, NULL, timestamp);
|
||||
}
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
{
|
||||
/*
|
||||
* Notify the compositor that the active workspace changed.
|
||||
*/
|
||||
MetaScreen *screen = workspace->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
MetaCompositor *comp = meta_display_get_compositor (display);
|
||||
MetaWorkspaceLayout layout1, layout2;
|
||||
gint num_workspaces, current_space, new_space;
|
||||
MetaMotionDirection direction = 0;
|
||||
|
||||
current_space = meta_workspace_index (old);
|
||||
new_space = meta_workspace_index (workspace);
|
||||
|
||||
num_workspaces = meta_screen_get_n_workspaces (workspace->screen);
|
||||
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
|
||||
current_space, &layout1);
|
||||
|
||||
meta_screen_calc_workspace_layout (workspace->screen, num_workspaces,
|
||||
new_space, &layout2);
|
||||
|
||||
if (layout1.current_col < layout2.current_col)
|
||||
direction = META_MOTION_RIGHT;
|
||||
if (layout1.current_col > layout2.current_col)
|
||||
direction = META_MOTION_LEFT;
|
||||
|
||||
if (layout1.current_row < layout2.current_row)
|
||||
{
|
||||
if (!direction)
|
||||
direction = META_MOTION_DOWN;
|
||||
else if (direction == META_MOTION_RIGHT)
|
||||
direction = META_MOTION_DOWN_RIGHT;
|
||||
else
|
||||
direction = META_MOTION_DOWN_LEFT;
|
||||
}
|
||||
|
||||
if (layout1.current_row > layout2.current_row)
|
||||
{
|
||||
if (!direction)
|
||||
direction = META_MOTION_UP;
|
||||
else if (direction == META_MOTION_RIGHT)
|
||||
direction = META_MOTION_UP_RIGHT;
|
||||
else
|
||||
direction = META_MOTION_UP_LEFT;
|
||||
}
|
||||
|
||||
meta_screen_free_workspace_layout (&layout1);
|
||||
meta_screen_free_workspace_layout (&layout2);
|
||||
|
||||
meta_compositor_switch_workspace (comp, screen, old, workspace, direction);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -405,6 +560,20 @@ meta_workspace_index (MetaWorkspace *workspace)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_update_window_hints (MetaWorkspace *workspace)
|
||||
{
|
||||
GList *l = workspace->windows;
|
||||
while (l)
|
||||
{
|
||||
MetaWindow *win = l->data;
|
||||
|
||||
meta_window_set_current_workspace_hint (win);
|
||||
|
||||
l = l->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* get windows contained on workspace, including workspace->windows
|
||||
* and also sticky windows.
|
||||
*/
|
||||
@@ -682,6 +851,19 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
|
||||
|
||||
/* We're all done, YAAY! Record that everything has been validated. */
|
||||
workspace->work_areas_invalid = FALSE;
|
||||
|
||||
#ifdef HAVE_COMPOSITE_EXTENSIONS
|
||||
{
|
||||
/*
|
||||
* Notify the compositor that the workspace geometry has changed.
|
||||
*/
|
||||
MetaScreen *screen = workspace->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
MetaCompositor *comp = meta_display_get_compositor (display);
|
||||
|
||||
meta_compositor_update_workspace_geometry (comp, workspace);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -737,6 +919,14 @@ meta_motion_direction_to_string (MetaMotionDirection direction)
|
||||
return "Left";
|
||||
case META_MOTION_RIGHT:
|
||||
return "Right";
|
||||
case META_MOTION_UP_RIGHT:
|
||||
return "Up-Right";
|
||||
case META_MOTION_DOWN_RIGHT:
|
||||
return "Down-Right";
|
||||
case META_MOTION_UP_LEFT:
|
||||
return "Up-Left";
|
||||
case META_MOTION_DOWN_LEFT:
|
||||
return "Down-Left";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
@@ -775,6 +965,7 @@ meta_workspace_get_neighbor (MetaWorkspace *workspace,
|
||||
case META_MOTION_DOWN:
|
||||
layout.current_row += 1;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
if (layout.current_col < 0)
|
||||
@@ -974,3 +1165,10 @@ focus_ancestor_or_mru_window (MetaWorkspace *workspace,
|
||||
timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
MetaScreen *
|
||||
meta_workspace_get_screen (MetaWorkspace *workspace)
|
||||
{
|
||||
return workspace->screen;
|
||||
}
|
||||
|
||||
|
@@ -199,7 +199,7 @@ get_property (MetaDisplay *display,
|
||||
False, req_type, &results->type, &results->format,
|
||||
&results->n_items,
|
||||
&results->bytes_after,
|
||||
(guchar **)&results->prop) != Success ||
|
||||
&results->prop) != Success ||
|
||||
results->type == None)
|
||||
{
|
||||
if (results->prop)
|
||||
@@ -673,9 +673,9 @@ meta_prop_get_text_property (MetaDisplay *display,
|
||||
/* From Xmd.h */
|
||||
#ifndef cvtINT32toInt
|
||||
#if SIZEOF_VOID_P == 8
|
||||
#define cvtINT8toInt(val) (((val) & 0x00000080) ? ((val) | 0xffffffffffffff00) : (val))
|
||||
#define cvtINT16toInt(val) (((val) & 0x00008000) ? ((val) | 0xffffffffffff0000) : (val))
|
||||
#define cvtINT32toInt(val) (((val) & 0x80000000) ? ((val) | 0xffffffff00000000) : (val))
|
||||
#define cvtINT8toInt(val) ((((unsigned int)val) & 0x00000080) ? (((unsigned int)val) | 0xffffffffffffff00) : ((unsigned int)val))
|
||||
#define cvtINT16toInt(val) ((((unsigned int)val) & 0x00008000) ? (((unsigned int)val) | 0xffffffffffff0000) : ((unsigned int)val))
|
||||
#define cvtINT32toInt(val) ((((unsigned int)val) & 0x80000000) ? (((unsigned int)val) | 0xffffffff00000000) : ((unsigned int)val))
|
||||
#define cvtINT8toShort(val) cvtINT8toInt(val)
|
||||
#define cvtINT16toShort(val) cvtINT16toInt(val)
|
||||
#define cvtINT32toShort(val) cvtINT32toInt(val)
|
||||
@@ -1051,7 +1051,7 @@ meta_prop_get_values (MetaDisplay *display,
|
||||
&results.type, &results.format,
|
||||
&results.n_items,
|
||||
&results.bytes_after,
|
||||
(unsigned char **)(&results.prop)) != Success ||
|
||||
&results.prop) != Success ||
|
||||
results.type == None)
|
||||
{
|
||||
values[i].type = META_PROP_VALUE_INVALID;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user