Compare commits
	
		
			206 Commits
		
	
	
		
			3.11.2
			...
			wip/quadbu
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					0f214e24ee | ||
| 
						 | 
					cf67327f0e | ||
| 
						 | 
					8e5bb17750 | ||
| 
						 | 
					14d2f8fddc | ||
| 
						 | 
					c249c3f3e5 | ||
| 
						 | 
					db0383d19f | ||
| 
						 | 
					a175b3c947 | ||
| 
						 | 
					554be56639 | ||
| 
						 | 
					b4de2458ab | ||
| 
						 | 
					49952bdc69 | ||
| 
						 | 
					b2fd24a098 | ||
| 
						 | 
					fe9d2570d0 | ||
| 
						 | 
					b16ac1ba8c | ||
| 
						 | 
					330ce648d3 | ||
| 
						 | 
					0c0973bbd8 | ||
| 
						 | 
					a967d479c5 | ||
| 
						 | 
					9707c1061d | ||
| 
						 | 
					29cb77ce70 | ||
| 
						 | 
					f93fa1d705 | ||
| 
						 | 
					a742b17805 | ||
| 
						 | 
					c4b65e0e6e | ||
| 
						 | 
					9ec8232417 | ||
| 
						 | 
					768e830f11 | ||
| 
						 | 
					4a4a624b77 | ||
| 
						 | 
					b13b7ea72e | ||
| 
						 | 
					9a89cc1198 | ||
| 
						 | 
					b8eb7b883f | ||
| 
						 | 
					4f9872c037 | ||
| 
						 | 
					24e12053ea | ||
| 
						 | 
					991c85f6a0 | ||
| 
						 | 
					4880ee9bb6 | ||
| 
						 | 
					2f77b71933 | ||
| 
						 | 
					47273eaab6 | ||
| 
						 | 
					202e6bd654 | ||
| 
						 | 
					fd41ab93da | ||
| 
						 | 
					a07fe23d7a | ||
| 
						 | 
					ef0763fd04 | ||
| 
						 | 
					b5ef6703fc | ||
| 
						 | 
					dde25e831f | ||
| 
						 | 
					8358b5dd24 | ||
| 
						 | 
					34a9c95b7f | ||
| 
						 | 
					dd76c92f30 | ||
| 
						 | 
					70e3ef02a6 | ||
| 
						 | 
					b159d6a5e1 | ||
| 
						 | 
					4c2e39bf2c | ||
| 
						 | 
					4a8f7aa884 | ||
| 
						 | 
					c8f466cb85 | ||
| 
						 | 
					2edec1bfa8 | ||
| 
						 | 
					73acbdd30c | ||
| 
						 | 
					c07004aefe | ||
| 
						 | 
					7e8833a215 | ||
| 
						 | 
					266ac00e56 | ||
| 
						 | 
					2b3fc741fb | ||
| 
						 | 
					91389c89a1 | ||
| 
						 | 
					abb060b272 | ||
| 
						 | 
					41e6cd8aa9 | ||
| 
						 | 
					bb5631793c | ||
| 
						 | 
					f77fc447e0 | ||
| 
						 | 
					c63d7cb692 | ||
| 
						 | 
					ac28b91bf6 | ||
| 
						 | 
					334e7373cd | ||
| 
						 | 
					b9b6eb99c3 | ||
| 
						 | 
					463318ac4c | ||
| 
						 | 
					3ee63d5a99 | ||
| 
						 | 
					eb01163656 | ||
| 
						 | 
					2bf844d585 | ||
| 
						 | 
					585fdd781c | ||
| 
						 | 
					54f8b5d69a | ||
| 
						 | 
					fc24552e0e | ||
| 
						 | 
					be352c2bf1 | ||
| 
						 | 
					36009cbae1 | ||
| 
						 | 
					21f9bf530d | ||
| 
						 | 
					64a82c8d77 | ||
| 
						 | 
					29edefdfc5 | ||
| 
						 | 
					7253a5d274 | ||
| 
						 | 
					ad43cbd70b | ||
| 
						 | 
					682d6f9ee2 | ||
| 
						 | 
					1e01a55cdc | ||
| 
						 | 
					1acb1bb7e6 | ||
| 
						 | 
					487602c409 | ||
| 
						 | 
					a7fa90b750 | ||
| 
						 | 
					0054e637cc | ||
| 
						 | 
					8c69f1b33c | ||
| 
						 | 
					870c6382ed | ||
| 
						 | 
					91770d0477 | ||
| 
						 | 
					6b81a05341 | ||
| 
						 | 
					5298a834ef | ||
| 
						 | 
					6ceddd626a | ||
| 
						 | 
					a538f36524 | ||
| 
						 | 
					e3a93db712 | ||
| 
						 | 
					7cdf55871e | ||
| 
						 | 
					c78089437d | ||
| 
						 | 
					ad1e23ce7d | ||
| 
						 | 
					52d411bd85 | ||
| 
						 | 
					3aac2bf934 | ||
| 
						 | 
					e053f7f2f4 | ||
| 
						 | 
					fb6a7cda70 | ||
| 
						 | 
					9c20de1adb | ||
| 
						 | 
					9935b4fd66 | ||
| 
						 | 
					45ff615b46 | ||
| 
						 | 
					79e96a6a1a | ||
| 
						 | 
					497541730f | ||
| 
						 | 
					101a13c86d | ||
| 
						 | 
					18cfcc0221 | ||
| 
						 | 
					8daefd92df | ||
| 
						 | 
					b580ccfe56 | ||
| 
						 | 
					d3c2607e53 | ||
| 
						 | 
					f64cea3fc3 | ||
| 
						 | 
					7a33fa6817 | ||
| 
						 | 
					67560db7b8 | ||
| 
						 | 
					6b7f7c66ec | ||
| 
						 | 
					79a3b23cec | ||
| 
						 | 
					ce99362094 | ||
| 
						 | 
					099fd2b3fb | ||
| 
						 | 
					abebb4775b | ||
| 
						 | 
					4752d427e4 | ||
| 
						 | 
					16a8e6ffe0 | ||
| 
						 | 
					b8aa9bddf9 | ||
| 
						 | 
					8e0bc053d4 | ||
| 
						 | 
					757674a9d6 | ||
| 
						 | 
					254afc5022 | ||
| 
						 | 
					56f8d32ca9 | ||
| 
						 | 
					1f6158ace7 | ||
| 
						 | 
					4cc842296e | ||
| 
						 | 
					f6e58be4b0 | ||
| 
						 | 
					a285bbbd14 | ||
| 
						 | 
					52c24c5c71 | ||
| 
						 | 
					64e09b37ac | ||
| 
						 | 
					f3908bb0b8 | ||
| 
						 | 
					aab354b72b | ||
| 
						 | 
					1f1aa85d68 | ||
| 
						 | 
					2bc0e35f7d | ||
| 
						 | 
					be501479da | ||
| 
						 | 
					707d728722 | ||
| 
						 | 
					ae05059cef | ||
| 
						 | 
					c1f5741ac0 | ||
| 
						 | 
					f5bb6e407f | ||
| 
						 | 
					3548e6da73 | ||
| 
						 | 
					d2a1db8834 | ||
| 
						 | 
					0b003bb895 | ||
| 
						 | 
					ebcd60d0b3 | ||
| 
						 | 
					a9a31b206b | ||
| 
						 | 
					a56df823f1 | ||
| 
						 | 
					fbec4718f8 | ||
| 
						 | 
					911cca9c99 | ||
| 
						 | 
					abb021e51e | ||
| 
						 | 
					03ee7e05d5 | ||
| 
						 | 
					02426c50cb | ||
| 
						 | 
					477acddf64 | ||
| 
						 | 
					1d04ea62ba | ||
| 
						 | 
					10c1903c72 | ||
| 
						 | 
					69dfd07a7f | ||
| 
						 | 
					bc9b923d5c | ||
| 
						 | 
					fef32fb0d4 | ||
| 
						 | 
					0e9491a415 | ||
| 
						 | 
					c7725ddf2a | ||
| 
						 | 
					5c7ea17abd | ||
| 
						 | 
					c6a6d057a8 | ||
| 
						 | 
					ed4fb0695e | ||
| 
						 | 
					addac8825d | ||
| 
						 | 
					8e74880b55 | ||
| 
						 | 
					6891ce95dc | ||
| 
						 | 
					b7e62d3ca5 | ||
| 
						 | 
					27a0b8f87a | ||
| 
						 | 
					21e94ed109 | ||
| 
						 | 
					0fe5c4f957 | ||
| 
						 | 
					75f5d59d53 | ||
| 
						 | 
					1db95bc32b | ||
| 
						 | 
					93a8933282 | ||
| 
						 | 
					5a63aaa5ac | ||
| 
						 | 
					a3eb5e562a | ||
| 
						 | 
					8a76383eca | ||
| 
						 | 
					734deeb17c | ||
| 
						 | 
					f8b4c28278 | ||
| 
						 | 
					3e179c07bc | ||
| 
						 | 
					56aae17b46 | ||
| 
						 | 
					78741846a4 | ||
| 
						 | 
					55180f5bb3 | ||
| 
						 | 
					62b884dd42 | ||
| 
						 | 
					3283018bfb | ||
| 
						 | 
					55226ada8a | ||
| 
						 | 
					ff790f7b39 | ||
| 
						 | 
					899570d213 | ||
| 
						 | 
					3b2506851c | ||
| 
						 | 
					9b88059e55 | ||
| 
						 | 
					59168b2c64 | ||
| 
						 | 
					47144253e4 | ||
| 
						 | 
					d8c66077f0 | ||
| 
						 | 
					59a01137e1 | ||
| 
						 | 
					ce3804ee04 | ||
| 
						 | 
					f0bc53ce5a | ||
| 
						 | 
					b8938e9d4d | ||
| 
						 | 
					7116d9cedb | ||
| 
						 | 
					66fb86fd0c | ||
| 
						 | 
					59cfbb07c8 | ||
| 
						 | 
					dc5bc3fea8 | ||
| 
						 | 
					fbbc32422e | ||
| 
						 | 
					fe8829f324 | ||
| 
						 | 
					b4036e061a | ||
| 
						 | 
					4ee9f3563b | ||
| 
						 | 
					c652a54f59 | ||
| 
						 | 
					61881477ac | ||
| 
						 | 
					4373916d9d | ||
| 
						 | 
					660d7df5ab | ||
| 
						 | 
					b7e3f627f1 | ||
| 
						 | 
					ca5d115715 | 
							
								
								
									
										41
									
								
								COPYING
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								COPYING
									
									
									
									
									
								
							@@ -1,12 +1,12 @@
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
		       Version 2, June 1991
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 | 
			
		||||
     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 | 
			
		||||
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
			    Preamble
 | 
			
		||||
                            Preamble
 | 
			
		||||
 | 
			
		||||
  The licenses for most software are designed to take away your
 | 
			
		||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
			
		||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users.  This
 | 
			
		||||
General Public License applies to most of the Free Software
 | 
			
		||||
Foundation's software and to any other program whose authors commit to
 | 
			
		||||
using it.  (Some other Free Software Foundation software is covered by
 | 
			
		||||
the GNU Library General Public License instead.)  You can apply it to
 | 
			
		||||
the GNU Lesser General Public License instead.)  You can apply it to
 | 
			
		||||
your programs, too.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.
 | 
			
		||||
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. This License applies to any program or other work which contains
 | 
			
		||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
 | 
			
		||||
    License.  (Exception: if the Program itself is interactive but
 | 
			
		||||
    does not normally print such an announcement, your work based on
 | 
			
		||||
    the Program is not required to print an announcement.)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
These requirements apply to the modified work as a whole.  If
 | 
			
		||||
identifiable sections of that work are not derived from the Program,
 | 
			
		||||
and can be reasonably considered independent and separate works in
 | 
			
		||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
 | 
			
		||||
access to copy the source code from the same place counts as
 | 
			
		||||
distribution of the source code, even though third parties are not
 | 
			
		||||
compelled to copy the source along with the object code.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  4. You may not copy, modify, sublicense, or distribute the Program
 | 
			
		||||
except as expressly provided under this License.  Any attempt
 | 
			
		||||
otherwise to copy, modify, sublicense or distribute the Program is
 | 
			
		||||
@@ -225,7 +225,7 @@ impose that choice.
 | 
			
		||||
 | 
			
		||||
This section is intended to make thoroughly clear what is believed to
 | 
			
		||||
be a consequence of the rest of this License.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  8. If the distribution and/or use of the Program is restricted in
 | 
			
		||||
certain countries either by patents or by copyrighted interfaces, the
 | 
			
		||||
original copyright holder who places the Program under this License
 | 
			
		||||
@@ -255,7 +255,7 @@ make exceptions for this.  Our decision will be guided by the two goals
 | 
			
		||||
of preserving the free status of all derivatives of our free software and
 | 
			
		||||
of promoting the sharing and reuse of software generally.
 | 
			
		||||
 | 
			
		||||
			    NO WARRANTY
 | 
			
		||||
                            NO WARRANTY
 | 
			
		||||
 | 
			
		||||
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
			
		||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
			
		||||
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
			
		||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
			
		||||
POSSIBILITY OF SUCH DAMAGES.
 | 
			
		||||
 | 
			
		||||
		     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
	    How to Apply These Terms to Your New Programs
 | 
			
		||||
                     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
            How to Apply These Terms to Your New Programs
 | 
			
		||||
 | 
			
		||||
  If you develop a new program, and you want it to be of the greatest
 | 
			
		||||
possible use to the public, the best way to achieve this is to make it
 | 
			
		||||
@@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    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.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
If the program is interactive, make it output a short notice like this
 | 
			
		||||
when it starts in an interactive mode:
 | 
			
		||||
 | 
			
		||||
    Gnomovision version 69, Copyright (C) year  name of author
 | 
			
		||||
    Gnomovision version 69, Copyright (C) year name of author
 | 
			
		||||
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
			
		||||
    This is free software, and you are welcome to redistribute it
 | 
			
		||||
    under certain conditions; type `show c' for details.
 | 
			
		||||
@@ -336,5 +335,5 @@ necessary.  Here is a sample; alter the names:
 | 
			
		||||
This General Public License does not permit incorporating your program into
 | 
			
		||||
proprietary programs.  If your program is a subroutine library, you may
 | 
			
		||||
consider it more useful to permit linking proprietary applications with the
 | 
			
		||||
library.  If this is what you want to do, use the GNU Library General
 | 
			
		||||
library.  If this is what you want to do, use the GNU Lesser General
 | 
			
		||||
Public License instead of this License.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										119
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,3 +1,122 @@
 | 
			
		||||
3.12.1
 | 
			
		||||
======
 | 
			
		||||
* Fix opacity values from _NET_WM_WINDOW_OPACITY [Nirbheek; #727874]
 | 
			
		||||
* Misc. cleanups [Jasper; #720631]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Nirbheek Chauhan, Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Inaki Larranaga Murgoitio [eu], marablack3 [el]
 | 
			
		||||
 | 
			
		||||
3.12.0
 | 
			
		||||
======
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Ask H. Larsen [da], Мирослав Николић [sr, sr@latin], Andika Triwidada [id],
 | 
			
		||||
  Daniel Korostil [uk], Petr Kovar [cs]
 | 
			
		||||
 | 
			
		||||
3.11.92
 | 
			
		||||
=======
 | 
			
		||||
* Fix identification of CSD windows [Owen; #723029]
 | 
			
		||||
* Add minimal handling of touch events [Carlos; #723552]
 | 
			
		||||
* Misc bug fixes and cleanups [Owen, Adel, Jasper; #723580, #726352]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Adel Gadllah, Carlos Garnacho, Rui Matos, Jasper St. Pierre, Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Changwoo Ryu [ko], Rūdolfs Mazurs [lv], Wylmer Wang [zh_CN],
 | 
			
		||||
  Chao-Hsiung Liao [zh_HK, zh_TW], Yuri Myasoedov [ru], Tiagosdot [pt],
 | 
			
		||||
  Claude Paroz [fr], Duarte Loreto [pt], A S Alam [pa]
 | 
			
		||||
 | 
			
		||||
3.11.91
 | 
			
		||||
=======
 | 
			
		||||
* Don't use keysym to match keybindings [Rui; #678001]
 | 
			
		||||
* Fix message tray icons showing up blank (again) [Adel; #725180]
 | 
			
		||||
* Improve keybinding lookups [Rui; #725588]
 | 
			
		||||
* Fix dynamic updates of titlebar style properties [Owen; #725751]
 | 
			
		||||
* Fix positioning of manually positioned windows [Owen; #724049]
 | 
			
		||||
* Misc. bug fixes [Carlos, Giovanni, Florian, Jasper; #724969, #724402, #722266,
 | 
			
		||||
  #725338]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Giovanni Campagna, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
 | 
			
		||||
  Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Aurimas Černius [lt], Milo Casagrande [it], Balázs Úr [hu],
 | 
			
		||||
  Matej Urbančič [sl], Enrico Nicoletto [pt_BR], Yosef Or Boczko [he],
 | 
			
		||||
  Piotr Drąg [pl], Fran Diéguez [gl]
 | 
			
		||||
 | 
			
		||||
3.11.90
 | 
			
		||||
=======
 | 
			
		||||
* Use correct output property for backlight control [Robert; #723606]
 | 
			
		||||
* Fix double-scaling on high DPI resolutions [Adel; #723931]
 | 
			
		||||
* Make tile previews a compositor effect [Stefano, Florian; #665758]
 | 
			
		||||
* Misc. bug fixes and cleanups [Ryan, Giovanni, Jasper; #722530, #724257,
 | 
			
		||||
  #724258, #724364, #720631, #707851, #707897]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Robert Ancell, Giovanni Campagna, Stefano Facchini, Adel Gadllah,
 | 
			
		||||
  Ryan Lortie, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Shankar Prasad [kn], Khaled Hosny [ar], Marek Černocký [cs],
 | 
			
		||||
  Kjartan Maraas [nb], Daniel Korostil [uk]
 | 
			
		||||
 | 
			
		||||
3.11.5
 | 
			
		||||
======
 | 
			
		||||
* Fix CSD titlebars being placed off-screen [Jasper; #719772]
 | 
			
		||||
* Expose MetaWindow:skip-taskbar property [Florian; #723307]
 | 
			
		||||
* Fix legacy tray icons showing up blank [Adel; #721596]
 | 
			
		||||
* Fix configuration of cloned monitors [Adel; #710610]
 | 
			
		||||
* Misc bug fixes and cleanups [Jasper, Adel, Jonas; #720631, #723468, #723563]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Marek Ch, Adel Gadllah, Florian Müllner, Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Rafael Ferreira [pt_BR], Enrico Nicoletto [pt_BR], Fran Diéguez [gl],
 | 
			
		||||
  Chao-Hsiung Liao [zh_HK, zh_TW]
 | 
			
		||||
 | 
			
		||||
3.11.4
 | 
			
		||||
======
 | 
			
		||||
* Don't leave focus on windows that are being unmanaged [Owen; #711618]
 | 
			
		||||
* Reduce server grabs [Daniel Drake; #721345, #721709]
 | 
			
		||||
* Improve heuristic to determine display output name [Cosimo Cecchi; #721674]
 | 
			
		||||
* Atomically unmaximize both directions [Jasper; #722108]
 | 
			
		||||
* Misc bug fixes [Debarshi, Andika; #721517, #721674]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Cosimo Cecchi, Daniel Drake, Debarshi Ray, Jasper St. Pierre,
 | 
			
		||||
  Andika Triwidada, Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Rafael Ferreira [pt_BR], Dimitris Spingos [el], Daniel Mustieles [es],
 | 
			
		||||
  Milo Casagrande [it], Yosef Or Boczko [he]
 | 
			
		||||
 | 
			
		||||
3.11.3
 | 
			
		||||
======
 | 
			
		||||
* xrandr: Use "hotplug_mode_update" property [Marc-André; #711216]
 | 
			
		||||
* Fix position of attached dialogs for CSD windows [Giovanni, Owen; #707194]
 | 
			
		||||
* Fix focus issues with external OSKs [Jasper; #715030]
 | 
			
		||||
* Add a MetaCullable interface [Jasper; #714706]
 | 
			
		||||
* Fix window group paint volume [Owen; #719669]
 | 
			
		||||
* Fix frame extents problems [Owen; #714707]
 | 
			
		||||
* Add shortcut to move windows between monitors [Florian; #671054]
 | 
			
		||||
* Fix problems with focus tracking [Owen; #720558]
 | 
			
		||||
* Misc. bug fixes and cleanups [Rui, Jasper, Owen; #712833, #678989, #720106,
 | 
			
		||||
  #720417, #720630]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Robert Bragg, Giovanni Campagna, Marc-André Lureau, Rui Matos, Alberto Milone,
 | 
			
		||||
  Florian Müllner, Sindhu S, Jasper St. Pierre, Rico Tzschichholz,
 | 
			
		||||
  Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  甘露(Gan  Lu) [zh_CN], Khaled Hosny [ar]
 | 
			
		||||
 | 
			
		||||
3.11.2
 | 
			
		||||
======
 | 
			
		||||
* Fix resize operations using mouse-button-modifier [Lionel; #710251]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# Run this to generate all the initial makefiles, etc.
 | 
			
		||||
 | 
			
		||||
srcdir=`dirname $0`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								configure.ac
									
									
									
									
									
								
							@@ -2,8 +2,8 @@ AC_PREREQ(2.50)
 | 
			
		||||
AC_CONFIG_MACRO_DIR([m4])
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_major_version], [3])
 | 
			
		||||
m4_define([mutter_minor_version], [11])
 | 
			
		||||
m4_define([mutter_micro_version], [2])
 | 
			
		||||
m4_define([mutter_minor_version], [12])
 | 
			
		||||
m4_define([mutter_micro_version], [1])
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_version],
 | 
			
		||||
          [mutter_major_version.mutter_minor_version.mutter_micro_version])
 | 
			
		||||
@@ -70,13 +70,13 @@ CLUTTER_PACKAGE=clutter-1.0
 | 
			
		||||
 | 
			
		||||
MUTTER_PC_MODULES="
 | 
			
		||||
   gtk+-3.0 >= 3.9.11
 | 
			
		||||
   gio-2.0 >= 2.25.10
 | 
			
		||||
   gio-unix-2.0 >= 2.25.10
 | 
			
		||||
   pango >= 1.2.0
 | 
			
		||||
   cairo >= 1.10.0
 | 
			
		||||
   gsettings-desktop-schemas >= 3.7.3
 | 
			
		||||
   xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
 | 
			
		||||
   $CLUTTER_PACKAGE >= 1.15.90
 | 
			
		||||
   cogl-1.0 >= 1.15.6
 | 
			
		||||
   $CLUTTER_PACKAGE >= 1.19.5
 | 
			
		||||
   cogl-1.0 >= 1.17.1
 | 
			
		||||
   upower-glib >= 0.99.0
 | 
			
		||||
   gnome-desktop-3.0
 | 
			
		||||
"
 | 
			
		||||
 
 | 
			
		||||
@@ -96,8 +96,6 @@ meta_compositor_hide_window
 | 
			
		||||
meta_compositor_switch_workspace
 | 
			
		||||
meta_compositor_maximize_window
 | 
			
		||||
meta_compositor_unmaximize_window
 | 
			
		||||
meta_compositor_window_mapped
 | 
			
		||||
meta_compositor_window_unmapped
 | 
			
		||||
meta_compositor_sync_window_geometry
 | 
			
		||||
meta_compositor_set_updates_frozen
 | 
			
		||||
meta_compositor_queue_frame_drawn
 | 
			
		||||
@@ -388,6 +386,23 @@ MetaWindowActorPrivate
 | 
			
		||||
meta_window_actor_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>meta-cullable</FILE>
 | 
			
		||||
<TITLE>MetaCullable</TITLE>
 | 
			
		||||
MetaCullable
 | 
			
		||||
MetaCullableInterface
 | 
			
		||||
meta_cullable_cull_out
 | 
			
		||||
meta_cullable_reset_culling
 | 
			
		||||
meta_cullable_cull_out_children
 | 
			
		||||
meta_cullable_reset_culling_children
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_TYPE_CULLABLE
 | 
			
		||||
META_CULLABLE
 | 
			
		||||
META_IS_CULLABLE
 | 
			
		||||
META_CULLABLE_GET_IFACE
 | 
			
		||||
meta_cullable_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>prefs</FILE>
 | 
			
		||||
MetaPreference
 | 
			
		||||
@@ -541,7 +556,10 @@ meta_window_is_override_redirect
 | 
			
		||||
meta_window_is_skip_taskbar
 | 
			
		||||
meta_window_get_rect
 | 
			
		||||
meta_window_get_input_rect
 | 
			
		||||
meta_window_get_frame_rect
 | 
			
		||||
meta_window_get_outer_rect
 | 
			
		||||
meta_window_client_rect_to_frame_rect
 | 
			
		||||
meta_window_frame_rect_to_client_rect
 | 
			
		||||
meta_window_get_screen
 | 
			
		||||
meta_window_get_display
 | 
			
		||||
meta_window_get_xwindow
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										545
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
							
						
						
									
										545
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										553
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
							
						
						
									
										553
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1288
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
							
						
						
									
										1288
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										528
									
								
								po/zh_HK.po
									
									
									
									
									
								
							
							
						
						
									
										528
									
								
								po/zh_HK.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										528
									
								
								po/zh_TW.po
									
									
									
									
									
								
							
							
						
						
									
										528
									
								
								po/zh_TW.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -29,6 +29,18 @@
 | 
			
		||||
	<KeyListEntry name="move-to-workspace-down"
 | 
			
		||||
	              _description="Move window one workspace down" />
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="move-to-monitor-left"
 | 
			
		||||
	              _description="Move window one monitor to the left" />
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="move-to-monitor-right"
 | 
			
		||||
	              _description="Move window one monitor to the right" />
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="move-to-monitor-up"
 | 
			
		||||
	              _description="Move window one monitor up" />
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="move-to-monitor-down"
 | 
			
		||||
	              _description="Move window one monitor down" />
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-applications"
 | 
			
		||||
	              _description="Switch applications"/>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,8 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	compositor/meta-background-actor.c	\
 | 
			
		||||
	compositor/meta-background-actor-private.h	\
 | 
			
		||||
	compositor/meta-background-group.c	\
 | 
			
		||||
	compositor/meta-background-group-private.h	\
 | 
			
		||||
	compositor/meta-cullable.c		\
 | 
			
		||||
	compositor/meta-cullable.h		\
 | 
			
		||||
	compositor/meta-module.c		\
 | 
			
		||||
	compositor/meta-module.h		\
 | 
			
		||||
	compositor/meta-plugin.c		\
 | 
			
		||||
@@ -64,6 +65,7 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	compositor/meta-shadow-factory.c	\
 | 
			
		||||
	compositor/meta-shadow-factory-private.h	\
 | 
			
		||||
	compositor/meta-shaped-texture.c	\
 | 
			
		||||
	compositor/meta-shaped-texture-private.h	\
 | 
			
		||||
	compositor/meta-texture-rectangle.c	\
 | 
			
		||||
	compositor/meta-texture-rectangle.h	\
 | 
			
		||||
	compositor/meta-texture-tower.c		\
 | 
			
		||||
@@ -92,8 +94,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	core/display.c				\
 | 
			
		||||
	core/display-private.h			\
 | 
			
		||||
	meta/display.h				\
 | 
			
		||||
	ui/draw-workspace.c			\
 | 
			
		||||
	ui/draw-workspace.h			\
 | 
			
		||||
	core/edge-resistance.c			\
 | 
			
		||||
	core/edge-resistance.h			\
 | 
			
		||||
	core/edid-parse.c			\
 | 
			
		||||
@@ -132,14 +132,18 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	core/screen-private.h			\
 | 
			
		||||
	meta/screen.h				\
 | 
			
		||||
	meta/types.h				\
 | 
			
		||||
	core/restart.c				\
 | 
			
		||||
	core/session.c				\
 | 
			
		||||
	core/session.h				\
 | 
			
		||||
	core/stereo.c				\
 | 
			
		||||
	core/stereo.h				\
 | 
			
		||||
	core/stack.c				\
 | 
			
		||||
	core/stack.h				\
 | 
			
		||||
	core/stack-tracker.c			\
 | 
			
		||||
	core/stack-tracker.h			\
 | 
			
		||||
	core/util.c				\
 | 
			
		||||
	meta/util.h				\
 | 
			
		||||
	core/util-private.h			\
 | 
			
		||||
	core/window-props.c			\
 | 
			
		||||
	core/window-props.h			\
 | 
			
		||||
	core/window.c				\
 | 
			
		||||
@@ -160,10 +164,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	ui/metaaccellabel.h			\
 | 
			
		||||
	ui/resizepopup.c			\
 | 
			
		||||
	ui/resizepopup.h			\
 | 
			
		||||
	ui/tabpopup.c				\
 | 
			
		||||
	ui/tabpopup.h				\
 | 
			
		||||
	ui/tile-preview.c			\
 | 
			
		||||
	ui/tile-preview.h			\
 | 
			
		||||
	ui/theme-parser.c			\
 | 
			
		||||
	ui/theme.c				\
 | 
			
		||||
	meta/theme.h				\
 | 
			
		||||
@@ -223,6 +223,10 @@ bin_PROGRAMS=mutter
 | 
			
		||||
mutter_SOURCES = core/mutter.c
 | 
			
		||||
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
 | 
			
		||||
 | 
			
		||||
libexec_PROGRAMS = mutter-restart-helper
 | 
			
		||||
mutter_restart_helper_SOURCES = core/restart-helper.c
 | 
			
		||||
mutter_restart_helper_LDADD = $(MUTTER_LIBS)
 | 
			
		||||
 | 
			
		||||
if HAVE_INTROSPECTION
 | 
			
		||||
include $(INTROSPECTION_MAKEFILE)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "clutter-utils.h"
 | 
			
		||||
@@ -95,8 +93,10 @@ meta_actor_vertices_are_untransformed (ClutterVertex *verts,
 | 
			
		||||
      v3x != v1x || v3y != v2y)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *x_origin = x;
 | 
			
		||||
  *y_origin = y;
 | 
			
		||||
  if (x_origin)
 | 
			
		||||
    *x_origin = x;
 | 
			
		||||
  if (y_origin)
 | 
			
		||||
    *y_origin = y;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __META_CLUTTER_UTILS_H__
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __META_COGL_UTILS_H__
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,6 @@ struct _MetaCompositor
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay    *display;
 | 
			
		||||
 | 
			
		||||
  Atom            atom_x_root_pixmap;
 | 
			
		||||
  Atom            atom_net_wm_window_opacity;
 | 
			
		||||
  guint           repaint_func_id;
 | 
			
		||||
 | 
			
		||||
  ClutterActor   *shadow_src;
 | 
			
		||||
@@ -28,6 +26,8 @@ struct _MetaCompositor
 | 
			
		||||
  gint64          server_time_query_time;
 | 
			
		||||
  gint64          server_time_offset;
 | 
			
		||||
 | 
			
		||||
  int             glx_opcode;
 | 
			
		||||
 | 
			
		||||
  guint           server_time_is_monotonic_time : 1;
 | 
			
		||||
  guint           show_redraw : 1;
 | 
			
		||||
  guint           debug       : 1;
 | 
			
		||||
@@ -48,14 +48,14 @@ struct _MetaCompScreen
 | 
			
		||||
  CoglFrameClosure      *frame_closure;
 | 
			
		||||
 | 
			
		||||
  /* Used for unredirecting fullscreen windows */
 | 
			
		||||
  guint                   disable_unredirect_count;
 | 
			
		||||
  MetaWindowActor             *unredirected_window;
 | 
			
		||||
 | 
			
		||||
  /* Before we create the output window */
 | 
			
		||||
  XserverRegion     pending_input_region;
 | 
			
		||||
  guint                  disable_unredirect_count;
 | 
			
		||||
  MetaWindow            *unredirected_window;
 | 
			
		||||
 | 
			
		||||
  gint                   switch_workspace_in_progress;
 | 
			
		||||
 | 
			
		||||
  guint                  stereo_tree_ext : 1;
 | 
			
		||||
  guint                  have_stereo_windows : 1;
 | 
			
		||||
 | 
			
		||||
  MetaPluginManager *plugin_mgr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -77,4 +77,9 @@ gint64 meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
 | 
			
		||||
 | 
			
		||||
void meta_check_end_modal (MetaScreen *screen);
 | 
			
		||||
 | 
			
		||||
gboolean meta_compositor_window_is_stereo     (MetaScreen *screen,
 | 
			
		||||
                                               Window      xwindow);
 | 
			
		||||
void     meta_compositor_select_stereo_notify (MetaScreen *screen,
 | 
			
		||||
                                               Window      xwindow);
 | 
			
		||||
 | 
			
		||||
#endif /* META_COMPOSITOR_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -42,15 +42,6 @@
 | 
			
		||||
 * the call, so it may be necessary to readjust the display based on the
 | 
			
		||||
 * old_rect to start the animation.
 | 
			
		||||
 *
 | 
			
		||||
 * meta_compositor_window_mapped() and meta_compositor_window_unmapped() are
 | 
			
		||||
 * notifications when the toplevel window (frame or client window) is mapped or
 | 
			
		||||
 * unmapped. That is, when the result of meta_window_toplevel_is_mapped()
 | 
			
		||||
 * changes. The main use of this is to drop resources when a window is unmapped.
 | 
			
		||||
 * A window will always be mapped before meta_compositor_show_window()
 | 
			
		||||
 * is called and will not be unmapped until after meta_compositor_hide_window()
 | 
			
		||||
 * is called. If the live_hidden_windows preference is set, windows will never
 | 
			
		||||
 * be unmapped.
 | 
			
		||||
 *
 | 
			
		||||
 * # Containers #
 | 
			
		||||
 *
 | 
			
		||||
 * There's two containers in the stage that are used to place window actors, here
 | 
			
		||||
@@ -83,7 +74,9 @@
 | 
			
		||||
#include "meta-window-actor-private.h"
 | 
			
		||||
#include "meta-window-group.h"
 | 
			
		||||
#include "window-private.h" /* to check window->hidden */
 | 
			
		||||
#include "display-private.h" /* for meta_display_lookup_x_window() */
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
#include "stereo.h"
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
#include <X11/extensions/shape.h>
 | 
			
		||||
#include <X11/extensions/Xcomposite.h>
 | 
			
		||||
 | 
			
		||||
@@ -175,31 +168,6 @@ process_damage (MetaCompositor     *compositor,
 | 
			
		||||
  meta_window_actor_process_damage (window_actor, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
process_property_notify (MetaCompositor	*compositor,
 | 
			
		||||
                         XPropertyEvent *event,
 | 
			
		||||
                         MetaWindow     *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActor *window_actor;
 | 
			
		||||
 | 
			
		||||
  if (window == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
 | 
			
		||||
  if (window_actor == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* Check for the opacity changing */
 | 
			
		||||
  if (event->atom == compositor->atom_net_wm_window_opacity)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_actor_update_opacity (window_actor);
 | 
			
		||||
      DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  DEBUG_TRACE ("process_property_notify: unknown\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Window
 | 
			
		||||
get_output_window (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
@@ -214,6 +182,10 @@ get_output_window (MetaScreen *screen)
 | 
			
		||||
  xroot = meta_screen_get_xroot (screen);
 | 
			
		||||
  output = XCompositeGetOverlayWindow (xdisplay, xroot);
 | 
			
		||||
 | 
			
		||||
  /* Now that we've gotten taken a reference count on the COW, we
 | 
			
		||||
   * can close the helper that is holding on to it */
 | 
			
		||||
  meta_restart_finish ();
 | 
			
		||||
 | 
			
		||||
  meta_core_add_old_event_mask (xdisplay, output, &mask);
 | 
			
		||||
 | 
			
		||||
  XISetMask (mask.mask, XI_KeyPress);
 | 
			
		||||
@@ -304,14 +276,14 @@ meta_get_window_actors (MetaScreen *screen)
 | 
			
		||||
  return info->windows;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
do_set_stage_input_region (MetaScreen   *screen,
 | 
			
		||||
                           XserverRegion region)
 | 
			
		||||
void
 | 
			
		||||
meta_set_stage_input_region (MetaScreen   *screen,
 | 
			
		||||
                             XserverRegion region)
 | 
			
		||||
{
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
  MetaDisplay *display = meta_screen_get_display (screen);
 | 
			
		||||
  Display        *xdpy = meta_display_get_xdisplay (display);
 | 
			
		||||
  Window        xstage = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
 | 
			
		||||
  MetaCompScreen *info    = meta_screen_get_compositor_data (screen);
 | 
			
		||||
  MetaDisplay    *display = meta_screen_get_display (screen);
 | 
			
		||||
  Display        *xdpy    = meta_display_get_xdisplay (display);
 | 
			
		||||
  Window          xstage  = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
 | 
			
		||||
 | 
			
		||||
  XFixesSetWindowShapeRegion (xdpy, xstage, ShapeInput, 0, 0, region);
 | 
			
		||||
 | 
			
		||||
@@ -323,35 +295,6 @@ do_set_stage_input_region (MetaScreen   *screen,
 | 
			
		||||
  XFixesSetWindowShapeRegion (xdpy, info->output, ShapeInput, 0, 0, region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_set_stage_input_region (MetaScreen   *screen,
 | 
			
		||||
                             XserverRegion region)
 | 
			
		||||
{
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
  MetaDisplay  *display = meta_screen_get_display (screen);
 | 
			
		||||
  Display      *xdpy    = meta_display_get_xdisplay (display);
 | 
			
		||||
 | 
			
		||||
  if (info->stage && info->output)
 | 
			
		||||
    {
 | 
			
		||||
      do_set_stage_input_region (screen, region);
 | 
			
		||||
    }
 | 
			
		||||
  else 
 | 
			
		||||
    {
 | 
			
		||||
      /* Reset info->pending_input_region if one existed before and set the new
 | 
			
		||||
       * one to use it later. */ 
 | 
			
		||||
      if (info->pending_input_region)
 | 
			
		||||
        {
 | 
			
		||||
          XFixesDestroyRegion (xdpy, info->pending_input_region);
 | 
			
		||||
          info->pending_input_region = None;
 | 
			
		||||
        }
 | 
			
		||||
      if (region != None)
 | 
			
		||||
        {
 | 
			
		||||
          info->pending_input_region = XFixesCreateRegion (xdpy, NULL, 0);
 | 
			
		||||
          XFixesCopyRegion (xdpy, info->pending_input_region, region);
 | 
			
		||||
        }
 | 
			
		||||
    } 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_empty_stage_input_region (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
@@ -602,6 +545,101 @@ redirect_windows (MetaCompositor *compositor,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define GLX_STEREO_TREE_EXT        0x20F5
 | 
			
		||||
#define GLX_STEREO_NOTIFY_MASK_EXT 0x00000001
 | 
			
		||||
#define GLX_STEREO_NOTIFY_EXT      0x00000000
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  int type;
 | 
			
		||||
  unsigned long serial;
 | 
			
		||||
  Bool send_event;
 | 
			
		||||
  Display *display;
 | 
			
		||||
  int extension;
 | 
			
		||||
  int evtype;
 | 
			
		||||
  Drawable window;
 | 
			
		||||
  Bool stereo_tree;
 | 
			
		||||
} StereoNotifyEvent;
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
screen_has_stereo_tree_ext (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
#if 0
 | 
			
		||||
  MetaDisplay *display = meta_screen_get_display (screen);
 | 
			
		||||
  Display     *xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
  const char *extensions_string;
 | 
			
		||||
 | 
			
		||||
  static const char * (*query_extensions_string) (Display *display,
 | 
			
		||||
                                                  int      screen);
 | 
			
		||||
 | 
			
		||||
  if (query_extensions_string == NULL)
 | 
			
		||||
    query_extensions_string =
 | 
			
		||||
      (const char * (*) (Display *, int))
 | 
			
		||||
      cogl_get_proc_address ("glXQueryExtensionsString");
 | 
			
		||||
 | 
			
		||||
  extensions_string = query_extensions_string (xdisplay,
 | 
			
		||||
                                               meta_screen_get_screen_number (screen));
 | 
			
		||||
 | 
			
		||||
  return strstr (extensions_string, "EXT_stereo_tree") != 0;
 | 
			
		||||
#else
 | 
			
		||||
  return TRUE;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include <GL/gl.h>
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_compositor_window_is_stereo (MetaScreen *screen,
 | 
			
		||||
                                  Window      xwindow)
 | 
			
		||||
{
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
  MetaDisplay    *display = meta_screen_get_display (screen);
 | 
			
		||||
  Display        *xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
 | 
			
		||||
  static int (*query_drawable) (Display      *dpy,
 | 
			
		||||
                                Drawable      draw,
 | 
			
		||||
                                int           attribute,
 | 
			
		||||
                                unsigned int *value);
 | 
			
		||||
 | 
			
		||||
  if (info->stereo_tree_ext)
 | 
			
		||||
    {
 | 
			
		||||
      unsigned int stereo_tree = 0;
 | 
			
		||||
 | 
			
		||||
      if (query_drawable == NULL)
 | 
			
		||||
        query_drawable =
 | 
			
		||||
          (int (*) (Display *, Drawable, int, unsigned int *))
 | 
			
		||||
          cogl_get_proc_address ("glXQueryDrawable");
 | 
			
		||||
 | 
			
		||||
      query_drawable (xdisplay, xwindow, GLX_STEREO_TREE_EXT, &stereo_tree);
 | 
			
		||||
 | 
			
		||||
      return stereo_tree != 0;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_select_stereo_notify (MetaScreen *screen,
 | 
			
		||||
                                      Window      xwindow)
 | 
			
		||||
{
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
  MetaDisplay    *display = meta_screen_get_display (screen);
 | 
			
		||||
  Display        *xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
 | 
			
		||||
  static void (*select_event) (Display      *dpy,
 | 
			
		||||
                               Drawable      draw,
 | 
			
		||||
                               unsigned long event_mask);
 | 
			
		||||
 | 
			
		||||
  if (info->stereo_tree_ext)
 | 
			
		||||
    {
 | 
			
		||||
      if (select_event == NULL)
 | 
			
		||||
        select_event =
 | 
			
		||||
          (void (*) (Display *, Drawable, unsigned long))
 | 
			
		||||
          cogl_get_proc_address ("glXSelectEvent");
 | 
			
		||||
 | 
			
		||||
      select_event (xdisplay, xwindow, GLX_STEREO_NOTIFY_MASK_EXT);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
                               MetaScreen     *screen)
 | 
			
		||||
@@ -617,14 +655,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  info = g_new0 (MetaCompScreen, 1);
 | 
			
		||||
  /*
 | 
			
		||||
   * We use an empty input region for Clutter as a default because that allows
 | 
			
		||||
   * the user to interact with all the windows displayed on the screen.
 | 
			
		||||
   * We have to initialize info->pending_input_region to an empty region explicitly, 
 | 
			
		||||
   * because None value is used to mean that the whole screen is an input region.
 | 
			
		||||
   */
 | 
			
		||||
  info->pending_input_region = XFixesCreateRegion (xdisplay, NULL, 0);
 | 
			
		||||
 | 
			
		||||
  info->screen = screen;
 | 
			
		||||
 | 
			
		||||
  meta_screen_set_compositor_data (screen, info);
 | 
			
		||||
@@ -632,14 +662,14 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
  info->output = None;
 | 
			
		||||
  info->windows = NULL;
 | 
			
		||||
 | 
			
		||||
  info->stereo_tree_ext = screen_has_stereo_tree_ext (screen);
 | 
			
		||||
 | 
			
		||||
  meta_screen_set_cm_selection (screen);
 | 
			
		||||
 | 
			
		||||
  info->stage = clutter_stage_new ();
 | 
			
		||||
 | 
			
		||||
  clutter_stage_set_paint_callback (CLUTTER_STAGE (info->stage),
 | 
			
		||||
                                    after_stage_paint,
 | 
			
		||||
                                    info,
 | 
			
		||||
                                    NULL);
 | 
			
		||||
  g_signal_connect (CLUTTER_STAGE (info->stage), "after-paint",
 | 
			
		||||
                    G_CALLBACK (after_stage_paint), info);
 | 
			
		||||
 | 
			
		||||
  clutter_stage_set_sync_delay (CLUTTER_STAGE (info->stage), META_SYNC_DELAY);
 | 
			
		||||
 | 
			
		||||
@@ -698,14 +728,20 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
  */
 | 
			
		||||
  XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None);
 | 
			
		||||
 | 
			
		||||
  do_set_stage_input_region (screen, info->pending_input_region);
 | 
			
		||||
  if (info->pending_input_region != None)
 | 
			
		||||
    {
 | 
			
		||||
      XFixesDestroyRegion (xdisplay, info->pending_input_region);
 | 
			
		||||
      info->pending_input_region = None;
 | 
			
		||||
    }
 | 
			
		||||
  info->output = get_output_window (screen);
 | 
			
		||||
  XReparentWindow (xdisplay, xwin, info->output, 0, 0);
 | 
			
		||||
 | 
			
		||||
  info->plugin_mgr = meta_plugin_manager_new (screen);
 | 
			
		||||
  meta_empty_stage_input_region (screen);
 | 
			
		||||
 | 
			
		||||
  /* Make sure there isn't any left-over output shape on the 
 | 
			
		||||
   * overlay window by setting the whole screen to be an
 | 
			
		||||
   * output region.
 | 
			
		||||
   * 
 | 
			
		||||
   * Note: there doesn't seem to be any real chance of that
 | 
			
		||||
   *  because the X server will destroy the overlay window
 | 
			
		||||
   *  when the last client using it exits.
 | 
			
		||||
   */
 | 
			
		||||
  XFixesSetWindowShapeRegion (xdisplay, info->output, ShapeBounding, 0, 0, None);
 | 
			
		||||
 | 
			
		||||
  /* Map overlay window before redirecting windows offscreen so we catch their
 | 
			
		||||
   * contents until we show the stage.
 | 
			
		||||
@@ -713,6 +749,8 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
  XMapWindow (xdisplay, info->output);
 | 
			
		||||
 | 
			
		||||
  redirect_windows (compositor, screen);
 | 
			
		||||
 | 
			
		||||
  info->plugin_mgr = meta_plugin_manager_new (screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -749,7 +787,7 @@ meta_shape_cow_for_window (MetaScreen *screen,
 | 
			
		||||
      int width, height;
 | 
			
		||||
      MetaRectangle rect;
 | 
			
		||||
 | 
			
		||||
      meta_window_get_outer_rect (metaWindow, &rect);
 | 
			
		||||
      meta_window_get_frame_rect (metaWindow, &rect);
 | 
			
		||||
 | 
			
		||||
      window_bounds.x = rect.x;
 | 
			
		||||
      window_bounds.y = rect.y;
 | 
			
		||||
@@ -770,6 +808,30 @@ meta_shape_cow_for_window (MetaScreen *screen,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_unredirected_window (MetaCompScreen *info,
 | 
			
		||||
                         MetaWindow     *window)
 | 
			
		||||
{
 | 
			
		||||
  if (info->unredirected_window == window)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (info->unredirected_window != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window));
 | 
			
		||||
      meta_window_actor_set_unredirected (window_actor, FALSE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  info->unredirected_window = window;
 | 
			
		||||
 | 
			
		||||
  if (info->unredirected_window != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (info->unredirected_window));
 | 
			
		||||
      meta_window_actor_set_unredirected (window_actor, TRUE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_shape_cow_for_window (info->screen, info->unredirected_window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_add_window (MetaCompositor    *compositor,
 | 
			
		||||
                            MetaWindow        *window)
 | 
			
		||||
@@ -801,13 +863,8 @@ meta_compositor_remove_window (MetaCompositor *compositor,
 | 
			
		||||
  screen = meta_window_get_screen (window);
 | 
			
		||||
  info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
 | 
			
		||||
  if (window_actor == info->unredirected_window)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_actor_set_redirected (window_actor, TRUE);
 | 
			
		||||
      meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)),
 | 
			
		||||
                                 NULL);
 | 
			
		||||
      info->unredirected_window = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  if (info->unredirected_window == window)
 | 
			
		||||
    set_unredirected_window (info, NULL);
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_destroy (window_actor);
 | 
			
		||||
}
 | 
			
		||||
@@ -877,6 +934,18 @@ meta_compositor_window_shape_changed (MetaCompositor *compositor,
 | 
			
		||||
  meta_window_actor_update_shape (window_actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_window_opacity_changed (MetaCompositor *compositor,
 | 
			
		||||
                                        MetaWindow     *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActor *window_actor;
 | 
			
		||||
  window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
 | 
			
		||||
  if (!window_actor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_update_opacity (window_actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Clutter makes the assumption that there is only one X window
 | 
			
		||||
 * per stage, which is a valid assumption to make for a generic
 | 
			
		||||
 * application toolkit. As such, it will ignore any events sent
 | 
			
		||||
@@ -983,28 +1052,35 @@ meta_compositor_process_event (MetaCompositor *compositor,
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  switch (event->type)
 | 
			
		||||
  if (event->type == GenericEvent &&
 | 
			
		||||
      event->xcookie.extension == compositor->glx_opcode)
 | 
			
		||||
    {
 | 
			
		||||
    case PropertyNotify:
 | 
			
		||||
      process_property_notify (compositor, (XPropertyEvent *) event, window);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
 | 
			
		||||
      if (event->xcookie.evtype == GLX_STEREO_NOTIFY_EXT)
 | 
			
		||||
        {
 | 
			
		||||
          /* Core code doesn't handle damage events, so we need to extract the MetaWindow
 | 
			
		||||
           * ourselves
 | 
			
		||||
           */
 | 
			
		||||
          if (window == NULL)
 | 
			
		||||
            {
 | 
			
		||||
              Window xwin = ((XDamageNotifyEvent *) event)->drawable;
 | 
			
		||||
              window = meta_display_lookup_x_window (compositor->display, xwin);
 | 
			
		||||
            }
 | 
			
		||||
          StereoNotifyEvent *stereo_event = (StereoNotifyEvent *)(event->xcookie.data);
 | 
			
		||||
          window = meta_display_lookup_x_window (compositor->display, stereo_event->window);
 | 
			
		||||
 | 
			
		||||
	  DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
 | 
			
		||||
          process_damage (compositor, (XDamageNotifyEvent *) event, window);
 | 
			
		||||
          if (window != NULL)
 | 
			
		||||
            {
 | 
			
		||||
              MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
 | 
			
		||||
              meta_window_actor_stereo_notify (window_actor, stereo_event->stereo_tree);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
 | 
			
		||||
    {
 | 
			
		||||
      /* Core code doesn't handle damage events, so we need to extract the MetaWindow
 | 
			
		||||
       * ourselves
 | 
			
		||||
       */
 | 
			
		||||
      if (window == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          Window xwin = ((XDamageNotifyEvent *) event)->drawable;
 | 
			
		||||
          window = meta_display_lookup_x_window (compositor->display, xwin);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      DEBUG_TRACE ("meta_compositor_process_event (process_damage)\n");
 | 
			
		||||
      process_damage (compositor, (XDamageNotifyEvent *) event, window);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Clutter needs to know about MapNotify events otherwise it will
 | 
			
		||||
@@ -1219,6 +1295,7 @@ meta_compositor_sync_stack (MetaCompositor  *compositor,
 | 
			
		||||
{
 | 
			
		||||
  GList *old_stack;
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
  int stereo_window_count = 0;
 | 
			
		||||
 | 
			
		||||
  DEBUG_TRACE ("meta_compositor_sync_stack\n");
 | 
			
		||||
 | 
			
		||||
@@ -1296,36 +1373,16 @@ meta_compositor_sync_stack (MetaCompositor  *compositor,
 | 
			
		||||
       * near the front of the other.)
 | 
			
		||||
       */
 | 
			
		||||
      info->windows = g_list_prepend (info->windows, actor);
 | 
			
		||||
      if (meta_window_actor_is_stereo (actor))
 | 
			
		||||
        stereo_window_count++;
 | 
			
		||||
 | 
			
		||||
      stack = g_list_remove (stack, window);
 | 
			
		||||
      old_stack = g_list_remove (old_stack, actor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  sync_actor_stacking (info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_window_mapped (MetaCompositor *compositor,
 | 
			
		||||
                               MetaWindow     *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
 | 
			
		||||
  DEBUG_TRACE ("meta_compositor_window_mapped\n");
 | 
			
		||||
  if (!window_actor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_mapped (window_actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_window_unmapped (MetaCompositor *compositor,
 | 
			
		||||
                                 MetaWindow     *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
 | 
			
		||||
  DEBUG_TRACE ("meta_compositor_window_unmapped\n");
 | 
			
		||||
  if (!window_actor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_window_actor_unmapped (window_actor);
 | 
			
		||||
  meta_stereo_set_have_stereo_windows (stereo_window_count > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -1417,7 +1474,6 @@ pre_paint_windows (MetaCompScreen *info)
 | 
			
		||||
{
 | 
			
		||||
  GList *l;
 | 
			
		||||
  MetaWindowActor *top_window;
 | 
			
		||||
  MetaWindowActor *expected_unredirected_window = NULL;
 | 
			
		||||
 | 
			
		||||
  if (info->onscreen == NULL)
 | 
			
		||||
    {
 | 
			
		||||
@@ -1435,26 +1491,9 @@ pre_paint_windows (MetaCompScreen *info)
 | 
			
		||||
 | 
			
		||||
  if (meta_window_actor_should_unredirect (top_window) &&
 | 
			
		||||
      info->disable_unredirect_count == 0)
 | 
			
		||||
    expected_unredirected_window = top_window;
 | 
			
		||||
 | 
			
		||||
  if (info->unredirected_window != expected_unredirected_window)
 | 
			
		||||
    {
 | 
			
		||||
      if (info->unredirected_window != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          meta_window_actor_set_redirected (info->unredirected_window, TRUE);
 | 
			
		||||
          meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (info->unredirected_window)),
 | 
			
		||||
                                     NULL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (expected_unredirected_window != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          meta_shape_cow_for_window (meta_window_get_screen (meta_window_actor_get_meta_window (top_window)),
 | 
			
		||||
                                     meta_window_actor_get_meta_window (top_window));
 | 
			
		||||
          meta_window_actor_set_redirected (top_window, FALSE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      info->unredirected_window = expected_unredirected_window;
 | 
			
		||||
    }
 | 
			
		||||
    set_unredirected_window (info, meta_window_actor_get_meta_window (top_window));
 | 
			
		||||
  else
 | 
			
		||||
    set_unredirected_window (info, NULL);
 | 
			
		||||
 | 
			
		||||
  for (l = info->windows; l; l = l->next)
 | 
			
		||||
    meta_window_actor_pre_paint (l->data);
 | 
			
		||||
@@ -1508,13 +1547,8 @@ on_shadow_factory_changed (MetaShadowFactory *factory,
 | 
			
		||||
MetaCompositor *
 | 
			
		||||
meta_compositor_new (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  char *atom_names[] = {
 | 
			
		||||
    "_XROOTPMAP_ID",
 | 
			
		||||
    "_NET_WM_WINDOW_OPACITY",
 | 
			
		||||
  };
 | 
			
		||||
  Atom                   atoms[G_N_ELEMENTS(atom_names)];
 | 
			
		||||
  MetaCompositor        *compositor;
 | 
			
		||||
  Display               *xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
  int glx_major_opcode, glx_first_event, glx_first_error;
 | 
			
		||||
 | 
			
		||||
  if (!composite_at_least_version (display, 0, 3))
 | 
			
		||||
    return NULL;
 | 
			
		||||
@@ -1526,21 +1560,18 @@ meta_compositor_new (MetaDisplay *display)
 | 
			
		||||
  if (g_getenv("META_DISABLE_MIPMAPS"))
 | 
			
		||||
    compositor->no_mipmaps = TRUE;
 | 
			
		||||
 | 
			
		||||
  meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
 | 
			
		||||
  XInternAtoms (xdisplay, atom_names, G_N_ELEMENTS (atom_names),
 | 
			
		||||
                False, atoms);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (meta_shadow_factory_get_default (),
 | 
			
		||||
                    "changed",
 | 
			
		||||
                    G_CALLBACK (on_shadow_factory_changed),
 | 
			
		||||
                    compositor);
 | 
			
		||||
 | 
			
		||||
  compositor->atom_x_root_pixmap = atoms[0];
 | 
			
		||||
  compositor->atom_net_wm_window_opacity = atoms[1];
 | 
			
		||||
 | 
			
		||||
  compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
 | 
			
		||||
                                                                  compositor,
 | 
			
		||||
                                                                  NULL);
 | 
			
		||||
  if (XQueryExtension (meta_display_get_xdisplay (display),
 | 
			
		||||
                       "GLX",
 | 
			
		||||
                       &glx_major_opcode, &glx_first_event, &glx_first_error))
 | 
			
		||||
    compositor->glx_opcode = glx_major_opcode;
 | 
			
		||||
 | 
			
		||||
  return compositor;
 | 
			
		||||
}
 | 
			
		||||
@@ -1682,3 +1713,31 @@ meta_compositor_monotonic_time_to_server_time (MetaDisplay *display,
 | 
			
		||||
  else
 | 
			
		||||
    return monotonic_time + compositor->server_time_offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_show_tile_preview (MetaCompositor *compositor,
 | 
			
		||||
                                   MetaScreen     *screen,
 | 
			
		||||
                                   MetaWindow     *window,
 | 
			
		||||
                                   MetaRectangle  *tile_rect,
 | 
			
		||||
                                   int             tile_monitor_number)
 | 
			
		||||
{
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
 | 
			
		||||
  if (!info->plugin_mgr)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_plugin_manager_show_tile_preview (info->plugin_mgr,
 | 
			
		||||
                                         window, tile_rect, tile_monitor_number);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_hide_tile_preview (MetaCompositor *compositor,
 | 
			
		||||
                                   MetaScreen     *screen)
 | 
			
		||||
{
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
 | 
			
		||||
  if (!info->plugin_mgr)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_plugin_manager_hide_tile_preview (info->plugin_mgr);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,9 +6,6 @@
 | 
			
		||||
#include <meta/screen.h>
 | 
			
		||||
#include <meta/meta-background-actor.h>
 | 
			
		||||
 | 
			
		||||
void meta_background_actor_set_clip_region  (MetaBackgroundActor *self,
 | 
			
		||||
                                             cairo_region_t      *clip_region);
 | 
			
		||||
 | 
			
		||||
cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self);
 | 
			
		||||
 | 
			
		||||
#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -14,9 +14,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Portions adapted from gnome-shell/src/shell-global.c
 | 
			
		||||
 */
 | 
			
		||||
@@ -41,20 +39,35 @@
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
#include <meta/meta-background.h>
 | 
			
		||||
#include "meta-background-actor-private.h"
 | 
			
		||||
#include "meta-cullable.h"
 | 
			
		||||
 | 
			
		||||
struct _MetaBackgroundActorPrivate
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *clip_region;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
 | 
			
		||||
static void cullable_iface_init (MetaCullableInterface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_clip_region (MetaBackgroundActor *self,
 | 
			
		||||
                 cairo_region_t      *clip_region)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackgroundActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->clip_region, (GDestroyNotify) cairo_region_destroy);
 | 
			
		||||
  if (clip_region)
 | 
			
		||||
    priv->clip_region = cairo_region_copy (clip_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_background_actor_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
 | 
			
		||||
 | 
			
		||||
  meta_background_actor_set_clip_region (self, NULL);
 | 
			
		||||
  set_clip_region (self, NULL);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
@@ -104,26 +117,6 @@ meta_background_actor_get_preferred_height (ClutterActor *actor,
 | 
			
		||||
    *natural_height_p = height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_background_actor_get_paint_volume (ClutterActor       *actor,
 | 
			
		||||
                                        ClutterPaintVolume *volume)
 | 
			
		||||
{
 | 
			
		||||
  ClutterContent *content;
 | 
			
		||||
  gfloat width, height;
 | 
			
		||||
 | 
			
		||||
  content = clutter_actor_get_content (actor);
 | 
			
		||||
 | 
			
		||||
  if (!content)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  clutter_content_get_preferred_size (content, &width, &height);
 | 
			
		||||
 | 
			
		||||
  clutter_paint_volume_set_width (volume, width);
 | 
			
		||||
  clutter_paint_volume_set_height (volume, height);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_background_actor_class_init (MetaBackgroundActorClass *klass)
 | 
			
		||||
{
 | 
			
		||||
@@ -136,7 +129,6 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass)
 | 
			
		||||
 | 
			
		||||
  actor_class->get_preferred_width = meta_background_actor_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
 | 
			
		||||
  actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -166,31 +158,27 @@ meta_background_actor_new (void)
 | 
			
		||||
  return CLUTTER_ACTOR (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_background_actor_set_clip_region:
 | 
			
		||||
 * @self: a #MetaBackgroundActor
 | 
			
		||||
 * @clip_region: (allow-none): the area of the actor (in allocate-relative
 | 
			
		||||
 *   coordinates) that is visible.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the area of the background that is unobscured by overlapping windows.
 | 
			
		||||
 * This is used to optimize and only paint the visible portions.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_background_actor_set_clip_region (MetaBackgroundActor *self,
 | 
			
		||||
                                       cairo_region_t      *clip_region)
 | 
			
		||||
static void
 | 
			
		||||
meta_background_actor_cull_out (MetaCullable   *cullable,
 | 
			
		||||
                                cairo_region_t *unobscured_region,
 | 
			
		||||
                                cairo_region_t *clip_region)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackgroundActorPrivate *priv;
 | 
			
		||||
  MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
 | 
			
		||||
  set_clip_region (self, clip_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
 | 
			
		||||
static void
 | 
			
		||||
meta_background_actor_reset_culling (MetaCullable *cullable)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackgroundActor *self = META_BACKGROUND_ACTOR (cullable);
 | 
			
		||||
  set_clip_region (self, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->clip_region,
 | 
			
		||||
                   (GDestroyNotify)
 | 
			
		||||
                   cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  if (clip_region)
 | 
			
		||||
    priv->clip_region = cairo_region_copy (clip_region);
 | 
			
		||||
static void
 | 
			
		||||
cullable_iface_init (MetaCullableInterface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->cull_out = meta_background_actor_cull_out;
 | 
			
		||||
  iface->reset_culling = meta_background_actor_reset_culling;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
#ifndef META_BACKGROUND_GROUP_PRIVATE_H
 | 
			
		||||
#define META_BACKGROUND_GROUP_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#include <meta/screen.h>
 | 
			
		||||
#include <meta/meta-background-group.h>
 | 
			
		||||
 | 
			
		||||
void meta_background_group_set_clip_region  (MetaBackgroundGroup *self,
 | 
			
		||||
                                             cairo_region_t      *visible_region);
 | 
			
		||||
#endif /* META_BACKGROUND_GROUP_PRIVATE_H */
 | 
			
		||||
@@ -16,87 +16,43 @@
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "compositor-private.h"
 | 
			
		||||
#include "clutter-utils.h"
 | 
			
		||||
#include "meta-background-actor-private.h"
 | 
			
		||||
#include "meta-background-group-private.h"
 | 
			
		||||
#include <meta/meta-background-group.h>
 | 
			
		||||
#include "meta-cullable.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR);
 | 
			
		||||
static void cullable_iface_init (MetaCullableInterface *iface);
 | 
			
		||||
 | 
			
		||||
struct _MetaBackgroundGroupPrivate
 | 
			
		||||
{
 | 
			
		||||
  gpointer dummy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_background_group_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS (meta_background_group_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_background_group_get_paint_volume (ClutterActor       *actor,
 | 
			
		||||
                                        ClutterPaintVolume *volume)
 | 
			
		||||
{
 | 
			
		||||
  return clutter_paint_volume_set_from_allocation (volume, actor);
 | 
			
		||||
}
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (MetaBackgroundGroup, meta_background_group, CLUTTER_TYPE_ACTOR,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_background_group_class_init (MetaBackgroundGroupClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  actor_class->get_paint_volume = meta_background_group_get_paint_volume;
 | 
			
		||||
  object_class->dispose = meta_background_group_dispose;
 | 
			
		||||
static void
 | 
			
		||||
meta_background_group_cull_out (MetaCullable   *cullable,
 | 
			
		||||
                                cairo_region_t *unobscured_region,
 | 
			
		||||
                                cairo_region_t *clip_region)
 | 
			
		||||
{
 | 
			
		||||
  meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (MetaBackgroundGroupPrivate));
 | 
			
		||||
static void
 | 
			
		||||
meta_background_group_reset_culling (MetaCullable *cullable)
 | 
			
		||||
{
 | 
			
		||||
  meta_cullable_reset_culling_children (cullable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cullable_iface_init (MetaCullableInterface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->cull_out = meta_background_group_cull_out;
 | 
			
		||||
  iface->reset_culling = meta_background_group_reset_culling;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_background_group_init (MetaBackgroundGroup *self)
 | 
			
		||||
{
 | 
			
		||||
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
 | 
			
		||||
                                            META_TYPE_BACKGROUND_GROUP,
 | 
			
		||||
                                            MetaBackgroundGroupPrivate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_background_group_set_clip_region:
 | 
			
		||||
 * @self: a #MetaBackgroundGroup
 | 
			
		||||
 * @region: (allow-none): the parts of the background to paint
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the area of the backgrounds that is unobscured by overlapping windows.
 | 
			
		||||
 * This is used to optimize and only paint the visible portions.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_background_group_set_clip_region (MetaBackgroundGroup *self,
 | 
			
		||||
                                       cairo_region_t      *region)
 | 
			
		||||
{
 | 
			
		||||
  GList *children, *l;
 | 
			
		||||
 | 
			
		||||
  children = clutter_actor_get_children (CLUTTER_ACTOR (self));
 | 
			
		||||
  for (l = children; l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterActor *actor = l->data;
 | 
			
		||||
 | 
			
		||||
      if (META_IS_BACKGROUND_ACTOR (actor))
 | 
			
		||||
        {
 | 
			
		||||
          meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (actor), region);
 | 
			
		||||
        }
 | 
			
		||||
      else if (META_IS_BACKGROUND_GROUP (actor))
 | 
			
		||||
        {
 | 
			
		||||
          int x, y;
 | 
			
		||||
 | 
			
		||||
          if (!meta_actor_is_untransformed (actor, &x, &y))
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          cairo_region_translate (region, -x, -y);
 | 
			
		||||
          meta_background_group_set_clip_region (META_BACKGROUND_GROUP (actor), region);
 | 
			
		||||
          cairo_region_translate (region, x, y);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  g_list_free (children);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
 
 | 
			
		||||
@@ -14,9 +14,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -37,6 +35,7 @@
 | 
			
		||||
#include "mutter-enum-types.h"
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
#include <meta/meta-background.h>
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
#include "meta-background-actor-private.h"
 | 
			
		||||
 | 
			
		||||
#define FRAGMENT_SHADER_DECLARATIONS                                           \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										201
									
								
								src/compositor/meta-cullable.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										201
									
								
								src/compositor/meta-cullable.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2013 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Owen Taylor <otaylor@redhat.com>
 | 
			
		||||
 *     Ray Strode <rstrode@redhat.com>
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "meta-cullable.h"
 | 
			
		||||
#include "clutter-utils.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_INTERFACE (MetaCullable, meta_cullable, CLUTTER_TYPE_ACTOR);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:meta-cullable
 | 
			
		||||
 * @title: MetaCullable
 | 
			
		||||
 * @short_description: CPU culling operations for efficient drawing
 | 
			
		||||
 *
 | 
			
		||||
 * When we are painting a stack of 5-10 large actors, the standard
 | 
			
		||||
 * bottom-to-top method of drawing every actor results in a tremendous
 | 
			
		||||
 * amount of overdraw. If these actors are painting textures like
 | 
			
		||||
 * windows, it can easily max out the available memory bandwidth on a
 | 
			
		||||
 * low-end graphics chipset. It's even worse if window textures are
 | 
			
		||||
 * being accessed over the AGP bus.
 | 
			
		||||
 *
 | 
			
		||||
 * #MetaCullable is our solution. The basic technique applied here is to
 | 
			
		||||
 * do a pre-pass before painting where we walk each actor from top to bottom
 | 
			
		||||
 * and ask each actor to "cull itself out". We pass in a region it can copy
 | 
			
		||||
 * to clip its drawing to, and the actor can subtract its fully opaque pixels
 | 
			
		||||
 * so that actors underneath know not to draw there as well.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_cullable_cull_out_children:
 | 
			
		||||
 * @cullable: The #MetaCullable
 | 
			
		||||
 * @unobscured_region: The unobscured region, as passed into cull_out()
 | 
			
		||||
 * @clip_region: The clip region, as passed into cull_out()
 | 
			
		||||
 *
 | 
			
		||||
 * This is a helper method for actors that want to recurse over their
 | 
			
		||||
 * child actors, and cull them out.
 | 
			
		||||
 *
 | 
			
		||||
 * See #MetaCullable and meta_cullable_cull_out() for more details.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_cullable_cull_out_children (MetaCullable   *cullable,
 | 
			
		||||
                                 cairo_region_t *unobscured_region,
 | 
			
		||||
                                 cairo_region_t *clip_region)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *actor = CLUTTER_ACTOR (cullable);
 | 
			
		||||
  ClutterActor *child;
 | 
			
		||||
  ClutterActorIter iter;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_iter_init (&iter, actor);
 | 
			
		||||
  while (clutter_actor_iter_prev (&iter, &child))
 | 
			
		||||
    {
 | 
			
		||||
      float x, y;
 | 
			
		||||
      gboolean needs_culling;
 | 
			
		||||
 | 
			
		||||
      if (!META_IS_CULLABLE (child))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      needs_culling = (unobscured_region != NULL && clip_region != NULL);
 | 
			
		||||
 | 
			
		||||
      if (needs_culling && !CLUTTER_ACTOR_IS_VISIBLE (child))
 | 
			
		||||
        needs_culling = FALSE;
 | 
			
		||||
 | 
			
		||||
      /* If an actor has effects applied, then that can change the area
 | 
			
		||||
       * it paints and the opacity, so we no longer can figure out what
 | 
			
		||||
       * portion of the actor is obscured and what portion of the screen
 | 
			
		||||
       * it obscures, so we skip the actor.
 | 
			
		||||
       *
 | 
			
		||||
       * This has a secondary beneficial effect: if a ClutterOffscreenEffect
 | 
			
		||||
       * is applied to an actor, then our clipped redraws interfere with the
 | 
			
		||||
       * caching of the FBO - even if we only need to draw a small portion
 | 
			
		||||
       * of the window right now, ClutterOffscreenEffect may use other portions
 | 
			
		||||
       * of the FBO later. So, skipping actors with effects applied also
 | 
			
		||||
       * prevents these bugs.
 | 
			
		||||
       *
 | 
			
		||||
       * Theoretically, we should check clutter_actor_get_offscreen_redirect()
 | 
			
		||||
       * as well for the same reason, but omitted for simplicity in the
 | 
			
		||||
       * hopes that no-one will do that.
 | 
			
		||||
       */
 | 
			
		||||
      if (needs_culling && clutter_actor_has_effects (child))
 | 
			
		||||
        needs_culling = FALSE;
 | 
			
		||||
 | 
			
		||||
      if (needs_culling && !meta_actor_is_untransformed (child, NULL, NULL))
 | 
			
		||||
        needs_culling = FALSE;
 | 
			
		||||
 | 
			
		||||
      if (needs_culling)
 | 
			
		||||
        {
 | 
			
		||||
          clutter_actor_get_position (child, &x, &y);
 | 
			
		||||
 | 
			
		||||
          /* Temporarily move to the coordinate system of the actor */
 | 
			
		||||
          cairo_region_translate (unobscured_region, - x, - y);
 | 
			
		||||
          cairo_region_translate (clip_region, - x, - y);
 | 
			
		||||
 | 
			
		||||
          meta_cullable_cull_out (META_CULLABLE (child), unobscured_region, clip_region);
 | 
			
		||||
 | 
			
		||||
          cairo_region_translate (unobscured_region, x, y);
 | 
			
		||||
          cairo_region_translate (clip_region, x, y);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          meta_cullable_cull_out (META_CULLABLE (child), NULL, NULL);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_cullable_reset_culling_children:
 | 
			
		||||
 * @cullable: The #MetaCullable
 | 
			
		||||
 *
 | 
			
		||||
 * This is a helper method for actors that want to recurse over their
 | 
			
		||||
 * child actors, and cull them out.
 | 
			
		||||
 *
 | 
			
		||||
 * See #MetaCullable and meta_cullable_reset_culling() for more details.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_cullable_reset_culling_children (MetaCullable *cullable)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *actor = CLUTTER_ACTOR (cullable);
 | 
			
		||||
  ClutterActor *child;
 | 
			
		||||
  ClutterActorIter iter;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_iter_init (&iter, actor);
 | 
			
		||||
  while (clutter_actor_iter_next (&iter, &child))
 | 
			
		||||
    {
 | 
			
		||||
      if (!META_IS_CULLABLE (child))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      meta_cullable_reset_culling (META_CULLABLE (child));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cullable_default_init (MetaCullableInterface *iface)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_cullable_cull_out:
 | 
			
		||||
 * @cullable: The #MetaCullable
 | 
			
		||||
 * @unobscured_region: The unobscured region, in @cullable's space.
 | 
			
		||||
 * @clip_region: The clip region, in @cullable's space.
 | 
			
		||||
 *
 | 
			
		||||
 * When #MetaWindowGroup is painted, we walk over its direct cullable
 | 
			
		||||
 * children from top to bottom and ask themselves to "cull out". Cullables
 | 
			
		||||
 * can use @unobscured_region and @clip_region to clip their drawing. Actors
 | 
			
		||||
 * interested in eliminating overdraw should copy the @clip_region and only
 | 
			
		||||
 * paint those parts, as everything else has been obscured by actors above it.
 | 
			
		||||
 *
 | 
			
		||||
 * Actors that may have fully opaque parts should also subtract out a region
 | 
			
		||||
 * that is fully opaque from @unobscured_region and @clip_region.
 | 
			
		||||
 *
 | 
			
		||||
 * @unobscured_region and @clip_region are extremely similar. The difference
 | 
			
		||||
 * is that @clip_region starts off with the stage's clip, if Clutter detects
 | 
			
		||||
 * that we're doing a clipped redraw. @unobscured_region, however, starts off
 | 
			
		||||
 * with the full stage size, so actors that may want to record what parts of
 | 
			
		||||
 * their window are unobscured for e.g. scheduling repaints can do so.
 | 
			
		||||
 *
 | 
			
		||||
 * Actors that have children can also use the meta_cullable_cull_out_children()
 | 
			
		||||
 * helper method to do a simple cull across all their children.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_cullable_cull_out (MetaCullable   *cullable,
 | 
			
		||||
                        cairo_region_t *unobscured_region,
 | 
			
		||||
                        cairo_region_t *clip_region)
 | 
			
		||||
{
 | 
			
		||||
  META_CULLABLE_GET_IFACE (cullable)->cull_out (cullable, unobscured_region, clip_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_cullable_reset_culling:
 | 
			
		||||
 * @cullable: The #MetaCullable
 | 
			
		||||
 *
 | 
			
		||||
 * Actors that copied data in their cull_out() implementation can now
 | 
			
		||||
 * reset their data, as the paint is now over. Additional paints may be
 | 
			
		||||
 * done by #ClutterClone or similar, and they should not be affected by
 | 
			
		||||
 * the culling operation.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_cullable_reset_culling (MetaCullable *cullable)
 | 
			
		||||
{
 | 
			
		||||
  META_CULLABLE_GET_IFACE (cullable)->reset_culling (cullable);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								src/compositor/meta-cullable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/compositor/meta-cullable.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2013 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Owen Taylor <otaylor@redhat.com>
 | 
			
		||||
 *     Ray Strode <rstrode@redhat.com>
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __META_CULLABLE_H__
 | 
			
		||||
#define __META_CULLABLE_H__
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_CULLABLE             (meta_cullable_get_type ())
 | 
			
		||||
#define META_CULLABLE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CULLABLE, MetaCullable))
 | 
			
		||||
#define META_IS_CULLABLE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CULLABLE))
 | 
			
		||||
#define META_CULLABLE_GET_IFACE(obj)   (G_TYPE_INSTANCE_GET_INTERFACE ((obj),  META_TYPE_CULLABLE, MetaCullableInterface))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaCullable MetaCullable;
 | 
			
		||||
typedef struct _MetaCullableInterface MetaCullableInterface;
 | 
			
		||||
 | 
			
		||||
struct _MetaCullableInterface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface g_iface;
 | 
			
		||||
 | 
			
		||||
  void (* cull_out)      (MetaCullable   *cullable,
 | 
			
		||||
                          cairo_region_t *unobscured_region,
 | 
			
		||||
                          cairo_region_t *clip_region);
 | 
			
		||||
  void (* reset_culling) (MetaCullable  *cullable);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType meta_cullable_get_type (void);
 | 
			
		||||
 | 
			
		||||
void meta_cullable_cull_out (MetaCullable   *cullable,
 | 
			
		||||
                             cairo_region_t *unobscured_region,
 | 
			
		||||
                             cairo_region_t *clip_region);
 | 
			
		||||
void meta_cullable_reset_culling (MetaCullable *cullable);
 | 
			
		||||
 | 
			
		||||
/* Utility methods for implementations */
 | 
			
		||||
void meta_cullable_cull_out_children (MetaCullable   *cullable,
 | 
			
		||||
                                      cairo_region_t *unobscured_region,
 | 
			
		||||
                                      cairo_region_t *clip_region);
 | 
			
		||||
void meta_cullable_reset_culling_children (MetaCullable *cullable);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __META_CULLABLE_H__ */
 | 
			
		||||
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-plugin.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_MODULE_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
@@ -326,3 +324,44 @@ meta_plugin_manager_confirm_display_change (MetaPluginManager *plugin_mgr)
 | 
			
		||||
  else
 | 
			
		||||
    return meta_plugin_complete_display_change (plugin, TRUE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_plugin_manager_show_tile_preview (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                                       MetaWindow        *window,
 | 
			
		||||
                                       MetaRectangle     *tile_rect,
 | 
			
		||||
                                       int                tile_monitor_number)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
  MetaDisplay *display  = meta_screen_get_display (plugin_mgr->screen);
 | 
			
		||||
 | 
			
		||||
  if (display->display_opening)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (klass->show_tile_preview)
 | 
			
		||||
    {
 | 
			
		||||
      klass->show_tile_preview (plugin, window, tile_rect, tile_monitor_number);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
  MetaDisplay *display  = meta_screen_get_display (plugin_mgr->screen);
 | 
			
		||||
 | 
			
		||||
  if (display->display_opening)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (klass->hide_tile_preview)
 | 
			
		||||
    {
 | 
			
		||||
      klass->hide_tile_preview (plugin);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_PLUGIN_MANAGER_H_
 | 
			
		||||
@@ -77,4 +75,9 @@ gboolean _meta_plugin_xevent_filter (MetaPlugin *plugin,
 | 
			
		||||
 | 
			
		||||
void     meta_plugin_manager_confirm_display_change (MetaPluginManager *mgr);
 | 
			
		||||
 | 
			
		||||
gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *mgr,
 | 
			
		||||
                                                MetaWindow        *window,
 | 
			
		||||
                                                MetaRectangle     *tile_rect,
 | 
			
		||||
                                                int                tile_monitor_number);
 | 
			
		||||
gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *mgr);
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __META_SHADOW_FACTORY_PRIVATE_H__
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								src/compositor/meta-shaped-texture-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/compositor/meta-shaped-texture-private.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
 *               2013 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 __META_SHAPED_TEXTURE_PRIVATE_H__
 | 
			
		||||
#define __META_SHAPED_TEXTURE_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-shaped-texture.h>
 | 
			
		||||
 | 
			
		||||
ClutterActor *meta_shaped_texture_new (void);
 | 
			
		||||
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
 | 
			
		||||
                                      CoglTexture       *texture,
 | 
			
		||||
				      gboolean           stereo);
 | 
			
		||||
gboolean meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture     *stex,
 | 
			
		||||
                                                    cairo_rectangle_int_t *unobscured_bounds);
 | 
			
		||||
gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -33,10 +31,14 @@
 | 
			
		||||
#include "clutter-utils.h"
 | 
			
		||||
#include "meta-texture-tower.h"
 | 
			
		||||
 | 
			
		||||
#include "meta-shaped-texture-private.h"
 | 
			
		||||
#include "meta-window-actor-private.h"
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
#include <cogl/cogl-texture-pixmap-x11.h>
 | 
			
		||||
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
 | 
			
		||||
#include "meta-cullable.h"
 | 
			
		||||
 | 
			
		||||
static void meta_shaped_texture_dispose  (GObject    *object);
 | 
			
		||||
 | 
			
		||||
@@ -56,8 +58,10 @@ static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
 | 
			
		||||
 | 
			
		||||
static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
 | 
			
		||||
               CLUTTER_TYPE_ACTOR);
 | 
			
		||||
static void cullable_iface_init (MetaCullableInterface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
 | 
			
		||||
 | 
			
		||||
#define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \
 | 
			
		||||
  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
 | 
			
		||||
@@ -66,15 +70,24 @@ G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
 | 
			
		||||
struct _MetaShapedTexturePrivate
 | 
			
		||||
{
 | 
			
		||||
  MetaTextureTower *paint_tower;
 | 
			
		||||
  Pixmap pixmap;
 | 
			
		||||
  CoglTexturePixmapX11 *texture;
 | 
			
		||||
  MetaTextureTower *paint_tower_right;
 | 
			
		||||
 | 
			
		||||
  CoglTexture *texture;
 | 
			
		||||
  CoglTexture *texture_right;
 | 
			
		||||
  CoglTexture *mask_texture;
 | 
			
		||||
 | 
			
		||||
  cairo_region_t *clip_region;
 | 
			
		||||
  cairo_region_t *input_shape_region;
 | 
			
		||||
 | 
			
		||||
  /* The region containing only fully opaque pixels */
 | 
			
		||||
  cairo_region_t *opaque_region;
 | 
			
		||||
 | 
			
		||||
  /* MetaCullable regions, see that documentation for more details */
 | 
			
		||||
  cairo_region_t *clip_region;
 | 
			
		||||
  cairo_region_t *unobscured_region;
 | 
			
		||||
 | 
			
		||||
  guint tex_width, tex_height;
 | 
			
		||||
 | 
			
		||||
  guint stereo : 1;
 | 
			
		||||
  guint create_mipmaps : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -103,26 +116,55 @@ meta_shaped_texture_init (MetaShapedTexture *self)
 | 
			
		||||
  priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
  priv->paint_tower = meta_texture_tower_new ();
 | 
			
		||||
  priv->paint_tower_right = NULL; /* demand create */
 | 
			
		||||
 | 
			
		||||
  priv->texture = NULL;
 | 
			
		||||
  priv->texture_right = NULL;
 | 
			
		||||
  priv->mask_texture = NULL;
 | 
			
		||||
  priv->create_mipmaps = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_unobscured_region (MetaShapedTexture *self,
 | 
			
		||||
                       cairo_region_t    *unobscured_region)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->unobscured_region, (GDestroyNotify) cairo_region_destroy);
 | 
			
		||||
  if (unobscured_region)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t bounds = { 0, 0, priv->tex_width, priv->tex_height };
 | 
			
		||||
      priv->unobscured_region = cairo_region_copy (unobscured_region);
 | 
			
		||||
      cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_clip_region (MetaShapedTexture *self,
 | 
			
		||||
                 cairo_region_t    *clip_region)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->clip_region, (GDestroyNotify) cairo_region_destroy);
 | 
			
		||||
  if (clip_region)
 | 
			
		||||
    priv->clip_region = cairo_region_copy (clip_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexture *self = (MetaShapedTexture *) object;
 | 
			
		||||
  MetaShapedTexturePrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->paint_tower)
 | 
			
		||||
    meta_texture_tower_free (priv->paint_tower);
 | 
			
		||||
  priv->paint_tower = NULL;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&priv->paint_tower, meta_texture_tower_free);
 | 
			
		||||
  g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free);
 | 
			
		||||
  g_clear_pointer (&priv->texture, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->texture_right, cogl_object_unref);
 | 
			
		||||
  g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_set_mask_texture (self, NULL);
 | 
			
		||||
  meta_shaped_texture_set_clip_region (self, NULL);
 | 
			
		||||
  set_unobscured_region (self, NULL);
 | 
			
		||||
  set_clip_region (self, NULL);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
@@ -193,54 +235,23 @@ paint_clipped_rectangle (CoglFramebuffer       *fb,
 | 
			
		||||
  cogl_framebuffer_draw_multitextured_rectangle (fb, pipeline,
 | 
			
		||||
                                                 x1, y1, x2, y2,
 | 
			
		||||
                                                 &coords[0], 8);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
paint_texture (MetaShapedTexture *stex,
 | 
			
		||||
	       CoglTexture       *paint_tex)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexture *stex = (MetaShapedTexture *) actor;
 | 
			
		||||
  ClutterActor *actor = CLUTTER_ACTOR (stex);
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
  guint tex_width, tex_height;
 | 
			
		||||
  guchar opacity;
 | 
			
		||||
  CoglContext *ctx;
 | 
			
		||||
  CoglFramebuffer *fb;
 | 
			
		||||
  CoglPipeline *pipeline = NULL;
 | 
			
		||||
  CoglTexture *paint_tex;
 | 
			
		||||
  ClutterActorBox alloc;
 | 
			
		||||
  cairo_region_t *blended_region = NULL;
 | 
			
		||||
  CoglPipelineFilter filter;
 | 
			
		||||
 | 
			
		||||
  if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
 | 
			
		||||
    clutter_actor_realize (CLUTTER_ACTOR (stex));
 | 
			
		||||
 | 
			
		||||
  /* The GL EXT_texture_from_pixmap extension does allow for it to be
 | 
			
		||||
   * used together with SGIS_generate_mipmap, however this is very
 | 
			
		||||
   * rarely supported. Also, even when it is supported there
 | 
			
		||||
   * are distinct performance implications from:
 | 
			
		||||
   *
 | 
			
		||||
   *  - Updating mipmaps that we don't need
 | 
			
		||||
   *  - Having to reallocate pixmaps on the server into larger buffers
 | 
			
		||||
   *
 | 
			
		||||
   * So, we just unconditionally use our mipmap emulation code. If we
 | 
			
		||||
   * wanted to use SGIS_generate_mipmap, we'd have to  query COGL to
 | 
			
		||||
   * see if it was supported (no API currently), and then if and only
 | 
			
		||||
   * if that was the case, set the clutter texture quality to HIGH.
 | 
			
		||||
   * Setting the texture quality to high without SGIS_generate_mipmap
 | 
			
		||||
   * support for TFP textures will result in fallbacks to XGetImage.
 | 
			
		||||
   */
 | 
			
		||||
  if (priv->create_mipmaps)
 | 
			
		||||
    paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
 | 
			
		||||
  else
 | 
			
		||||
    paint_tex = COGL_TEXTURE (priv->texture);
 | 
			
		||||
 | 
			
		||||
  if (paint_tex == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tex_width = priv->tex_width;
 | 
			
		||||
  tex_height = priv->tex_height;
 | 
			
		||||
 | 
			
		||||
@@ -253,18 +264,11 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
  filter = COGL_PIPELINE_FILTER_LINEAR;
 | 
			
		||||
 | 
			
		||||
  if (!clutter_actor_is_in_clone_paint (actor))
 | 
			
		||||
    {
 | 
			
		||||
      int x_origin, y_origin;
 | 
			
		||||
  if (!clutter_actor_is_in_clone_paint (actor) && meta_actor_is_untransformed (actor, NULL, NULL))
 | 
			
		||||
    filter = COGL_PIPELINE_FILTER_NEAREST;
 | 
			
		||||
 | 
			
		||||
      if (meta_actor_is_untransformed (actor,
 | 
			
		||||
                                       &x_origin,
 | 
			
		||||
                                       &y_origin))
 | 
			
		||||
        filter = COGL_PIPELINE_FILTER_NEAREST;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
  fb = cogl_get_draw_framebuffer ();
 | 
			
		||||
  ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
 | 
			
		||||
  opacity = clutter_actor_get_paint_opacity (actor);
 | 
			
		||||
  clutter_actor_get_allocation_box (actor, &alloc);
 | 
			
		||||
@@ -387,6 +391,74 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
    cairo_region_destroy (blended_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexture *stex = (MetaShapedTexture *) actor;
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
  CoglFramebuffer *fb;
 | 
			
		||||
  gboolean stereo;
 | 
			
		||||
  CoglTexture *paint_tex;
 | 
			
		||||
  CoglTexture *paint_tex_right;
 | 
			
		||||
 | 
			
		||||
  if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
 | 
			
		||||
    clutter_actor_realize (CLUTTER_ACTOR (stex));
 | 
			
		||||
 | 
			
		||||
  /* The GL EXT_texture_from_pixmap extension does allow for it to be
 | 
			
		||||
   * used together with SGIS_generate_mipmap, however this is very
 | 
			
		||||
   * rarely supported. Also, even when it is supported there
 | 
			
		||||
   * are distinct performance implications from:
 | 
			
		||||
   *
 | 
			
		||||
   *  - Updating mipmaps that we don't need
 | 
			
		||||
   *  - Having to reallocate pixmaps on the server into larger buffers
 | 
			
		||||
   *
 | 
			
		||||
   * So, we just unconditionally use our mipmap emulation code. If we
 | 
			
		||||
   * wanted to use SGIS_generate_mipmap, we'd have to  query COGL to
 | 
			
		||||
   * see if it was supported (no API currently), and then if and only
 | 
			
		||||
   * if that was the case, set the clutter texture quality to HIGH.
 | 
			
		||||
   * Setting the texture quality to high without SGIS_generate_mipmap
 | 
			
		||||
   * support for TFP textures will result in fallbacks to XGetImage.
 | 
			
		||||
   */
 | 
			
		||||
  if (priv->create_mipmaps)
 | 
			
		||||
    paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
 | 
			
		||||
  else
 | 
			
		||||
    paint_tex = COGL_TEXTURE (priv->texture);
 | 
			
		||||
 | 
			
		||||
  fb = cogl_get_draw_framebuffer ();
 | 
			
		||||
 | 
			
		||||
  stereo = priv->stereo && cogl_framebuffer_get_is_stereo (fb);
 | 
			
		||||
 | 
			
		||||
  if (stereo)
 | 
			
		||||
    {
 | 
			
		||||
      if (priv->create_mipmaps)
 | 
			
		||||
	paint_tex_right = meta_texture_tower_get_paint_texture (priv->paint_tower_right);
 | 
			
		||||
      else
 | 
			
		||||
	paint_tex_right = COGL_TEXTURE (priv->texture_right);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    paint_tex_right = NULL;
 | 
			
		||||
 | 
			
		||||
  if (paint_tex != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (stereo)
 | 
			
		||||
	cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_LEFT);
 | 
			
		||||
      else
 | 
			
		||||
	cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH);
 | 
			
		||||
 | 
			
		||||
      paint_texture (stex, paint_tex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (paint_tex_right != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_RIGHT);
 | 
			
		||||
      paint_texture (stex, paint_tex_right);
 | 
			
		||||
      cogl_framebuffer_set_stereo_mode (fb, COGL_STEREO_BOTH);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_pick (ClutterActor       *actor,
 | 
			
		||||
			  const ClutterColor *color)
 | 
			
		||||
@@ -394,45 +466,60 @@ meta_shaped_texture_pick (ClutterActor       *actor,
 | 
			
		||||
  MetaShapedTexture *stex = (MetaShapedTexture *) actor;
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (!clutter_actor_should_pick_paint (actor) ||
 | 
			
		||||
      (priv->clip_region && cairo_region_is_empty (priv->clip_region)))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* If there is no region then use the regular pick */
 | 
			
		||||
  if (priv->mask_texture == NULL)
 | 
			
		||||
  if (priv->input_shape_region == NULL)
 | 
			
		||||
    CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)->pick (actor, color);
 | 
			
		||||
  else if (clutter_actor_should_pick_paint (actor))
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      CoglTexture *paint_tex;
 | 
			
		||||
      ClutterActorBox alloc;
 | 
			
		||||
      guint tex_width, tex_height;
 | 
			
		||||
      int n_rects;
 | 
			
		||||
      float *rectangles;
 | 
			
		||||
      int i;
 | 
			
		||||
      CoglPipeline *pipeline;
 | 
			
		||||
      CoglContext *ctx;
 | 
			
		||||
      CoglFramebuffer *fb;
 | 
			
		||||
      CoglColor cogl_color;
 | 
			
		||||
 | 
			
		||||
      paint_tex = COGL_TEXTURE (priv->texture);
 | 
			
		||||
      /* Note: We don't bother trying to intersect the pick and clip regions
 | 
			
		||||
       * since needing to copy the region, do the intersection, and probably
 | 
			
		||||
       * increase the number of rectangles seems more likely to have a negative
 | 
			
		||||
       * effect.
 | 
			
		||||
       *
 | 
			
		||||
       * NB: Most of the time when just using rectangles for picking then
 | 
			
		||||
       * picking shouldn't involve any rendering, and minimizing the number of
 | 
			
		||||
       * rectangles has more benefit than reducing the area of the pick
 | 
			
		||||
       * region.
 | 
			
		||||
       */
 | 
			
		||||
 | 
			
		||||
      if (paint_tex == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
      n_rects = cairo_region_num_rectangles (priv->input_shape_region);
 | 
			
		||||
      rectangles = g_alloca (sizeof (float) * 4 * n_rects);
 | 
			
		||||
 | 
			
		||||
      tex_width = cogl_texture_get_width (paint_tex);
 | 
			
		||||
      tex_height = cogl_texture_get_height (paint_tex);
 | 
			
		||||
      for (i = 0; i < n_rects; i++)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_rectangle_int_t rect;
 | 
			
		||||
          int pos = i * 4;
 | 
			
		||||
 | 
			
		||||
      if (tex_width == 0 || tex_height == 0) /* no contents yet */
 | 
			
		||||
        return;
 | 
			
		||||
          cairo_region_get_rectangle (priv->input_shape_region, i, &rect);
 | 
			
		||||
 | 
			
		||||
          rectangles[pos] = rect.x;
 | 
			
		||||
          rectangles[pos + 1] = rect.y;
 | 
			
		||||
          rectangles[pos + 2] = rect.x + rect.width;
 | 
			
		||||
          rectangles[pos + 3] = rect.y + rect.height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
      fb = cogl_get_draw_framebuffer ();
 | 
			
		||||
 | 
			
		||||
      cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha);
 | 
			
		||||
 | 
			
		||||
      pipeline = get_masked_pipeline (ctx);
 | 
			
		||||
      cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture);
 | 
			
		||||
      pipeline = cogl_pipeline_new (ctx);
 | 
			
		||||
      cogl_pipeline_set_color (pipeline, &cogl_color);
 | 
			
		||||
 | 
			
		||||
      clutter_actor_get_allocation_box (actor, &alloc);
 | 
			
		||||
 | 
			
		||||
      cogl_framebuffer_draw_rectangle (fb, pipeline,
 | 
			
		||||
                                       0, 0,
 | 
			
		||||
                                       alloc.x2 - alloc.x1,
 | 
			
		||||
                                       alloc.y2 - alloc.y1);
 | 
			
		||||
      cogl_framebuffer_draw_rectangles (fb, pipeline,
 | 
			
		||||
                                        rectangles, n_rects);
 | 
			
		||||
      cogl_object_unref (pipeline);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -476,18 +563,37 @@ meta_shaped_texture_get_preferred_height (ClutterActor *self,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_shaped_texture_get_paint_volume (ClutterActor *self,
 | 
			
		||||
meta_shaped_texture_get_paint_volume (ClutterActor *actor,
 | 
			
		||||
                                      ClutterPaintVolume *volume)
 | 
			
		||||
{
 | 
			
		||||
  return clutter_paint_volume_set_from_allocation (volume, self);
 | 
			
		||||
}
 | 
			
		||||
  MetaShapedTexture *self = META_SHAPED_TEXTURE (actor);
 | 
			
		||||
  cairo_rectangle_int_t unobscured_bounds;
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
meta_shaped_texture_new (void)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *self = g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
 | 
			
		||||
  if (!clutter_paint_volume_set_from_allocation (volume, actor))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return self;
 | 
			
		||||
  if (meta_shaped_texture_get_unobscured_bounds (self, &unobscured_bounds))
 | 
			
		||||
    {
 | 
			
		||||
      ClutterVertex origin;
 | 
			
		||||
      cairo_rectangle_int_t bounds;
 | 
			
		||||
 | 
			
		||||
      /* I hate ClutterPaintVolume so much... */
 | 
			
		||||
      clutter_paint_volume_get_origin (volume, &origin);
 | 
			
		||||
      bounds.x = origin.x;
 | 
			
		||||
      bounds.y = origin.y;
 | 
			
		||||
      bounds.width = clutter_paint_volume_get_width (volume);
 | 
			
		||||
      bounds.height = clutter_paint_volume_get_height (volume);
 | 
			
		||||
 | 
			
		||||
      gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
 | 
			
		||||
 | 
			
		||||
      origin.x = bounds.x;
 | 
			
		||||
      origin.y = bounds.y;
 | 
			
		||||
      clutter_paint_volume_set_origin (volume, &origin);
 | 
			
		||||
      clutter_paint_volume_set_width (volume, bounds.width);
 | 
			
		||||
      clutter_paint_volume_set_height (volume, bounds.height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -506,9 +612,14 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
 | 
			
		||||
    {
 | 
			
		||||
      CoglTexture *base_texture;
 | 
			
		||||
      priv->create_mipmaps = create_mipmaps;
 | 
			
		||||
      base_texture = create_mipmaps ?
 | 
			
		||||
        COGL_TEXTURE (priv->texture) : NULL;
 | 
			
		||||
      base_texture = create_mipmaps ? priv->texture : NULL;
 | 
			
		||||
      meta_texture_tower_set_base_texture (priv->paint_tower, base_texture);
 | 
			
		||||
 | 
			
		||||
      if (priv->stereo)
 | 
			
		||||
	{
 | 
			
		||||
	  base_texture = create_mipmaps ? priv->texture_right : NULL;
 | 
			
		||||
	  meta_texture_tower_set_base_texture (priv->paint_tower_right, base_texture);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -533,6 +644,49 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
 | 
			
		||||
  clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
effective_unobscured_region (MetaShapedTexture *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv = self->priv;
 | 
			
		||||
  ClutterActor *parent = clutter_actor_get_parent (CLUTTER_ACTOR (self));
 | 
			
		||||
 | 
			
		||||
  if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  while (parent && !META_IS_WINDOW_ACTOR (parent))
 | 
			
		||||
    parent = clutter_actor_get_parent (parent);
 | 
			
		||||
 | 
			
		||||
  if (parent && clutter_actor_has_mapped_clones (parent))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  return priv->unobscured_region;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture     *self,
 | 
			
		||||
                                           cairo_rectangle_int_t *unobscured_bounds)
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *unobscured_region = effective_unobscured_region (self);
 | 
			
		||||
 | 
			
		||||
  if (unobscured_region)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_get_extents (unobscured_region, unobscured_bounds);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_shaped_texture_is_obscured (MetaShapedTexture *self)
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *unobscured_region = effective_unobscured_region (self);
 | 
			
		||||
 | 
			
		||||
  if (unobscured_region)
 | 
			
		||||
    return cairo_region_is_empty (unobscured_region);
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_update_area:
 | 
			
		||||
@@ -541,14 +695,9 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
 | 
			
		||||
 * @y: the y coordinate of the damaged area
 | 
			
		||||
 * @width: the width of the damaged area
 | 
			
		||||
 * @height: the height of the damaged area
 | 
			
		||||
 * @unobscured_region: The unobscured region of the window or %NULL if
 | 
			
		||||
 * there is no valid one (like when the actor is transformed or
 | 
			
		||||
 * has a mapped clone)
 | 
			
		||||
 *
 | 
			
		||||
 * Repairs the damaged area indicated by @x, @y, @width and @height
 | 
			
		||||
 * and queues a redraw for the intersection @visibible_region and
 | 
			
		||||
 * the damage area. If @visibible_region is %NULL a redraw will always
 | 
			
		||||
 * get queued.
 | 
			
		||||
 * and potentially queues a redraw.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: Whether a redraw have been queued or not
 | 
			
		||||
 */
 | 
			
		||||
@@ -557,10 +706,10 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
 | 
			
		||||
				 int                x,
 | 
			
		||||
				 int                y,
 | 
			
		||||
				 int                width,
 | 
			
		||||
				 int                height,
 | 
			
		||||
				 cairo_region_t    *unobscured_region)
 | 
			
		||||
				 int                height)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
  cairo_region_t *unobscured_region;
 | 
			
		||||
  const cairo_rectangle_int_t clip = { x, y, width, height };
 | 
			
		||||
 | 
			
		||||
  priv = stex->priv;
 | 
			
		||||
@@ -568,11 +717,11 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
 | 
			
		||||
  if (priv->texture == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  cogl_texture_pixmap_x11_update_area (priv->texture,
 | 
			
		||||
                                       x, y, width, height);
 | 
			
		||||
 | 
			
		||||
  meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
 | 
			
		||||
  if (priv->stereo)
 | 
			
		||||
    meta_texture_tower_update_area (priv->paint_tower_right, x, y, width, height);
 | 
			
		||||
 | 
			
		||||
  unobscured_region = effective_unobscured_region (stex);
 | 
			
		||||
  if (unobscured_region)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_t *intersection;
 | 
			
		||||
@@ -589,23 +738,23 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
 | 
			
		||||
          cairo_region_get_extents (intersection, &damage_rect);
 | 
			
		||||
          clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &damage_rect);
 | 
			
		||||
          cairo_region_destroy (intersection);
 | 
			
		||||
 | 
			
		||||
          return TRUE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      cairo_region_destroy (intersection);
 | 
			
		||||
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_cogl_texture (MetaShapedTexture    *stex,
 | 
			
		||||
                  CoglTexturePixmapX11 *cogl_tex)
 | 
			
		||||
set_cogl_texture (MetaShapedTexture *stex,
 | 
			
		||||
                  CoglTexture       *cogl_tex,
 | 
			
		||||
		  gboolean           stereo)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
  guint width, height;
 | 
			
		||||
@@ -616,8 +765,23 @@ set_cogl_texture (MetaShapedTexture    *stex,
 | 
			
		||||
 | 
			
		||||
  if (priv->texture != NULL)
 | 
			
		||||
    cogl_object_unref (priv->texture);
 | 
			
		||||
  if (priv->texture_right != NULL)
 | 
			
		||||
    cogl_object_unref (priv->texture_right);
 | 
			
		||||
 | 
			
		||||
  priv->stereo = stereo;
 | 
			
		||||
 | 
			
		||||
  priv->texture = cogl_tex;
 | 
			
		||||
  if (priv->stereo)
 | 
			
		||||
    {
 | 
			
		||||
      priv->texture_right = cogl_texture_pixmap_x11_new_right ((CoglTexturePixmapX11 *)cogl_tex);
 | 
			
		||||
      if (priv->paint_tower_right == NULL)
 | 
			
		||||
	priv->paint_tower_right = meta_texture_tower_new ();
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      priv->texture_right = NULL;
 | 
			
		||||
      g_clear_pointer (&priv->paint_tower_right, meta_texture_tower_free);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (cogl_tex != NULL)
 | 
			
		||||
    {
 | 
			
		||||
@@ -635,47 +799,38 @@ set_cogl_texture (MetaShapedTexture    *stex,
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* size changed to 0 going to an inavlid texture */
 | 
			
		||||
      /* size changed to 0 going to an invalid texture */
 | 
			
		||||
      priv->tex_width = 0;
 | 
			
		||||
      priv->tex_height = 0;
 | 
			
		||||
      clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
 | 
			
		||||
  /* NB: We don't queue a redraw of the actor here because we don't
 | 
			
		||||
   * know how much of the buffer has changed with respect to the
 | 
			
		||||
   * previous buffer. We only queue a redraw in response to surface
 | 
			
		||||
   * damage. */
 | 
			
		||||
 | 
			
		||||
  if (priv->create_mipmaps)
 | 
			
		||||
    {
 | 
			
		||||
      meta_texture_tower_set_base_texture (priv->paint_tower, cogl_tex);
 | 
			
		||||
      if (priv->stereo)
 | 
			
		||||
	meta_texture_tower_set_base_texture (priv->paint_tower_right, priv->texture_right);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_set_pixmap:
 | 
			
		||||
 * meta_shaped_texture_set_texture:
 | 
			
		||||
 * @stex: The #MetaShapedTexture
 | 
			
		||||
 * @pixmap: The pixmap you want the stex to assume
 | 
			
		||||
 * @pixmap: The #CoglTexture to display
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
 | 
			
		||||
                                Pixmap             pixmap)
 | 
			
		||||
meta_shaped_texture_set_texture (MetaShapedTexture *stex,
 | 
			
		||||
                                 CoglTexture       *texture,
 | 
			
		||||
				 gboolean           stereo)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
 | 
			
		||||
 | 
			
		||||
  priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->pixmap == pixmap)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv->pixmap = pixmap;
 | 
			
		||||
 | 
			
		||||
  if (pixmap != None)
 | 
			
		||||
    {
 | 
			
		||||
      CoglContext *ctx =
 | 
			
		||||
        clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
      set_cogl_texture (stex, cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL));
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    set_cogl_texture (stex, NULL);
 | 
			
		||||
 | 
			
		||||
  if (priv->create_mipmaps)
 | 
			
		||||
    meta_texture_tower_set_base_texture (priv->paint_tower,
 | 
			
		||||
                                         COGL_TEXTURE (priv->texture));
 | 
			
		||||
  set_cogl_texture (stex, texture, stereo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -692,22 +847,18 @@ meta_shaped_texture_get_texture (MetaShapedTexture *stex)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_set_clip_region:
 | 
			
		||||
 * meta_shaped_texture_set_input_shape_region:
 | 
			
		||||
 * @stex: a #MetaShapedTexture
 | 
			
		||||
 * @clip_region: the region of the texture that is visible and
 | 
			
		||||
 *   should be painted.
 | 
			
		||||
 * @shape_region: the region of the texture that should respond to
 | 
			
		||||
 *    input.
 | 
			
		||||
 *
 | 
			
		||||
 * Provides a hint to the texture about what areas of the texture
 | 
			
		||||
 * are not completely obscured and thus need to be painted. This
 | 
			
		||||
 * is an optimization and is not supposed to have any effect on
 | 
			
		||||
 * the output.
 | 
			
		||||
 *
 | 
			
		||||
 * Typically a parent container will set the clip region before
 | 
			
		||||
 * painting its children, and then unset it afterwards.
 | 
			
		||||
 * Determines what region of the texture should accept input. For
 | 
			
		||||
 * X based windows this is defined by the ShapeInput region of the
 | 
			
		||||
 * window.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
 | 
			
		||||
				     cairo_region_t    *clip_region)
 | 
			
		||||
meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
 | 
			
		||||
                                            cairo_region_t    *shape_region)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
 | 
			
		||||
@@ -715,13 +866,19 @@ meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
 | 
			
		||||
 | 
			
		||||
  priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->clip_region)
 | 
			
		||||
    cairo_region_destroy (priv->clip_region);
 | 
			
		||||
  if (priv->input_shape_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_destroy (priv->input_shape_region);
 | 
			
		||||
      priv->input_shape_region = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (clip_region)
 | 
			
		||||
    priv->clip_region = cairo_region_copy (clip_region);
 | 
			
		||||
  else
 | 
			
		||||
    priv->clip_region = NULL;
 | 
			
		||||
  if (shape_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_reference (shape_region);
 | 
			
		||||
      priv->input_shape_region = shape_region;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -851,3 +1008,46 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
 | 
			
		||||
 | 
			
		||||
  return surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_cull_out (MetaCullable   *cullable,
 | 
			
		||||
                              cairo_region_t *unobscured_region,
 | 
			
		||||
                              cairo_region_t *clip_region)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable);
 | 
			
		||||
  MetaShapedTexturePrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  set_unobscured_region (self, unobscured_region);
 | 
			
		||||
  set_clip_region (self, clip_region);
 | 
			
		||||
 | 
			
		||||
  if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (self)) == 0xff)
 | 
			
		||||
    {
 | 
			
		||||
      if (priv->opaque_region)
 | 
			
		||||
        {
 | 
			
		||||
          if (unobscured_region)
 | 
			
		||||
            cairo_region_subtract (unobscured_region, priv->opaque_region);
 | 
			
		||||
          if (clip_region)
 | 
			
		||||
            cairo_region_subtract (clip_region, priv->opaque_region);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_reset_culling (MetaCullable *cullable)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable);
 | 
			
		||||
  set_clip_region (self, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cullable_iface_init (MetaCullableInterface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->cull_out = meta_shaped_texture_cull_out;
 | 
			
		||||
  iface->reset_culling = meta_shaped_texture_reset_culling;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
meta_shaped_texture_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,9 +18,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
@@ -28,41 +26,6 @@
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include "meta-texture-rectangle.h"
 | 
			
		||||
 | 
			
		||||
CoglTexture *
 | 
			
		||||
meta_texture_rectangle_new (unsigned int width,
 | 
			
		||||
                            unsigned int height,
 | 
			
		||||
                            CoglPixelFormat format,
 | 
			
		||||
                            CoglPixelFormat internal_format,
 | 
			
		||||
                            unsigned int rowstride,
 | 
			
		||||
                            const guint8 *data,
 | 
			
		||||
                            GError **error)
 | 
			
		||||
{
 | 
			
		||||
  ClutterBackend *backend =
 | 
			
		||||
    clutter_get_default_backend ();
 | 
			
		||||
  CoglContext *context =
 | 
			
		||||
    clutter_backend_get_cogl_context (backend);
 | 
			
		||||
  CoglTextureRectangle *tex_rect;
 | 
			
		||||
 | 
			
		||||
  tex_rect = cogl_texture_rectangle_new_with_size (context,
 | 
			
		||||
                                                   width, height,
 | 
			
		||||
                                                   internal_format,
 | 
			
		||||
                                                   error);
 | 
			
		||||
  if (tex_rect == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (data)
 | 
			
		||||
    cogl_texture_set_region (COGL_TEXTURE (tex_rect),
 | 
			
		||||
                             0, 0, /* src_x/y */
 | 
			
		||||
                             0, 0, /* dst_x/y */
 | 
			
		||||
                             width, height, /* dst_width/height */
 | 
			
		||||
                             width, height, /* width/height */
 | 
			
		||||
                             format,
 | 
			
		||||
                             rowstride,
 | 
			
		||||
                             data);
 | 
			
		||||
 | 
			
		||||
  return COGL_TEXTURE (tex_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
texture_rectangle_check_cb (CoglTexture *sub_texture,
 | 
			
		||||
                            const float *sub_texture_coords,
 | 
			
		||||
 
 | 
			
		||||
@@ -18,9 +18,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __META_TEXTURE_RECTANGLE_H__
 | 
			
		||||
@@ -30,15 +28,6 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
CoglTexture *
 | 
			
		||||
meta_texture_rectangle_new (unsigned int width,
 | 
			
		||||
                            unsigned int height,
 | 
			
		||||
                            CoglPixelFormat format,
 | 
			
		||||
                            CoglPixelFormat internal_format,
 | 
			
		||||
                            unsigned int rowstride,
 | 
			
		||||
                            const guint8 *data,
 | 
			
		||||
                            GError **error);
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_texture_rectangle_check (CoglTexture *texture);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
@@ -361,18 +359,10 @@ texture_tower_create_texture (MetaTextureTower *tower,
 | 
			
		||||
  if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
 | 
			
		||||
      meta_texture_rectangle_check (tower->textures[level - 1]))
 | 
			
		||||
    {
 | 
			
		||||
      tower->textures[level] =
 | 
			
		||||
        meta_texture_rectangle_new (width, height,
 | 
			
		||||
                                    /* data format */
 | 
			
		||||
                                    TEXTURE_FORMAT,
 | 
			
		||||
                                    /* internal cogl format */
 | 
			
		||||
                                    TEXTURE_FORMAT,
 | 
			
		||||
                                    /* rowstride */
 | 
			
		||||
                                    width * 4,
 | 
			
		||||
                                    /* data */
 | 
			
		||||
                                    NULL,
 | 
			
		||||
                                    /* error */
 | 
			
		||||
                                    NULL);
 | 
			
		||||
      ClutterBackend *backend = clutter_get_default_backend ();
 | 
			
		||||
      CoglContext *context = clutter_backend_get_cogl_context (backend);
 | 
			
		||||
 | 
			
		||||
      tower->textures[level] = cogl_texture_rectangle_new_with_size (context, width, height);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __META_TEXTURE_TOWER_H__
 | 
			
		||||
 
 | 
			
		||||
@@ -35,13 +35,13 @@ void meta_window_actor_frame_complete (MetaWindowActor    *self,
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state);
 | 
			
		||||
 | 
			
		||||
gboolean meta_window_actor_should_unredirect (MetaWindowActor *self);
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_get_shape_bounds (MetaWindowActor       *self,
 | 
			
		||||
                                          cairo_rectangle_int_t *bounds);
 | 
			
		||||
 | 
			
		||||
gboolean meta_window_actor_should_unredirect   (MetaWindowActor *self);
 | 
			
		||||
void     meta_window_actor_set_unredirected    (MetaWindowActor *self,
 | 
			
		||||
                                                gboolean         unredirected);
 | 
			
		||||
 | 
			
		||||
gboolean meta_window_actor_effect_in_progress  (MetaWindowActor *self);
 | 
			
		||||
void     meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
 | 
			
		||||
                                                gboolean         did_placement);
 | 
			
		||||
@@ -55,18 +55,14 @@ void     meta_window_actor_set_updates_frozen  (MetaWindowActor *self,
 | 
			
		||||
void     meta_window_actor_queue_frame_drawn   (MetaWindowActor *self,
 | 
			
		||||
                                                gboolean         no_delay_frame);
 | 
			
		||||
 | 
			
		||||
cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self);
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_set_clip_region         (MetaWindowActor *self,
 | 
			
		||||
                                                cairo_region_t  *clip_region);
 | 
			
		||||
void meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
 | 
			
		||||
                                                cairo_region_t  *beneath_region);
 | 
			
		||||
void meta_window_actor_reset_clip_regions      (MetaWindowActor *self);
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_set_unobscured_region      (MetaWindowActor *self,
 | 
			
		||||
                                                   cairo_region_t  *unobscured_region);
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_effect_completed (MetaWindowActor *actor,
 | 
			
		||||
                                         gulong           event);
 | 
			
		||||
 | 
			
		||||
void     meta_window_actor_stereo_notify (MetaWindowActor *actor,
 | 
			
		||||
                                          gboolean         stereo_tree);
 | 
			
		||||
 | 
			
		||||
gboolean meta_window_actor_is_stereo (MetaWindowActor *actor);
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_detach (MetaWindowActor *self);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WINDOW_ACTOR_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -11,8 +11,8 @@
 | 
			
		||||
#include "compositor-private.h"
 | 
			
		||||
#include "meta-window-actor-private.h"
 | 
			
		||||
#include "meta-window-group.h"
 | 
			
		||||
#include "meta-background-actor-private.h"
 | 
			
		||||
#include "meta-background-group-private.h"
 | 
			
		||||
#include "window-private.h"
 | 
			
		||||
#include "meta-cullable.h"
 | 
			
		||||
 | 
			
		||||
struct _MetaWindowGroupClass
 | 
			
		||||
{
 | 
			
		||||
@@ -26,7 +26,10 @@ struct _MetaWindowGroup
 | 
			
		||||
  MetaScreen *screen;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR);
 | 
			
		||||
static void cullable_iface_init (MetaCullableInterface *iface);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR,
 | 
			
		||||
                         G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
 | 
			
		||||
 | 
			
		||||
/* Help macros to scale from OpenGL <-1,1> coordinates system to
 | 
			
		||||
 * window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c
 | 
			
		||||
@@ -86,33 +89,40 @@ painting_untransformed (MetaWindowGroup *window_group,
 | 
			
		||||
  return meta_actor_vertices_are_untransformed (vertices, width, height, x_origin, y_origin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_group_cull_out (MetaCullable   *cullable,
 | 
			
		||||
                            cairo_region_t *unobscured_region,
 | 
			
		||||
                            cairo_region_t *clip_region)
 | 
			
		||||
{
 | 
			
		||||
  meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_group_reset_culling (MetaCullable *cullable)
 | 
			
		||||
{
 | 
			
		||||
  meta_cullable_reset_culling_children (cullable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cullable_iface_init (MetaCullableInterface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->cull_out = meta_window_group_cull_out;
 | 
			
		||||
  iface->reset_culling = meta_window_group_reset_culling;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *clip_region;
 | 
			
		||||
  cairo_region_t *unobscured_region;
 | 
			
		||||
  ClutterActorIter iter;
 | 
			
		||||
  ClutterActor *child;
 | 
			
		||||
  cairo_rectangle_int_t visible_rect, clip_rect;
 | 
			
		||||
  int paint_x_offset, paint_y_offset;
 | 
			
		||||
  int paint_x_origin, paint_y_origin;
 | 
			
		||||
  int actor_x_origin, actor_y_origin;
 | 
			
		||||
  int paint_x_offset, paint_y_offset;
 | 
			
		||||
 | 
			
		||||
  MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
 | 
			
		||||
  ClutterActor *stage = clutter_actor_get_stage (actor);
 | 
			
		||||
 | 
			
		||||
  /* Start off by treating all windows as completely unobscured, so damage anywhere
 | 
			
		||||
   * in a window queues redraws, but confine it more below. */
 | 
			
		||||
  clutter_actor_iter_init (&iter, actor);
 | 
			
		||||
  while (clutter_actor_iter_next (&iter, &child))
 | 
			
		||||
    {
 | 
			
		||||
      if (META_IS_WINDOW_ACTOR (child))
 | 
			
		||||
        {
 | 
			
		||||
          MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
 | 
			
		||||
          meta_window_actor_set_unobscured_region (window_actor, NULL);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
 | 
			
		||||
 | 
			
		||||
  /* Normally we expect an actor to be drawn at it's position on the screen.
 | 
			
		||||
   * However, if we're inside the paint of a ClutterClone, that won't be the
 | 
			
		||||
@@ -134,9 +144,6 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  paint_x_offset = paint_x_origin - actor_x_origin;
 | 
			
		||||
  paint_y_offset = paint_y_origin - actor_y_origin;
 | 
			
		||||
 | 
			
		||||
  visible_rect.x = visible_rect.y = 0;
 | 
			
		||||
  visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
 | 
			
		||||
  visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
 | 
			
		||||
@@ -154,134 +161,53 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
  clip_region = cairo_region_create_rectangle (&clip_rect);
 | 
			
		||||
 | 
			
		||||
  paint_x_offset = paint_x_origin - actor_x_origin;
 | 
			
		||||
  paint_y_offset = paint_y_origin - actor_y_origin;
 | 
			
		||||
  cairo_region_translate (clip_region, -paint_x_offset, -paint_y_offset);
 | 
			
		||||
 | 
			
		||||
  if (info->unredirected_window != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t unredirected_rect;
 | 
			
		||||
      MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
 | 
			
		||||
 | 
			
		||||
      meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect);
 | 
			
		||||
      meta_window_get_frame_rect (info->unredirected_window, (MetaRectangle *)&unredirected_rect);
 | 
			
		||||
      cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect);
 | 
			
		||||
      cairo_region_subtract_rectangle (clip_region, &unredirected_rect);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* We walk the list from top to bottom (opposite of painting order),
 | 
			
		||||
   * and subtract the opaque area of each window out of the visible
 | 
			
		||||
   * region that we pass to the windows below.
 | 
			
		||||
   */
 | 
			
		||||
  clutter_actor_iter_init (&iter, actor);
 | 
			
		||||
  while (clutter_actor_iter_prev (&iter, &child))
 | 
			
		||||
    {
 | 
			
		||||
      if (!CLUTTER_ACTOR_IS_VISIBLE (child))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (info->unredirected_window != NULL &&
 | 
			
		||||
          child == CLUTTER_ACTOR (info->unredirected_window))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      /* If an actor has effects applied, then that can change the area
 | 
			
		||||
       * it paints and the opacity, so we no longer can figure out what
 | 
			
		||||
       * portion of the actor is obscured and what portion of the screen
 | 
			
		||||
       * it obscures, so we skip the actor.
 | 
			
		||||
       *
 | 
			
		||||
       * This has a secondary beneficial effect: if a ClutterOffscreenEffect
 | 
			
		||||
       * is applied to an actor, then our clipped redraws interfere with the
 | 
			
		||||
       * caching of the FBO - even if we only need to draw a small portion
 | 
			
		||||
       * of the window right now, ClutterOffscreenEffect may use other portions
 | 
			
		||||
       * of the FBO later. So, skipping actors with effects applied also
 | 
			
		||||
       * prevents these bugs.
 | 
			
		||||
       *
 | 
			
		||||
       * Theoretically, we should check clutter_actor_get_offscreen_redirect()
 | 
			
		||||
       * as well for the same reason, but omitted for simplicity in the
 | 
			
		||||
       * hopes that no-one will do that.
 | 
			
		||||
       */
 | 
			
		||||
      if (clutter_actor_has_effects (child))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (META_IS_WINDOW_ACTOR (child))
 | 
			
		||||
        {
 | 
			
		||||
          MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
 | 
			
		||||
          int x, y;
 | 
			
		||||
 | 
			
		||||
          if (!meta_actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          x += paint_x_offset;
 | 
			
		||||
          y += paint_y_offset;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
          /* Temporarily move to the coordinate system of the actor */
 | 
			
		||||
          cairo_region_translate (unobscured_region, - x, - y);
 | 
			
		||||
          cairo_region_translate (clip_region, - x, - y);
 | 
			
		||||
 | 
			
		||||
          meta_window_actor_set_unobscured_region (window_actor, unobscured_region);
 | 
			
		||||
          meta_window_actor_set_clip_region (window_actor, clip_region);
 | 
			
		||||
 | 
			
		||||
          if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
 | 
			
		||||
            {
 | 
			
		||||
              cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
 | 
			
		||||
              if (obscured_region)
 | 
			
		||||
                {
 | 
			
		||||
                  cairo_region_subtract (unobscured_region, obscured_region);
 | 
			
		||||
                  cairo_region_subtract (clip_region, obscured_region);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          meta_window_actor_set_clip_region_beneath (window_actor, clip_region);
 | 
			
		||||
 | 
			
		||||
          cairo_region_translate (unobscured_region, x, y);
 | 
			
		||||
          cairo_region_translate (clip_region, x, y);
 | 
			
		||||
        }
 | 
			
		||||
      else if (META_IS_BACKGROUND_ACTOR (child) ||
 | 
			
		||||
               META_IS_BACKGROUND_GROUP (child))
 | 
			
		||||
        {
 | 
			
		||||
          int x, y;
 | 
			
		||||
 | 
			
		||||
          if (!meta_actor_is_untransformed (child, &x, &y))
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          x += paint_x_offset;
 | 
			
		||||
          y += paint_y_offset;
 | 
			
		||||
 | 
			
		||||
          cairo_region_translate (clip_region, - x, - y);
 | 
			
		||||
 | 
			
		||||
          if (META_IS_BACKGROUND_GROUP (child))
 | 
			
		||||
            meta_background_group_set_clip_region (META_BACKGROUND_GROUP (child), clip_region);
 | 
			
		||||
          else
 | 
			
		||||
            meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (child), clip_region);
 | 
			
		||||
 | 
			
		||||
          cairo_region_translate (clip_region, x, y);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
 | 
			
		||||
 | 
			
		||||
  cairo_region_destroy (unobscured_region);
 | 
			
		||||
  cairo_region_destroy (clip_region);
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
 | 
			
		||||
 | 
			
		||||
  /* Now that we are done painting, unset the visible regions (they will
 | 
			
		||||
   * mess up painting clones of our actors)
 | 
			
		||||
   */
 | 
			
		||||
  clutter_actor_iter_init (&iter, actor);
 | 
			
		||||
  while (clutter_actor_iter_next (&iter, &child))
 | 
			
		||||
    {
 | 
			
		||||
      if (META_IS_WINDOW_ACTOR (child))
 | 
			
		||||
        {
 | 
			
		||||
          MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
 | 
			
		||||
          meta_window_actor_reset_clip_regions (window_actor);
 | 
			
		||||
        }
 | 
			
		||||
      else if (META_IS_BACKGROUND_ACTOR (child))
 | 
			
		||||
        {
 | 
			
		||||
          MetaBackgroundActor *background_actor = META_BACKGROUND_ACTOR (child);
 | 
			
		||||
          meta_background_actor_set_clip_region (background_actor, NULL);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  meta_cullable_reset_culling (META_CULLABLE (window_group));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Adapted from clutter_actor_update_default_paint_volume() */
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_window_group_get_paint_volume (ClutterActor       *actor,
 | 
			
		||||
meta_window_group_get_paint_volume (ClutterActor       *self,
 | 
			
		||||
                                    ClutterPaintVolume *volume)
 | 
			
		||||
{
 | 
			
		||||
  return clutter_paint_volume_set_from_allocation (volume, actor);
 | 
			
		||||
  ClutterActorIter iter;
 | 
			
		||||
  ClutterActor *child;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_iter_init (&iter, self);
 | 
			
		||||
  while (clutter_actor_iter_next (&iter, &child))
 | 
			
		||||
    {
 | 
			
		||||
      const ClutterPaintVolume *child_volume;
 | 
			
		||||
 | 
			
		||||
      if (!CLUTTER_ACTOR_IS_MAPPED (child))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      child_volume = clutter_actor_get_transformed_paint_volume (child, self);
 | 
			
		||||
      if (child_volume == NULL)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      clutter_paint_volume_union (volume, child_volume);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -11,29 +11,9 @@
 | 
			
		||||
 * MetaWindowGroup:
 | 
			
		||||
 *
 | 
			
		||||
 * This class is a subclass of ClutterActor with special handling for
 | 
			
		||||
 * MetaWindowActor/MetaBackgroundActor/MetaBackgroundGroup when painting
 | 
			
		||||
 * children.
 | 
			
		||||
 *
 | 
			
		||||
 * When we are painting a stack of 5-10 maximized windows, the
 | 
			
		||||
 * standard bottom-to-top method of drawing every actor results in a
 | 
			
		||||
 * tremendous amount of overdraw and can easily max out the available
 | 
			
		||||
 * memory bandwidth on a low-end graphics chipset. It's even worse if
 | 
			
		||||
 * window textures are being accessed over the AGP bus.
 | 
			
		||||
 *
 | 
			
		||||
 * The basic technique applied here is to do a pre-pass before painting
 | 
			
		||||
 * where we walk window from top to bottom and compute the visible area
 | 
			
		||||
 * at each step by subtracting out the windows above it. The visible
 | 
			
		||||
 * area is passed to MetaWindowActor which uses it to clip the portion of
 | 
			
		||||
 * the window which drawn and avoid redrawing the shadow if it is completely
 | 
			
		||||
 * obscured.
 | 
			
		||||
 *
 | 
			
		||||
 * A caveat is that this is ineffective if applications are using ARGB
 | 
			
		||||
 * visuals, since we have no way of knowing whether a window obscures
 | 
			
		||||
 * the windows behind it or not. Alternate approaches using the depth
 | 
			
		||||
 * or stencil buffer rather than client side regions might be able to
 | 
			
		||||
 * handle alpha windows, but the combination of glAlphaFunc and stenciling
 | 
			
		||||
 * tends not to be efficient except on newer cards. (And on newer cards
 | 
			
		||||
 * we have lots of memory and bandwidth.)
 | 
			
		||||
 * #MetaCullable when painting children. It uses code similar to
 | 
			
		||||
 * meta_cullable_cull_out_children(), but also has additional special
 | 
			
		||||
 * cases for the undirected window, and similar.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_WINDOW_GROUP            (meta_window_group_get_type ())
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __META_WINDOW_SHAPE_H__
 | 
			
		||||
 
 | 
			
		||||
@@ -16,20 +16,17 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-plugin.h>
 | 
			
		||||
#include <meta/window.h>
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
#include <meta/meta-background-group.h>
 | 
			
		||||
#include <meta/meta-background-actor.h>
 | 
			
		||||
 | 
			
		||||
#include <libintl.h>
 | 
			
		||||
#define _(x) dgettext (GETTEXT_PACKAGE, x)
 | 
			
		||||
#define N_(x) x
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
#include <glib/gi18n-lib.h>
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <gmodule.h>
 | 
			
		||||
@@ -42,6 +39,7 @@
 | 
			
		||||
#define SWITCH_TIMEOUT    500
 | 
			
		||||
 | 
			
		||||
#define ACTOR_DATA_KEY "MCCP-Default-actor-data"
 | 
			
		||||
#define SCREEN_TILE_PREVIEW_DATA_KEY "MCCP-Default-screen-tile-preview-data"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_DEFAULT_PLUGIN            (meta_default_plugin_get_type ())
 | 
			
		||||
#define META_DEFAULT_PLUGIN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEFAULT_PLUGIN, MetaDefaultPlugin))
 | 
			
		||||
@@ -70,6 +68,7 @@ struct _MetaDefaultPluginClass
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static GQuark actor_data_quark = 0;
 | 
			
		||||
static GQuark screen_tile_preview_data_quark = 0;
 | 
			
		||||
 | 
			
		||||
static void start      (MetaPlugin      *plugin);
 | 
			
		||||
static void minimize   (MetaPlugin      *plugin,
 | 
			
		||||
@@ -100,6 +99,12 @@ static void kill_window_effects   (MetaPlugin      *plugin,
 | 
			
		||||
                                   MetaWindowActor *actor);
 | 
			
		||||
static void kill_switch_workspace (MetaPlugin      *plugin);
 | 
			
		||||
 | 
			
		||||
static void show_tile_preview (MetaPlugin      *plugin,
 | 
			
		||||
                               MetaWindow      *window,
 | 
			
		||||
                               MetaRectangle   *tile_rect,
 | 
			
		||||
                               int              tile_monitor_number);
 | 
			
		||||
static void hide_tile_preview (MetaPlugin      *plugin);
 | 
			
		||||
 | 
			
		||||
static void confirm_display_change (MetaPlugin *plugin);
 | 
			
		||||
 | 
			
		||||
static const MetaPluginInfo * plugin_info (MetaPlugin *plugin);
 | 
			
		||||
@@ -146,6 +151,15 @@ typedef struct
 | 
			
		||||
} EffectCompleteData;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _ScreenTilePreview
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor   *actor;
 | 
			
		||||
 | 
			
		||||
  GdkRGBA        *preview_color;
 | 
			
		||||
 | 
			
		||||
  MetaRectangle   tile_rect;
 | 
			
		||||
} ScreenTilePreview;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_default_plugin_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
@@ -206,6 +220,8 @@ meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
 | 
			
		||||
  plugin_class->unmaximize       = unmaximize;
 | 
			
		||||
  plugin_class->destroy          = destroy;
 | 
			
		||||
  plugin_class->switch_workspace = switch_workspace;
 | 
			
		||||
  plugin_class->show_tile_preview = show_tile_preview;
 | 
			
		||||
  plugin_class->hide_tile_preview = hide_tile_preview;
 | 
			
		||||
  plugin_class->plugin_info      = plugin_info;
 | 
			
		||||
  plugin_class->kill_window_effects   = kill_window_effects;
 | 
			
		||||
  plugin_class->kill_switch_workspace = kill_switch_workspace;
 | 
			
		||||
@@ -292,26 +308,13 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
 | 
			
		||||
  meta_plugin_switch_workspace_completed (plugin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
show_stage (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaScreen *screen;
 | 
			
		||||
  ClutterActor *stage;
 | 
			
		||||
 | 
			
		||||
  screen = meta_plugin_get_screen (plugin);
 | 
			
		||||
  stage = meta_get_stage_for_screen (screen);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_show (stage);
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_monitors_changed (MetaScreen *screen,
 | 
			
		||||
                     MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin);
 | 
			
		||||
  int i, n;
 | 
			
		||||
  GRand *rand = g_rand_new_with_seed (12345);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_destroy_all_children (self->priv->background_group);
 | 
			
		||||
 | 
			
		||||
@@ -334,14 +337,16 @@ on_monitors_changed (MetaScreen *screen,
 | 
			
		||||
         reproducible.
 | 
			
		||||
      */
 | 
			
		||||
      clutter_color_init (&color,
 | 
			
		||||
                          g_random_int () % 255,
 | 
			
		||||
                          g_random_int () % 255,
 | 
			
		||||
                          g_random_int () % 255,
 | 
			
		||||
                          g_rand_int_range (rand, 0, 255),
 | 
			
		||||
                          g_rand_int_range (rand, 0, 255),
 | 
			
		||||
                          g_rand_int_range (rand, 0, 255),
 | 
			
		||||
                          255);
 | 
			
		||||
      clutter_actor_set_background_color (background, &color);
 | 
			
		||||
 | 
			
		||||
      clutter_actor_add_child (self->priv->background_group, background);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_rand_free (rand);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -358,10 +363,7 @@ start (MetaPlugin *plugin)
 | 
			
		||||
                    G_CALLBACK (on_monitors_changed), plugin);
 | 
			
		||||
  on_monitors_changed (screen, plugin);
 | 
			
		||||
 | 
			
		||||
  meta_later_add (META_LATER_BEFORE_REDRAW,
 | 
			
		||||
                  (GSourceFunc) show_stage,
 | 
			
		||||
                  plugin,
 | 
			
		||||
                  NULL);
 | 
			
		||||
  clutter_actor_show (meta_get_stage_for_screen (screen));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -410,9 +412,11 @@ switch_workspace (MetaPlugin *plugin,
 | 
			
		||||
      MetaWindowActor *window_actor = l->data;
 | 
			
		||||
      ActorPrivate    *apriv	    = get_actor_private (window_actor);
 | 
			
		||||
      ClutterActor    *actor	    = CLUTTER_ACTOR (window_actor);
 | 
			
		||||
      MetaWorkspace   *workspace;
 | 
			
		||||
      gint             win_workspace;
 | 
			
		||||
 | 
			
		||||
      win_workspace = meta_window_actor_get_workspace (window_actor);
 | 
			
		||||
      workspace = meta_window_get_workspace (meta_window_actor_get_meta_window (window_actor));
 | 
			
		||||
      win_workspace = meta_workspace_index (workspace);
 | 
			
		||||
 | 
			
		||||
      if (win_workspace == to || win_workspace == from)
 | 
			
		||||
        {
 | 
			
		||||
@@ -705,15 +709,15 @@ map (MetaPlugin *plugin, MetaWindowActor *window_actor)
 | 
			
		||||
      EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
 | 
			
		||||
      ActorPrivate *apriv = get_actor_private (window_actor);
 | 
			
		||||
 | 
			
		||||
      clutter_actor_move_anchor_point_from_gravity (actor,
 | 
			
		||||
                                                    CLUTTER_GRAVITY_CENTER);
 | 
			
		||||
 | 
			
		||||
      clutter_actor_set_scale (actor, 0.0, 0.0);
 | 
			
		||||
      clutter_actor_set_pivot_point (actor, 0.5, 0.5);
 | 
			
		||||
      clutter_actor_set_opacity (actor, 0);
 | 
			
		||||
      clutter_actor_set_scale (actor, 0.5, 0.5);
 | 
			
		||||
      clutter_actor_show (actor);
 | 
			
		||||
 | 
			
		||||
      animation = clutter_actor_animate (actor,
 | 
			
		||||
                                         CLUTTER_EASE_IN_SINE,
 | 
			
		||||
                                         CLUTTER_EASE_OUT_QUAD,
 | 
			
		||||
                                         MAP_TIMEOUT,
 | 
			
		||||
                                         "opacity", 255,
 | 
			
		||||
                                         "scale-x", 1.0,
 | 
			
		||||
                                         "scale-y", 1.0,
 | 
			
		||||
                                         NULL);
 | 
			
		||||
@@ -785,6 +789,82 @@ destroy (MetaPlugin *plugin, MetaWindowActor *window_actor)
 | 
			
		||||
    meta_plugin_destroy_completed (plugin, window_actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Tile preview private data accessor
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
free_screen_tile_preview (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  ScreenTilePreview *preview = data;
 | 
			
		||||
 | 
			
		||||
  if (G_LIKELY (preview != NULL)) {
 | 
			
		||||
    clutter_actor_destroy (preview->actor);
 | 
			
		||||
    g_slice_free (ScreenTilePreview, preview);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ScreenTilePreview *
 | 
			
		||||
get_screen_tile_preview (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  ScreenTilePreview *preview = g_object_get_qdata (G_OBJECT (screen), screen_tile_preview_data_quark);
 | 
			
		||||
 | 
			
		||||
  if (G_UNLIKELY (screen_tile_preview_data_quark == 0))
 | 
			
		||||
    screen_tile_preview_data_quark = g_quark_from_static_string (SCREEN_TILE_PREVIEW_DATA_KEY);
 | 
			
		||||
 | 
			
		||||
  if (G_UNLIKELY (!preview))
 | 
			
		||||
    {
 | 
			
		||||
      preview = g_slice_new0 (ScreenTilePreview);
 | 
			
		||||
 | 
			
		||||
      preview->actor = clutter_actor_new ();
 | 
			
		||||
      clutter_actor_set_background_color (preview->actor, CLUTTER_COLOR_Blue);
 | 
			
		||||
      clutter_actor_set_opacity (preview->actor, 100);
 | 
			
		||||
 | 
			
		||||
      clutter_actor_add_child (meta_get_window_group_for_screen (screen), preview->actor);
 | 
			
		||||
      g_object_set_qdata_full (G_OBJECT (screen),
 | 
			
		||||
                               screen_tile_preview_data_quark, preview,
 | 
			
		||||
                               free_screen_tile_preview);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return preview;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
show_tile_preview (MetaPlugin    *plugin,
 | 
			
		||||
                   MetaWindow    *window,
 | 
			
		||||
                   MetaRectangle *tile_rect,
 | 
			
		||||
                   int            tile_monitor_number)
 | 
			
		||||
{
 | 
			
		||||
  MetaScreen *screen = meta_plugin_get_screen (plugin);
 | 
			
		||||
  ScreenTilePreview *preview = get_screen_tile_preview (screen);
 | 
			
		||||
  ClutterActor *window_actor;
 | 
			
		||||
 | 
			
		||||
  if (CLUTTER_ACTOR_IS_VISIBLE (preview->actor)
 | 
			
		||||
      && preview->tile_rect.x == tile_rect->x
 | 
			
		||||
      && preview->tile_rect.y == tile_rect->y
 | 
			
		||||
      && preview->tile_rect.width == tile_rect->width
 | 
			
		||||
      && preview->tile_rect.height == tile_rect->height)
 | 
			
		||||
    return; /* nothing to do */
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_position (preview->actor, tile_rect->x, tile_rect->y);
 | 
			
		||||
  clutter_actor_set_size (preview->actor, tile_rect->width, tile_rect->height);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_show (preview->actor);
 | 
			
		||||
 | 
			
		||||
  window_actor = CLUTTER_ACTOR (meta_window_get_compositor_private (window));
 | 
			
		||||
  clutter_actor_lower (preview->actor, window_actor);
 | 
			
		||||
 | 
			
		||||
  preview->tile_rect = *tile_rect;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
hide_tile_preview (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaScreen *screen = meta_plugin_get_screen (plugin);
 | 
			
		||||
  ScreenTilePreview *preview = get_screen_tile_preview (screen);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_hide (preview->actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
kill_switch_workspace (MetaPlugin     *plugin)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "region-utils.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __META_REGION_UTILS_H__
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* The standard cycle-windows keybinding should be the key above the
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -53,6 +51,7 @@
 | 
			
		||||
#include "bell.h"
 | 
			
		||||
#include "screen-private.h"
 | 
			
		||||
#include "window-private.h"
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
#include <meta/prefs.h>
 | 
			
		||||
#include <meta/compositor.h>
 | 
			
		||||
#ifdef HAVE_LIBCANBERRA
 | 
			
		||||
 
 | 
			
		||||
@@ -14,9 +14,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_BOXES_PRIVATE_H
 | 
			
		||||
 
 | 
			
		||||
@@ -25,9 +25,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "boxes-private.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -18,9 +18,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
@@ -118,8 +116,6 @@ typedef struct
 | 
			
		||||
{
 | 
			
		||||
  MetaRectangle        orig;
 | 
			
		||||
  MetaRectangle        current;
 | 
			
		||||
  MetaFrameBorders    *borders;
 | 
			
		||||
  gboolean             must_free_borders;
 | 
			
		||||
  ActionType           action_type;
 | 
			
		||||
  gboolean             is_user_action;
 | 
			
		||||
 | 
			
		||||
@@ -195,7 +191,6 @@ static gboolean constrain_partially_onscreen (MetaWindow         *window,
 | 
			
		||||
 | 
			
		||||
static void setup_constraint_info        (ConstraintInfo      *info,
 | 
			
		||||
                                          MetaWindow          *window,
 | 
			
		||||
                                          MetaFrameBorders    *orig_borders,
 | 
			
		||||
                                          MetaMoveResizeFlags  flags,
 | 
			
		||||
                                          int                  resize_gravity,
 | 
			
		||||
                                          const MetaRectangle *orig,
 | 
			
		||||
@@ -204,13 +199,12 @@ static void place_window_if_needed       (MetaWindow     *window,
 | 
			
		||||
                                          ConstraintInfo *info);
 | 
			
		||||
static void update_onscreen_requirements (MetaWindow     *window,
 | 
			
		||||
                                          ConstraintInfo *info);
 | 
			
		||||
static void extend_by_frame              (MetaRectangle           *rect,
 | 
			
		||||
                                          const MetaFrameBorders  *borders);
 | 
			
		||||
static void unextend_by_frame            (MetaRectangle           *rect,
 | 
			
		||||
                                          const MetaFrameBorders  *borders);
 | 
			
		||||
static inline void get_size_limits       (const MetaWindow        *window,
 | 
			
		||||
                                          const MetaFrameBorders  *borders,
 | 
			
		||||
                                          gboolean include_frame,
 | 
			
		||||
static void extend_by_frame              (MetaWindow     *window,
 | 
			
		||||
                                          MetaRectangle  *rect);
 | 
			
		||||
static void unextend_by_frame            (MetaWindow     *window,
 | 
			
		||||
                                          MetaRectangle  *rect);
 | 
			
		||||
static inline void get_size_limits       (MetaWindow    *window,
 | 
			
		||||
                                          gboolean       include_frame,
 | 
			
		||||
                                          MetaRectangle *min_size,
 | 
			
		||||
                                          MetaRectangle *max_size);
 | 
			
		||||
 | 
			
		||||
@@ -280,7 +274,6 @@ do_all_constraints (MetaWindow         *window,
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_constrain (MetaWindow          *window,
 | 
			
		||||
                       MetaFrameBorders    *orig_borders,
 | 
			
		||||
                       MetaMoveResizeFlags  flags,
 | 
			
		||||
                       int                  resize_gravity,
 | 
			
		||||
                       const MetaRectangle *orig,
 | 
			
		||||
@@ -303,7 +296,6 @@ meta_window_constrain (MetaWindow          *window,
 | 
			
		||||
 | 
			
		||||
  setup_constraint_info (&info,
 | 
			
		||||
                         window, 
 | 
			
		||||
                         orig_borders,
 | 
			
		||||
                         flags,
 | 
			
		||||
                         resize_gravity,
 | 
			
		||||
                         orig,
 | 
			
		||||
@@ -333,19 +325,11 @@ meta_window_constrain (MetaWindow          *window,
 | 
			
		||||
   * if this was a user move or user move-and-resize operation.
 | 
			
		||||
   */
 | 
			
		||||
  update_onscreen_requirements (window, &info);
 | 
			
		||||
 | 
			
		||||
  /* Ew, what an ugly way to do things.  Destructors (in a real OOP language,
 | 
			
		||||
   * not gobject-style--gobject would be more pain than it's worth) or
 | 
			
		||||
   * smart pointers would be so much nicer here.  *shrug*
 | 
			
		||||
   */
 | 
			
		||||
  if (info.must_free_borders)
 | 
			
		||||
    g_free (info.borders);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
setup_constraint_info (ConstraintInfo      *info,
 | 
			
		||||
                       MetaWindow          *window,
 | 
			
		||||
                       MetaFrameBorders    *orig_borders,
 | 
			
		||||
                       MetaMoveResizeFlags  flags,
 | 
			
		||||
                       int                  resize_gravity,
 | 
			
		||||
                       const MetaRectangle *orig,
 | 
			
		||||
@@ -357,18 +341,6 @@ setup_constraint_info (ConstraintInfo      *info,
 | 
			
		||||
  info->orig    = *orig;
 | 
			
		||||
  info->current = *new;
 | 
			
		||||
 | 
			
		||||
  /* Create a fake frame geometry if none really exists */
 | 
			
		||||
  if (orig_borders && !window->fullscreen)
 | 
			
		||||
    {
 | 
			
		||||
      info->borders = orig_borders;
 | 
			
		||||
      info->must_free_borders = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      info->borders = g_new0 (MetaFrameBorders, 1);
 | 
			
		||||
      info->must_free_borders = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION)
 | 
			
		||||
    info->action_type = ACTION_MOVE_AND_RESIZE;
 | 
			
		||||
  else if (flags & META_IS_RESIZE_ACTION)
 | 
			
		||||
@@ -454,7 +426,7 @@ setup_constraint_info (ConstraintInfo      *info,
 | 
			
		||||
   */
 | 
			
		||||
  if (meta_prefs_get_force_fullscreen() &&
 | 
			
		||||
      !window->hide_titlebar_when_maximized &&
 | 
			
		||||
      window->decorated &&
 | 
			
		||||
      (window->decorated || !meta_window_is_client_decorated (window)) &&
 | 
			
		||||
      meta_rectangle_equal (new, &monitor_info->rect) &&
 | 
			
		||||
      window->has_fullscreen_func &&
 | 
			
		||||
      !window->fullscreen)
 | 
			
		||||
@@ -519,11 +491,17 @@ place_window_if_needed(MetaWindow     *window,
 | 
			
		||||
      !window->minimized &&
 | 
			
		||||
      !window->fullscreen)
 | 
			
		||||
    {
 | 
			
		||||
      MetaRectangle placed_rect = info->orig;
 | 
			
		||||
      MetaRectangle orig_rect;
 | 
			
		||||
      MetaRectangle placed_rect;
 | 
			
		||||
      MetaWorkspace *cur_workspace;
 | 
			
		||||
      const MetaMonitorInfo *monitor_info;
 | 
			
		||||
 | 
			
		||||
      meta_window_place (window, info->borders, info->orig.x, info->orig.y,
 | 
			
		||||
      meta_window_get_frame_rect (window, &placed_rect);
 | 
			
		||||
 | 
			
		||||
      orig_rect = info->orig;
 | 
			
		||||
      extend_by_frame (window, &orig_rect);
 | 
			
		||||
 | 
			
		||||
      meta_window_place (window, orig_rect.x, orig_rect.y,
 | 
			
		||||
                         &placed_rect.x, &placed_rect.y);
 | 
			
		||||
      did_placement = TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -541,6 +519,7 @@ place_window_if_needed(MetaWindow     *window,
 | 
			
		||||
        meta_workspace_get_onmonitor_region (cur_workspace, 
 | 
			
		||||
                                             monitor_info->number);
 | 
			
		||||
 | 
			
		||||
      meta_window_frame_rect_to_client_rect (window, &placed_rect, &placed_rect);
 | 
			
		||||
 | 
			
		||||
      info->current.x = placed_rect.x;
 | 
			
		||||
      info->current.y = placed_rect.y;
 | 
			
		||||
@@ -586,10 +565,6 @@ place_window_if_needed(MetaWindow     *window,
 | 
			
		||||
                (window->maximize_vertically_after_placement ?
 | 
			
		||||
                 META_MAXIMIZE_VERTICAL : 0), &info->current);
 | 
			
		||||
 | 
			
		||||
          /* maximization may have changed frame geometry */
 | 
			
		||||
          if (!window->fullscreen)
 | 
			
		||||
            meta_frame_calc_borders (window->frame, info->borders);
 | 
			
		||||
 | 
			
		||||
          if (window->fullscreen_after_placement)
 | 
			
		||||
            {
 | 
			
		||||
              window->saved_rect = info->current;
 | 
			
		||||
@@ -649,7 +624,7 @@ update_onscreen_requirements (MetaWindow     *window,
 | 
			
		||||
  /* The require onscreen/on-single-monitor and titlebar_visible
 | 
			
		||||
   * stuff is relative to the outer window, not the inner
 | 
			
		||||
   */
 | 
			
		||||
  extend_by_frame (&info->current, info->borders);
 | 
			
		||||
  extend_by_frame (window, &info->current);
 | 
			
		||||
 | 
			
		||||
  /* Update whether we want future constraint runs to require the
 | 
			
		||||
   * window to be on fully onscreen.
 | 
			
		||||
@@ -682,10 +657,13 @@ update_onscreen_requirements (MetaWindow     *window,
 | 
			
		||||
   */
 | 
			
		||||
  if (window->frame && window->decorated)
 | 
			
		||||
    {
 | 
			
		||||
      MetaFrameBorders borders;
 | 
			
		||||
      MetaRectangle titlebar_rect;
 | 
			
		||||
 | 
			
		||||
      meta_frame_calc_borders (window->frame, &borders);
 | 
			
		||||
 | 
			
		||||
      titlebar_rect = info->current;
 | 
			
		||||
      titlebar_rect.height = info->borders->visible.top;
 | 
			
		||||
      titlebar_rect.height = borders.visible.top;
 | 
			
		||||
      old = window->require_titlebar_visible;
 | 
			
		||||
      window->require_titlebar_visible =
 | 
			
		||||
        meta_rectangle_overlaps_with_region (info->usable_screen_region,
 | 
			
		||||
@@ -698,39 +676,33 @@ update_onscreen_requirements (MetaWindow     *window,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Don't forget to restore the position of the window */
 | 
			
		||||
  unextend_by_frame (&info->current, info->borders);
 | 
			
		||||
  unextend_by_frame (window, &info->current);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
extend_by_frame (MetaRectangle           *rect,
 | 
			
		||||
                 const MetaFrameBorders *borders)
 | 
			
		||||
extend_by_frame (MetaWindow    *window,
 | 
			
		||||
                 MetaRectangle *rect)
 | 
			
		||||
{
 | 
			
		||||
  rect->x -= borders->visible.left;
 | 
			
		||||
  rect->y -= borders->visible.top;
 | 
			
		||||
  rect->width  += borders->visible.left + borders->visible.right;
 | 
			
		||||
  rect->height += borders->visible.top + borders->visible.bottom;
 | 
			
		||||
  meta_window_client_rect_to_frame_rect (window, rect, rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unextend_by_frame (MetaRectangle           *rect,
 | 
			
		||||
                   const MetaFrameBorders *borders)
 | 
			
		||||
unextend_by_frame (MetaWindow    *window,
 | 
			
		||||
                   MetaRectangle *rect)
 | 
			
		||||
{
 | 
			
		||||
  rect->x += borders->visible.left;
 | 
			
		||||
  rect->y += borders->visible.top;
 | 
			
		||||
  rect->width  -= borders->visible.left + borders->visible.right;
 | 
			
		||||
  rect->height -= borders->visible.top + borders->visible.bottom;
 | 
			
		||||
  meta_window_frame_rect_to_client_rect (window, rect, rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
get_size_limits (const MetaWindow        *window,
 | 
			
		||||
                 const MetaFrameBorders *borders,
 | 
			
		||||
                 gboolean                 include_frame,
 | 
			
		||||
get_size_limits (MetaWindow    *window,
 | 
			
		||||
                 gboolean       include_frame,
 | 
			
		||||
                 MetaRectangle *min_size,
 | 
			
		||||
                 MetaRectangle *max_size)
 | 
			
		||||
{
 | 
			
		||||
  /* We pack the results into MetaRectangle structs just for convienience; we
 | 
			
		||||
   * don't actually use the position of those rects.
 | 
			
		||||
   */
 | 
			
		||||
  min_size->x = min_size->y = max_size->x = max_size->y = 0;
 | 
			
		||||
  min_size->width  = window->size_hints.min_width;
 | 
			
		||||
  min_size->height = window->size_hints.min_height;
 | 
			
		||||
  max_size->width  = window->size_hints.max_width;
 | 
			
		||||
@@ -738,22 +710,8 @@ get_size_limits (const MetaWindow        *window,
 | 
			
		||||
 | 
			
		||||
  if (include_frame)
 | 
			
		||||
    {
 | 
			
		||||
      int fw = borders->visible.left + borders->visible.right;
 | 
			
		||||
      int fh = borders->visible.top + borders->visible.bottom;
 | 
			
		||||
 | 
			
		||||
      min_size->width  += fw;
 | 
			
		||||
      min_size->height += fh;
 | 
			
		||||
      /* Do check to avoid overflow (e.g. max_size->width & max_size->height
 | 
			
		||||
       * may be set to G_MAXINT by meta_set_normal_hints()).
 | 
			
		||||
       */
 | 
			
		||||
      if (max_size->width < (G_MAXINT - fw))
 | 
			
		||||
        max_size->width += fw;
 | 
			
		||||
      else
 | 
			
		||||
        max_size->width = G_MAXINT;
 | 
			
		||||
      if (max_size->height < (G_MAXINT - fh))
 | 
			
		||||
        max_size->height += fh;
 | 
			
		||||
      else
 | 
			
		||||
        max_size->height = G_MAXINT;
 | 
			
		||||
      meta_window_client_rect_to_frame_rect (window, min_size, min_size);
 | 
			
		||||
      meta_window_client_rect_to_frame_rect (window, max_size, max_size);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -765,18 +723,28 @@ constrain_modal_dialog (MetaWindow         *window,
 | 
			
		||||
{
 | 
			
		||||
  int x, y;
 | 
			
		||||
  MetaWindow *parent = meta_window_get_transient_for (window);
 | 
			
		||||
  MetaRectangle child_rect, parent_rect;
 | 
			
		||||
  gboolean constraint_already_satisfied;
 | 
			
		||||
 | 
			
		||||
  if (!meta_window_is_attached_dialog (window))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  x = parent->rect.x + (parent->rect.width / 2  - info->current.width / 2);
 | 
			
		||||
  y = parent->rect.y + (parent->rect.height / 2 - info->current.height / 2);
 | 
			
		||||
  if (parent->frame)
 | 
			
		||||
    {
 | 
			
		||||
      x += parent->frame->rect.x;
 | 
			
		||||
      y += parent->frame->rect.y;
 | 
			
		||||
    }
 | 
			
		||||
  /* We want to center the dialog on the parent, including the decorations
 | 
			
		||||
     for both of them. info->current is in client X window coordinates, so we need
 | 
			
		||||
     to convert them to frame coordinates, apply the centering and then
 | 
			
		||||
     convert back to client.
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  child_rect = info->current;
 | 
			
		||||
  extend_by_frame (window, &child_rect);
 | 
			
		||||
 | 
			
		||||
  meta_window_get_frame_rect (parent, &parent_rect);
 | 
			
		||||
 | 
			
		||||
  child_rect.x = parent_rect.x + (parent_rect.width / 2  - child_rect.width / 2);
 | 
			
		||||
  child_rect.y = parent_rect.y + (parent_rect.height / 2 - child_rect.height / 2);
 | 
			
		||||
  unextend_by_frame (window, &child_rect);
 | 
			
		||||
  x = child_rect.x;
 | 
			
		||||
  y = child_rect.y;
 | 
			
		||||
 | 
			
		||||
  constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
 | 
			
		||||
 | 
			
		||||
@@ -841,19 +809,19 @@ constrain_maximization (MetaWindow         *window,
 | 
			
		||||
      active_workspace_struts = window->screen->active_workspace->all_struts;
 | 
			
		||||
 | 
			
		||||
      target_size = info->current;
 | 
			
		||||
      extend_by_frame (&target_size, info->borders);
 | 
			
		||||
      extend_by_frame (window, &target_size);
 | 
			
		||||
      meta_rectangle_expand_to_avoiding_struts (&target_size,
 | 
			
		||||
                                                &info->entire_monitor,
 | 
			
		||||
                                                direction,
 | 
			
		||||
                                                active_workspace_struts);
 | 
			
		||||
   }
 | 
			
		||||
  /* Now make target_size = maximized size of client window */
 | 
			
		||||
  unextend_by_frame (&target_size, info->borders);
 | 
			
		||||
  unextend_by_frame (window, &target_size);
 | 
			
		||||
 | 
			
		||||
  /* Check min size constraints; max size constraints are ignored for maximized
 | 
			
		||||
   * windows, as per bug 327543.
 | 
			
		||||
   */
 | 
			
		||||
  get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
 | 
			
		||||
  get_size_limits (window, FALSE, &min_size, &max_size);
 | 
			
		||||
  hminbad = target_size.width < min_size.width && window->maximized_horizontally;
 | 
			
		||||
  vminbad = target_size.height < min_size.height && window->maximized_vertically;
 | 
			
		||||
  if (hminbad || vminbad)
 | 
			
		||||
@@ -907,12 +875,12 @@ constrain_tiling (MetaWindow         *window,
 | 
			
		||||
   * use an external function for the actual calculation
 | 
			
		||||
   */
 | 
			
		||||
  meta_window_get_current_tile_area (window, &target_size);
 | 
			
		||||
  unextend_by_frame (&target_size, info->borders);
 | 
			
		||||
  unextend_by_frame (window, &target_size);
 | 
			
		||||
 | 
			
		||||
  /* Check min size constraints; max size constraints are ignored as for
 | 
			
		||||
   * maximized windows.
 | 
			
		||||
   */
 | 
			
		||||
  get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
 | 
			
		||||
  get_size_limits (window, FALSE, &min_size, &max_size);
 | 
			
		||||
  hminbad = target_size.width < min_size.width;
 | 
			
		||||
  vminbad = target_size.height < min_size.height;
 | 
			
		||||
  if (hminbad || vminbad)
 | 
			
		||||
@@ -955,7 +923,7 @@ constrain_fullscreen (MetaWindow         *window,
 | 
			
		||||
 | 
			
		||||
  monitor = info->entire_monitor;
 | 
			
		||||
 | 
			
		||||
  get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
 | 
			
		||||
  get_size_limits (window, FALSE, &min_size, &max_size);
 | 
			
		||||
  too_big =   !meta_rectangle_could_fit_rect (&monitor, &min_size);
 | 
			
		||||
  too_small = !meta_rectangle_could_fit_rect (&max_size, &monitor);
 | 
			
		||||
  if (too_big || too_small)
 | 
			
		||||
@@ -1064,7 +1032,7 @@ constrain_size_limits (MetaWindow         *window,
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  /* Determine whether constraint is already satisfied; exit if it is */
 | 
			
		||||
  get_size_limits (window, info->borders, FALSE, &min_size, &max_size);
 | 
			
		||||
  get_size_limits (window, FALSE, &min_size, &max_size);
 | 
			
		||||
  /* We ignore max-size limits for maximized windows; see #327543 */
 | 
			
		||||
  if (window->maximized_horizontally)
 | 
			
		||||
    max_size.width = MAX (max_size.width, info->current.width);
 | 
			
		||||
@@ -1256,8 +1224,8 @@ do_screen_and_monitor_relative_constraints (
 | 
			
		||||
 | 
			
		||||
  /* Determine whether constraint applies; exit if it doesn't */
 | 
			
		||||
  how_far_it_can_be_smushed = info->current;
 | 
			
		||||
  get_size_limits (window, info->borders, TRUE, &min_size, &max_size);
 | 
			
		||||
  extend_by_frame (&info->current, info->borders);
 | 
			
		||||
  get_size_limits (window, TRUE, &min_size, &max_size);
 | 
			
		||||
  extend_by_frame (window, &info->current);
 | 
			
		||||
 | 
			
		||||
  if (info->action_type != ACTION_MOVE)
 | 
			
		||||
    {
 | 
			
		||||
@@ -1277,7 +1245,7 @@ do_screen_and_monitor_relative_constraints (
 | 
			
		||||
                                        &info->current);
 | 
			
		||||
  if (exit_early || constraint_satisfied || check_only)
 | 
			
		||||
    {
 | 
			
		||||
      unextend_by_frame (&info->current, info->borders);
 | 
			
		||||
      unextend_by_frame (window, &info->current);
 | 
			
		||||
      return constraint_satisfied;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1301,7 +1269,7 @@ do_screen_and_monitor_relative_constraints (
 | 
			
		||||
                                      info->fixed_directions,
 | 
			
		||||
                                      &info->current);
 | 
			
		||||
 | 
			
		||||
  unextend_by_frame (&info->current, info->borders);
 | 
			
		||||
  unextend_by_frame (window, &info->current);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1390,7 +1358,6 @@ constrain_titlebar_visible (MetaWindow         *window,
 | 
			
		||||
      window->type == META_WINDOW_DOCK    ||
 | 
			
		||||
      window->fullscreen                  ||
 | 
			
		||||
      !window->require_titlebar_visible   ||
 | 
			
		||||
      !window->decorated                  ||
 | 
			
		||||
      unconstrained_user_action)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -1414,8 +1381,11 @@ constrain_titlebar_visible (MetaWindow         *window,
 | 
			
		||||
   */
 | 
			
		||||
  if (window->frame)
 | 
			
		||||
    {
 | 
			
		||||
      bottom_amount = info->current.height + info->borders->visible.bottom;
 | 
			
		||||
      vert_amount_onscreen = info->borders->visible.top;
 | 
			
		||||
      MetaFrameBorders borders;
 | 
			
		||||
      meta_frame_calc_borders (window->frame, &borders);
 | 
			
		||||
 | 
			
		||||
      bottom_amount = info->current.height + borders.visible.bottom;
 | 
			
		||||
      vert_amount_onscreen = borders.visible.top;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    bottom_amount = vert_amount_offscreen;
 | 
			
		||||
@@ -1489,8 +1459,11 @@ constrain_partially_onscreen (MetaWindow         *window,
 | 
			
		||||
   */
 | 
			
		||||
  if (window->frame)
 | 
			
		||||
    {
 | 
			
		||||
      bottom_amount = info->current.height + info->borders->visible.bottom;
 | 
			
		||||
      vert_amount_onscreen = info->borders->visible.top;
 | 
			
		||||
      MetaFrameBorders borders;
 | 
			
		||||
      meta_frame_calc_borders (window->frame, &borders);
 | 
			
		||||
 | 
			
		||||
      bottom_amount = info->current.height + borders.visible.bottom;
 | 
			
		||||
      vert_amount_onscreen = borders.visible.top;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    bottom_amount = vert_amount_offscreen;
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_CONSTRAINTS_H
 | 
			
		||||
@@ -35,11 +33,12 @@ typedef enum
 | 
			
		||||
  META_DO_GRAVITY_ADJUST    = 1 << 1,
 | 
			
		||||
  META_IS_USER_ACTION       = 1 << 2,
 | 
			
		||||
  META_IS_MOVE_ACTION       = 1 << 3,
 | 
			
		||||
  META_IS_RESIZE_ACTION     = 1 << 4
 | 
			
		||||
  META_IS_RESIZE_ACTION     = 1 << 4,
 | 
			
		||||
  META_FORCE_STATIC_GRAVITY = 1 << 5,
 | 
			
		||||
  META_IS_INITIAL_RESIZE    = 1 << 6
 | 
			
		||||
} MetaMoveResizeFlags;
 | 
			
		||||
 | 
			
		||||
void meta_window_constrain (MetaWindow          *window,
 | 
			
		||||
                            MetaFrameBorders    *orig_borders,
 | 
			
		||||
                            MetaMoveResizeFlags  flags,
 | 
			
		||||
                            int                  resize_gravity,
 | 
			
		||||
                            const MetaRectangle *orig,
 | 
			
		||||
 
 | 
			
		||||
@@ -18,9 +18,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
@@ -29,6 +27,7 @@
 | 
			
		||||
#include "workspace-private.h"
 | 
			
		||||
#include <meta/prefs.h>
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
 | 
			
		||||
/* Looks up the MetaWindow representing the frame of the given X window.
 | 
			
		||||
 * Used as a helper function by a bunch of the functions below.
 | 
			
		||||
@@ -171,6 +170,7 @@ meta_core_queue_frame_resize (Display *xdisplay,
 | 
			
		||||
  MetaWindow *window = get_window (xdisplay, frame_xwindow);
 | 
			
		||||
 | 
			
		||||
  meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
 | 
			
		||||
  meta_window_frame_size_changed (window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -279,8 +279,7 @@ meta_core_lower_beneath_grab_window (Display *xdisplay,
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  changes.stack_mode = Below;
 | 
			
		||||
  changes.sibling = grab_window->frame ? grab_window->frame->xwindow
 | 
			
		||||
                                       : grab_window->xwindow;
 | 
			
		||||
  changes.sibling = meta_window_get_toplevel_xwindow (grab_window);
 | 
			
		||||
 | 
			
		||||
  meta_stack_tracker_record_lower_below (screen->stack_tracker,
 | 
			
		||||
                                         xwindow,
 | 
			
		||||
@@ -323,8 +322,7 @@ meta_core_maximize (Display *xdisplay,
 | 
			
		||||
  if (meta_prefs_get_raise_on_click ())
 | 
			
		||||
    meta_window_raise (window);
 | 
			
		||||
 | 
			
		||||
  meta_window_maximize (window, 
 | 
			
		||||
                        META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
 | 
			
		||||
  meta_window_maximize (window, META_MAXIMIZE_BOTH);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -337,11 +335,9 @@ meta_core_toggle_maximize_vertically (Display *xdisplay,
 | 
			
		||||
    meta_window_raise (window);
 | 
			
		||||
 | 
			
		||||
  if (META_WINDOW_MAXIMIZED_VERTICALLY (window))
 | 
			
		||||
    meta_window_unmaximize (window, 
 | 
			
		||||
                            META_MAXIMIZE_VERTICAL);
 | 
			
		||||
    meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL);
 | 
			
		||||
  else
 | 
			
		||||
    meta_window_maximize (window,
 | 
			
		||||
    			    META_MAXIMIZE_VERTICAL);
 | 
			
		||||
    meta_window_maximize (window, META_MAXIMIZE_VERTICAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -354,11 +350,9 @@ meta_core_toggle_maximize_horizontally (Display *xdisplay,
 | 
			
		||||
    meta_window_raise (window);
 | 
			
		||||
 | 
			
		||||
  if (META_WINDOW_MAXIMIZED_HORIZONTALLY (window))
 | 
			
		||||
    meta_window_unmaximize (window, 
 | 
			
		||||
                            META_MAXIMIZE_HORIZONTAL);
 | 
			
		||||
    meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL);
 | 
			
		||||
  else
 | 
			
		||||
    meta_window_maximize (window,
 | 
			
		||||
    			    META_MAXIMIZE_HORIZONTAL);
 | 
			
		||||
    meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -371,11 +365,9 @@ meta_core_toggle_maximize (Display *xdisplay,
 | 
			
		||||
    meta_window_raise (window);
 | 
			
		||||
 | 
			
		||||
  if (META_WINDOW_MAXIMIZED (window))
 | 
			
		||||
    meta_window_unmaximize (window, 
 | 
			
		||||
                            META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
 | 
			
		||||
    meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
 | 
			
		||||
  else
 | 
			
		||||
    meta_window_maximize (window,
 | 
			
		||||
                          META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
 | 
			
		||||
    meta_window_maximize (window, META_MAXIMIZE_BOTH);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -387,8 +379,7 @@ meta_core_unmaximize (Display *xdisplay,
 | 
			
		||||
  if (meta_prefs_get_raise_on_click ())
 | 
			
		||||
    meta_window_raise (window);
 | 
			
		||||
 | 
			
		||||
  meta_window_unmaximize (window,
 | 
			
		||||
                          META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
 | 
			
		||||
  meta_window_unmaximize (window, META_MAXIMIZE_BOTH);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_CORE_H
 | 
			
		||||
 
 | 
			
		||||
@@ -17,15 +17,13 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define _XOPEN_SOURCE /* for kill() */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
#include "window-private.h"
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
#include <meta/workspace.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -19,9 +19,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_DISPLAY_PRIVATE_H
 | 
			
		||||
@@ -138,6 +136,14 @@ struct _MetaDisplay
 | 
			
		||||
   */
 | 
			
		||||
  guint allow_terminal_deactivation : 1;
 | 
			
		||||
 | 
			
		||||
  /* If true, server->focus_serial refers to us changing the focus; in
 | 
			
		||||
   * this case, we can ignore focus events that have exactly focus_serial,
 | 
			
		||||
   * since we take care to make another request immediately afterwards.
 | 
			
		||||
   * But if focus is being changed by another client, we have to accept
 | 
			
		||||
   * multiple events with the same serial.
 | 
			
		||||
   */
 | 
			
		||||
  guint focused_by_us : 1;
 | 
			
		||||
 | 
			
		||||
  guint static_gravity_works : 1;
 | 
			
		||||
  
 | 
			
		||||
  /*< private-ish >*/
 | 
			
		||||
@@ -224,8 +230,8 @@ struct _MetaDisplay
 | 
			
		||||
  int	      grab_resize_timeout_id;
 | 
			
		||||
 | 
			
		||||
  /* Keybindings stuff */
 | 
			
		||||
  MetaKeyBinding *key_bindings;
 | 
			
		||||
  int             n_key_bindings;
 | 
			
		||||
  GHashTable     *key_bindings;
 | 
			
		||||
  GHashTable     *key_bindings_index;
 | 
			
		||||
  int             min_keycode;
 | 
			
		||||
  int             max_keycode;
 | 
			
		||||
  KeySym *keymap;
 | 
			
		||||
@@ -477,4 +483,11 @@ void meta_display_set_input_focus_xwindow (MetaDisplay *display,
 | 
			
		||||
                                           Window       window,
 | 
			
		||||
                                           guint32      timestamp);
 | 
			
		||||
 | 
			
		||||
gboolean meta_display_show_restart_message (MetaDisplay *display,
 | 
			
		||||
                                            const char  *message);
 | 
			
		||||
gboolean meta_display_request_restart      (MetaDisplay *display);
 | 
			
		||||
 | 
			
		||||
void meta_restart_init (void);
 | 
			
		||||
void meta_restart_finish (void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -34,7 +32,7 @@
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
#include <meta/main.h>
 | 
			
		||||
#include "screen-private.h"
 | 
			
		||||
#include "window-private.h"
 | 
			
		||||
@@ -74,14 +72,6 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#define GRAB_OP_IS_WINDOW_SWITCH(g)                     \
 | 
			
		||||
        (g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL  ||  \
 | 
			
		||||
         g == META_GRAB_OP_KEYBOARD_TABBING_DOCK    ||  \
 | 
			
		||||
         g == META_GRAB_OP_KEYBOARD_TABBING_GROUP   ||  \
 | 
			
		||||
         g == META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL ||  \
 | 
			
		||||
         g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK   ||  \
 | 
			
		||||
         g == META_GRAB_OP_KEYBOARD_ESCAPING_GROUP)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * SECTION:pings
 | 
			
		||||
 *
 | 
			
		||||
@@ -117,12 +107,6 @@ typedef struct
 | 
			
		||||
  guint        ping_timeout_id;
 | 
			
		||||
} MetaPingData;
 | 
			
		||||
 | 
			
		||||
typedef struct 
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  Window xwindow;
 | 
			
		||||
} MetaAutoRaiseData;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
@@ -146,6 +130,8 @@ enum
 | 
			
		||||
  WINDOW_MARKED_URGENT,
 | 
			
		||||
  GRAB_OP_BEGIN,
 | 
			
		||||
  GRAB_OP_END,
 | 
			
		||||
  SHOW_RESTART_MESSAGE,
 | 
			
		||||
  RESTART,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -322,6 +308,59 @@ meta_display_class_init (MetaDisplayClass *klass)
 | 
			
		||||
                  META_TYPE_WINDOW,
 | 
			
		||||
                  META_TYPE_GRAB_OP);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * MetaDisplay::show-restart-message:
 | 
			
		||||
   * @display: the #MetaDisplay instance
 | 
			
		||||
   * @message: (allow-none): The message to display, or %NULL
 | 
			
		||||
   *  to clear a previous restart message.
 | 
			
		||||
   *
 | 
			
		||||
   * The ::show-restart-message signal will be emitted to indicate
 | 
			
		||||
   * that the compositor should show a message during restart. This is
 | 
			
		||||
   * emitted when meta_restart() is called, either by Mutter
 | 
			
		||||
   * internally or by the embedding compositor.  The message should be
 | 
			
		||||
   * immediately added to the Clutter stage in its final form -
 | 
			
		||||
   * ::restart will be emitted to exit the application and leave the
 | 
			
		||||
   * stage contents frozen as soon as the the stage is painted again.
 | 
			
		||||
   *
 | 
			
		||||
   * On case of failure to restart, this signal will be emitted again
 | 
			
		||||
   * with %NULL for @message.
 | 
			
		||||
   *
 | 
			
		||||
   * Returns: %TRUE means the message was added to the stage; %FALSE
 | 
			
		||||
   *   indicates that the compositor did not show the message.
 | 
			
		||||
   */
 | 
			
		||||
  display_signals[SHOW_RESTART_MESSAGE] =
 | 
			
		||||
    g_signal_new ("show-restart-message",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0,
 | 
			
		||||
                  g_signal_accumulator_true_handled,
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  G_TYPE_BOOLEAN, 1,
 | 
			
		||||
                  G_TYPE_STRING);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * MetaDisplay::restart:
 | 
			
		||||
   * @display: the #MetaDisplay instance
 | 
			
		||||
   *
 | 
			
		||||
   * The ::restart signal is emitted to indicate that compositor
 | 
			
		||||
   * should reexec the process. This is
 | 
			
		||||
   * emitted when meta_restart() is called, either by Mutter
 | 
			
		||||
   * internally or by the embedding compositor. See also
 | 
			
		||||
   * ::show-restart-message.
 | 
			
		||||
   *
 | 
			
		||||
   * Returns: %FALSE to indicate that the compositor could not
 | 
			
		||||
   *  be restarted. When the compositor is restarted, the signal
 | 
			
		||||
   *  should not return.
 | 
			
		||||
   */
 | 
			
		||||
  display_signals[RESTART] =
 | 
			
		||||
    g_signal_new ("restart",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0,
 | 
			
		||||
                  g_signal_accumulator_true_handled,
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  G_TYPE_BOOLEAN, 0);
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_FOCUS_WINDOW,
 | 
			
		||||
                                   g_param_spec_object ("focus-window",
 | 
			
		||||
@@ -924,8 +963,6 @@ meta_display_open (void)
 | 
			
		||||
 | 
			
		||||
  enable_compositor (the_display);
 | 
			
		||||
   
 | 
			
		||||
  meta_display_grab (the_display);
 | 
			
		||||
  
 | 
			
		||||
  /* Now manage all existing windows */
 | 
			
		||||
  tmp = the_display->screens;
 | 
			
		||||
  while (tmp != NULL)
 | 
			
		||||
@@ -977,8 +1014,6 @@ meta_display_open (void)
 | 
			
		||||
 | 
			
		||||
  meta_idle_monitor_init_dbus ();
 | 
			
		||||
 | 
			
		||||
  meta_display_ungrab (the_display);
 | 
			
		||||
 | 
			
		||||
  /* Done opening new display */
 | 
			
		||||
  the_display->display_opening = FALSE;
 | 
			
		||||
 | 
			
		||||
@@ -1223,7 +1258,18 @@ meta_display_screen_for_x_screen (MetaDisplay *display,
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Grab/ungrab routines taken from fvwm */
 | 
			
		||||
/* Grab/ungrab routines taken from fvwm.
 | 
			
		||||
 * Calling this function will cause X to ignore all other clients until
 | 
			
		||||
 * you ungrab. This may not be quite as bad as it sounds, yet there is
 | 
			
		||||
 * agreement that avoiding server grabs except when they are clearly needed
 | 
			
		||||
 * is a good thing.
 | 
			
		||||
 *
 | 
			
		||||
 * If you do use such grabs, please clearly explain the necessity for their
 | 
			
		||||
 * usage in a comment. Try to keep their scope extremely limited. In
 | 
			
		||||
 * particular, try to avoid emitting any signals or notifications while
 | 
			
		||||
 * a grab is active (if the signal receiver tries to block on an X request
 | 
			
		||||
 * from another client at this point, you will have a deadlock).
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_display_grab (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
@@ -1367,13 +1413,6 @@ grab_op_is_keyboard (MetaGrabOp op)
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_RESIZING_NE:
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_RESIZING_SW:
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_RESIZING_NW:
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
 | 
			
		||||
    case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
 | 
			
		||||
    case META_GRAB_OP_COMPOSITOR:
 | 
			
		||||
      return TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -1585,23 +1624,10 @@ reset_ignored_crossing_serials (MetaDisplay *display)
 | 
			
		||||
static gboolean 
 | 
			
		||||
window_raise_with_delay_callback (void *data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
  MetaAutoRaiseData *auto_raise;
 | 
			
		||||
  MetaWindow *window = data;
 | 
			
		||||
 | 
			
		||||
  auto_raise = data;
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_FOCUS, 
 | 
			
		||||
	      "In autoraise callback for window 0x%lx\n", 
 | 
			
		||||
	      auto_raise->xwindow);
 | 
			
		||||
 | 
			
		||||
  auto_raise->display->autoraise_timeout_id = 0;
 | 
			
		||||
  auto_raise->display->autoraise_window = NULL;
 | 
			
		||||
 | 
			
		||||
  window  = meta_display_lookup_x_window (auto_raise->display, 
 | 
			
		||||
					  auto_raise->xwindow);
 | 
			
		||||
  
 | 
			
		||||
  if (window == NULL) 
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  window->display->autoraise_timeout_id = 0;
 | 
			
		||||
  window->display->autoraise_window = NULL;
 | 
			
		||||
 | 
			
		||||
  /* If we aren't already on top, check whether the pointer is inside
 | 
			
		||||
   * the window and raise the window if so.
 | 
			
		||||
@@ -1610,6 +1636,7 @@ window_raise_with_delay_callback (void *data)
 | 
			
		||||
    {
 | 
			
		||||
      int x, y, root_x, root_y;
 | 
			
		||||
      Window root, child;
 | 
			
		||||
      MetaRectangle frame_rect;
 | 
			
		||||
      unsigned int mask;
 | 
			
		||||
      gboolean same_screen;
 | 
			
		||||
      gboolean point_in_window;
 | 
			
		||||
@@ -1621,9 +1648,8 @@ window_raise_with_delay_callback (void *data)
 | 
			
		||||
				   &root_x, &root_y, &x, &y, &mask);
 | 
			
		||||
      meta_error_trap_pop (window->display);
 | 
			
		||||
 | 
			
		||||
      point_in_window = 
 | 
			
		||||
        (window->frame && POINT_IN_RECT (root_x, root_y, window->frame->rect)) ||
 | 
			
		||||
        (window->frame == NULL && POINT_IN_RECT (root_x, root_y, window->rect));
 | 
			
		||||
      meta_window_get_frame_rect (window, &frame_rect);
 | 
			
		||||
      point_in_window = POINT_IN_RECT (root_x, root_y, frame_rect);
 | 
			
		||||
      if (same_screen && point_in_window)
 | 
			
		||||
	meta_window_raise (window);
 | 
			
		||||
      else
 | 
			
		||||
@@ -1743,17 +1769,11 @@ void
 | 
			
		||||
meta_display_queue_autoraise_callback (MetaDisplay *display,
 | 
			
		||||
                                       MetaWindow  *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaAutoRaiseData *auto_raise_data;
 | 
			
		||||
 | 
			
		||||
  meta_topic (META_DEBUG_FOCUS, 
 | 
			
		||||
              "Queuing an autoraise timeout for %s with delay %d\n", 
 | 
			
		||||
              window->desc, 
 | 
			
		||||
              meta_prefs_get_auto_raise_delay ());
 | 
			
		||||
  
 | 
			
		||||
  auto_raise_data = g_new (MetaAutoRaiseData, 1);
 | 
			
		||||
  auto_raise_data->display = window->display;
 | 
			
		||||
  auto_raise_data->xwindow = window->xwindow;
 | 
			
		||||
  
 | 
			
		||||
  if (display->autoraise_timeout_id != 0)
 | 
			
		||||
    g_source_remove (display->autoraise_timeout_id);
 | 
			
		||||
 | 
			
		||||
@@ -1761,8 +1781,7 @@ meta_display_queue_autoraise_callback (MetaDisplay *display,
 | 
			
		||||
    g_timeout_add_full (G_PRIORITY_DEFAULT,
 | 
			
		||||
                        meta_prefs_get_auto_raise_delay (),
 | 
			
		||||
                        window_raise_with_delay_callback,
 | 
			
		||||
                        auto_raise_data,
 | 
			
		||||
                        g_free);
 | 
			
		||||
                        window, NULL);
 | 
			
		||||
  display->autoraise_window = window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1851,6 +1870,9 @@ get_input_event (MetaDisplay *display,
 | 
			
		||||
 | 
			
		||||
      switch (input_event->evtype)
 | 
			
		||||
        {
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
        case XI_Motion:
 | 
			
		||||
        case XI_ButtonPress:
 | 
			
		||||
        case XI_ButtonRelease:
 | 
			
		||||
@@ -1891,9 +1913,11 @@ static void
 | 
			
		||||
update_focus_window (MetaDisplay *display,
 | 
			
		||||
                     MetaWindow  *window,
 | 
			
		||||
                     Window       xwindow,
 | 
			
		||||
                     gulong       serial)
 | 
			
		||||
                     gulong       serial,
 | 
			
		||||
                     gboolean     focused_by_us)
 | 
			
		||||
{
 | 
			
		||||
  display->focus_serial = serial;
 | 
			
		||||
  display->focused_by_us = focused_by_us;
 | 
			
		||||
 | 
			
		||||
  if (display->focus_xwindow == xwindow)
 | 
			
		||||
    return;
 | 
			
		||||
@@ -2004,7 +2028,8 @@ request_xserver_input_focus_change (MetaDisplay *display,
 | 
			
		||||
  update_focus_window (display,
 | 
			
		||||
                       meta_window,
 | 
			
		||||
                       xwindow,
 | 
			
		||||
                       serial);
 | 
			
		||||
                       serial,
 | 
			
		||||
                       TRUE);
 | 
			
		||||
 | 
			
		||||
  meta_error_trap_pop (display);
 | 
			
		||||
 | 
			
		||||
@@ -2118,15 +2143,36 @@ handle_window_focus_event (MetaDisplay  *display,
 | 
			
		||||
  else
 | 
			
		||||
    g_return_if_reached ();
 | 
			
		||||
 | 
			
		||||
  if (display->server_focus_serial > display->focus_serial)
 | 
			
		||||
  /* If display->focused_by_us, then the focus_serial will be used only
 | 
			
		||||
   * for a focus change we made and have already accounted for.
 | 
			
		||||
   * (See request_xserver_input_focus_change().) Otherwise, we can get
 | 
			
		||||
   * multiple focus events with the same serial.
 | 
			
		||||
   */
 | 
			
		||||
  if (display->server_focus_serial > display->focus_serial ||
 | 
			
		||||
      (!display->focused_by_us &&
 | 
			
		||||
       display->server_focus_serial == display->focus_serial))
 | 
			
		||||
    {
 | 
			
		||||
      update_focus_window (display,
 | 
			
		||||
                           focus_window,
 | 
			
		||||
                           focus_window ? focus_window->xwindow : None,
 | 
			
		||||
                           display->server_focus_serial);
 | 
			
		||||
                           display->server_focus_serial,
 | 
			
		||||
                           FALSE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
window_has_xwindow (MetaWindow *window,
 | 
			
		||||
                    Window      xwindow)
 | 
			
		||||
{
 | 
			
		||||
  if (window->xwindow == xwindow)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  if (window->frame && window->frame->xwindow == xwindow)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_callback:
 | 
			
		||||
 * @event: The event that just happened
 | 
			
		||||
@@ -2180,16 +2226,18 @@ event_callback (XEvent   *event,
 | 
			
		||||
  display->current_time = event_get_time (display, event);
 | 
			
		||||
  display->monitor_cache_invalidated = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (event->xany.serial > display->focus_serial &&
 | 
			
		||||
  if (display->focused_by_us &&
 | 
			
		||||
      event->xany.serial > display->focus_serial &&
 | 
			
		||||
      display->focus_window &&
 | 
			
		||||
      display->focus_window->xwindow != display->server_focus_window)
 | 
			
		||||
      !window_has_xwindow (display->focus_window, display->server_focus_window))
 | 
			
		||||
    {
 | 
			
		||||
      meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed\n",
 | 
			
		||||
                  display->focus_window->desc);
 | 
			
		||||
      update_focus_window (display,
 | 
			
		||||
                           meta_display_lookup_x_window (display, display->server_focus_window),
 | 
			
		||||
                           display->server_focus_window,
 | 
			
		||||
                           display->server_focus_serial);
 | 
			
		||||
                           display->server_focus_serial,
 | 
			
		||||
                           FALSE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  screen = meta_display_screen_for_root (display, event->xany.window);
 | 
			
		||||
@@ -2303,9 +2351,10 @@ event_callback (XEvent   *event,
 | 
			
		||||
    {
 | 
			
		||||
      XIDeviceEvent *device_event = (XIDeviceEvent *) input_event;
 | 
			
		||||
      XIEnterEvent *enter_event = (XIEnterEvent *) input_event;
 | 
			
		||||
      gint button = 0;
 | 
			
		||||
 | 
			
		||||
      if (window && !window->override_redirect &&
 | 
			
		||||
          ((input_event->type == XI_KeyPress) || (input_event->type == XI_ButtonPress)))
 | 
			
		||||
          ((input_event->evtype == XI_KeyPress) || (input_event->evtype == XI_ButtonPress)))
 | 
			
		||||
        {
 | 
			
		||||
          if (CurrentTime == display->current_time)
 | 
			
		||||
            {
 | 
			
		||||
@@ -2338,20 +2387,33 @@ event_callback (XEvent   *event,
 | 
			
		||||
          if (meta_display_process_key_event (display, window, (XIDeviceEvent *) input_event))
 | 
			
		||||
            filter_out_event = bypass_compositor = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
          /* Filter out non-pointer-emulating touches */
 | 
			
		||||
          if ((((XIDeviceEvent *) input_event)->flags & XITouchEmulatingPointer) == 0)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
          /* Fall through */
 | 
			
		||||
        case XI_ButtonPress:
 | 
			
		||||
          if (display->grab_op == META_GRAB_OP_COMPOSITOR)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
          display->overlay_key_only_pressed = FALSE;
 | 
			
		||||
 | 
			
		||||
          if (device_event->detail == 4 || device_event->detail == 5)
 | 
			
		||||
            /* Scrollwheel event, do nothing and deliver event to compositor below */
 | 
			
		||||
            break;
 | 
			
		||||
          if (input_event->evtype == XI_ButtonPress)
 | 
			
		||||
            {
 | 
			
		||||
              if (device_event->detail == 4 || device_event->detail == 5)
 | 
			
		||||
                /* Scrollwheel event, do nothing and deliver event to compositor below */
 | 
			
		||||
                break;
 | 
			
		||||
              else
 | 
			
		||||
                button = device_event->detail;
 | 
			
		||||
            }
 | 
			
		||||
          else if (input_event->evtype == XI_TouchBegin)
 | 
			
		||||
            button = 1;
 | 
			
		||||
 | 
			
		||||
          if ((window &&
 | 
			
		||||
               meta_grab_op_is_mouse (display->grab_op) &&
 | 
			
		||||
               (device_event->mods.effective & display->window_grab_modifiers) &&
 | 
			
		||||
               display->grab_button != device_event->detail &&
 | 
			
		||||
               display->grab_button != button &&
 | 
			
		||||
               display->grab_window == window) ||
 | 
			
		||||
              grab_op_is_keyboard (display->grab_op))
 | 
			
		||||
            {
 | 
			
		||||
@@ -2361,18 +2423,6 @@ event_callback (XEvent   *event,
 | 
			
		||||
                          (display->grab_window ?
 | 
			
		||||
                           display->grab_window->desc : 
 | 
			
		||||
                           "none"));
 | 
			
		||||
              if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
 | 
			
		||||
                {
 | 
			
		||||
                  MetaScreen *screen;
 | 
			
		||||
                  meta_topic (META_DEBUG_WINDOW_OPS, 
 | 
			
		||||
                              "Syncing to old stack positions.\n");
 | 
			
		||||
                  screen = 
 | 
			
		||||
                    meta_display_screen_for_root (display, device_event->event);
 | 
			
		||||
 | 
			
		||||
                  if (screen!=NULL)
 | 
			
		||||
                    meta_stack_set_positions (screen->stack,
 | 
			
		||||
                                              display->grab_old_window_stacking);
 | 
			
		||||
                }
 | 
			
		||||
              meta_display_end_grab_op (display,
 | 
			
		||||
                                        device_event->time);
 | 
			
		||||
            }
 | 
			
		||||
@@ -2393,8 +2443,7 @@ event_callback (XEvent   *event,
 | 
			
		||||
               */
 | 
			
		||||
              unmodified = (device_event->mods.effective & grab_mask) == 0;
 | 
			
		||||
          
 | 
			
		||||
              if (unmodified ||
 | 
			
		||||
                  device_event->detail == 1)
 | 
			
		||||
              if (unmodified || button == 1)
 | 
			
		||||
                {
 | 
			
		||||
                  /* don't focus if frame received, will be lowered in
 | 
			
		||||
                   * frames.c or special-cased if the click was on a
 | 
			
		||||
@@ -2415,7 +2464,7 @@ event_callback (XEvent   *event,
 | 
			
		||||
                        {
 | 
			
		||||
                          meta_topic (META_DEBUG_FOCUS,
 | 
			
		||||
                                      "Focusing %s due to unmodified button %u press (display.c)\n",
 | 
			
		||||
                                      window->desc, device_event->detail);
 | 
			
		||||
                                      window->desc, button);
 | 
			
		||||
                          meta_window_focus (window, device_event->time);
 | 
			
		||||
                        }
 | 
			
		||||
                      else
 | 
			
		||||
@@ -2431,21 +2480,21 @@ event_callback (XEvent   *event,
 | 
			
		||||
                  if (!unmodified)
 | 
			
		||||
                    begin_move = TRUE;
 | 
			
		||||
                }
 | 
			
		||||
              else if (!unmodified && device_event->detail == meta_prefs_get_mouse_button_resize())
 | 
			
		||||
              else if (!unmodified && button == meta_prefs_get_mouse_button_resize())
 | 
			
		||||
                {
 | 
			
		||||
                  if (window->has_resize_func)
 | 
			
		||||
                    {
 | 
			
		||||
                      gboolean north, south;
 | 
			
		||||
                      gboolean west, east;
 | 
			
		||||
                      int root_x, root_y;
 | 
			
		||||
                      MetaRectangle frame_rect;
 | 
			
		||||
                      MetaGrabOp op;
 | 
			
		||||
 | 
			
		||||
                      meta_window_get_position (window, &root_x, &root_y);
 | 
			
		||||
                      meta_window_get_frame_rect (window, &frame_rect);
 | 
			
		||||
 | 
			
		||||
                      west = device_event->root_x <  (root_x + 1 * window->rect.width  / 3);
 | 
			
		||||
                      east = device_event->root_x >  (root_x + 2 * window->rect.width  / 3);
 | 
			
		||||
                      north = device_event->root_y < (root_y + 1 * window->rect.height / 3);
 | 
			
		||||
                      south = device_event->root_y > (root_y + 2 * window->rect.height / 3);
 | 
			
		||||
                      west = device_event->root_x <  (frame_rect.x + 1 * frame_rect.width  / 3);
 | 
			
		||||
                      east = device_event->root_x >  (frame_rect.x + 2 * frame_rect.width  / 3);
 | 
			
		||||
                      north = device_event->root_y < (frame_rect.y + 1 * frame_rect.height / 3);
 | 
			
		||||
                      south = device_event->root_y > (frame_rect.y + 2 * frame_rect.height / 3);
 | 
			
		||||
 | 
			
		||||
                      if (north && west)
 | 
			
		||||
                        op = META_GRAB_OP_RESIZING_NW;
 | 
			
		||||
@@ -2473,21 +2522,21 @@ event_callback (XEvent   *event,
 | 
			
		||||
                                                    op,
 | 
			
		||||
                                                    TRUE,
 | 
			
		||||
                                                    FALSE,
 | 
			
		||||
                                                    device_event->detail,
 | 
			
		||||
                                                    button,
 | 
			
		||||
                                                    0,
 | 
			
		||||
                                                    device_event->time,
 | 
			
		||||
                                                    device_event->root_x,
 | 
			
		||||
                                                    device_event->root_y);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
              else if (device_event->detail == meta_prefs_get_mouse_button_menu())
 | 
			
		||||
              else if (button == meta_prefs_get_mouse_button_menu())
 | 
			
		||||
                {
 | 
			
		||||
                  if (meta_prefs_get_raise_on_click ())
 | 
			
		||||
                    meta_window_raise (window);
 | 
			
		||||
                  meta_window_show_menu (window,
 | 
			
		||||
                                         device_event->root_x,
 | 
			
		||||
                                         device_event->root_y,
 | 
			
		||||
                                         device_event->detail,
 | 
			
		||||
                                         button,
 | 
			
		||||
                                         device_event->time);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -2512,7 +2561,7 @@ event_callback (XEvent   *event,
 | 
			
		||||
                                              META_GRAB_OP_MOVING,
 | 
			
		||||
                                              TRUE,
 | 
			
		||||
                                              FALSE,
 | 
			
		||||
                                              device_event->detail,
 | 
			
		||||
                                              button,
 | 
			
		||||
                                              0,
 | 
			
		||||
                                              device_event->time,
 | 
			
		||||
                                              device_event->root_x,
 | 
			
		||||
@@ -2662,6 +2711,18 @@ event_callback (XEvent   *event,
 | 
			
		||||
            filter_out_event = bypass_compositor = TRUE;
 | 
			
		||||
          break;
 | 
			
		||||
#endif /* HAVE_XI23 */
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
          /* Filter out non-pointer-emulating touches */
 | 
			
		||||
          if ((((XIDeviceEvent *) input_event)->flags & XITouchEmulatingPointer) == 0)
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
          /* Currently unhandled, if any grab_op is started through XI_TouchBegin,
 | 
			
		||||
           * the XIGrabDevice() evmask drops touch events, so only emulated
 | 
			
		||||
           * XI_Motions and XI_ButtonRelease will follow.
 | 
			
		||||
           */
 | 
			
		||||
          g_assert_not_reached ();
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
@@ -2741,7 +2802,7 @@ event_callback (XEvent   *event,
 | 
			
		||||
 | 
			
		||||
              if (display->grab_op != META_GRAB_OP_NONE &&
 | 
			
		||||
                  display->grab_window == window &&
 | 
			
		||||
                  ((window->frame == NULL) || !window->frame->mapped))
 | 
			
		||||
                  window->frame == NULL)
 | 
			
		||||
                meta_display_end_grab_op (display, timestamp);
 | 
			
		||||
      
 | 
			
		||||
              if (!frame_was_receiver)
 | 
			
		||||
@@ -2775,14 +2836,14 @@ event_callback (XEvent   *event,
 | 
			
		||||
              && meta_display_screen_for_root (display, event->xmap.event))
 | 
			
		||||
            {
 | 
			
		||||
              window = meta_window_new (display, event->xmap.window,
 | 
			
		||||
                                        FALSE);
 | 
			
		||||
                                        FALSE, FALSE);
 | 
			
		||||
            }
 | 
			
		||||
          break;
 | 
			
		||||
        case MapRequest:
 | 
			
		||||
          if (window == NULL)
 | 
			
		||||
            {
 | 
			
		||||
              window = meta_window_new (display, event->xmaprequest.window,
 | 
			
		||||
                                        FALSE);
 | 
			
		||||
                                        FALSE, FALSE);
 | 
			
		||||
            }
 | 
			
		||||
          /* if frame was receiver it's some malicious send event or something */
 | 
			
		||||
          else if (!frame_was_receiver && window)        
 | 
			
		||||
@@ -3137,6 +3198,9 @@ event_get_modified_window (MetaDisplay *display,
 | 
			
		||||
        case XI_ButtonRelease:
 | 
			
		||||
        case XI_KeyPress:
 | 
			
		||||
        case XI_KeyRelease:
 | 
			
		||||
        case XI_TouchBegin:
 | 
			
		||||
        case XI_TouchUpdate:
 | 
			
		||||
        case XI_TouchEnd:
 | 
			
		||||
          return ((XIDeviceEvent *) input_event)->event;
 | 
			
		||||
        case XI_FocusIn:
 | 
			
		||||
        case XI_FocusOut:
 | 
			
		||||
@@ -3423,6 +3487,15 @@ meta_spew_xi2_event (MetaDisplay *display,
 | 
			
		||||
    case XI_Leave:
 | 
			
		||||
      name = "XI_Leave";
 | 
			
		||||
      break;
 | 
			
		||||
    case XI_TouchBegin:
 | 
			
		||||
      name = "XI_TouchBegin";
 | 
			
		||||
      break;
 | 
			
		||||
    case XI_TouchUpdate:
 | 
			
		||||
      name = "XI_TouchUpdate";
 | 
			
		||||
      break;
 | 
			
		||||
    case XI_TouchEnd:
 | 
			
		||||
      name = "XI_TouchEnd";
 | 
			
		||||
      break;
 | 
			
		||||
#ifdef HAVE_XI23
 | 
			
		||||
    case XI_BarrierHit:
 | 
			
		||||
      name = "XI_BarrierHit";
 | 
			
		||||
@@ -3480,6 +3553,18 @@ meta_spew_xi2_event (MetaDisplay *display,
 | 
			
		||||
                               enter_event->root_x,
 | 
			
		||||
                               enter_event->root_y);
 | 
			
		||||
      break;
 | 
			
		||||
    case XI_TouchBegin:
 | 
			
		||||
    case XI_TouchUpdate:
 | 
			
		||||
    case XI_TouchEnd:
 | 
			
		||||
      extra = g_strdup_printf ("win: 0x%lx root: 0x%lx touch sequence: %d x: %g y: %g state: 0x%x flags: 0x%x",
 | 
			
		||||
                               device_event->event,
 | 
			
		||||
                               device_event->root,
 | 
			
		||||
                               device_event->detail,
 | 
			
		||||
                               device_event->root_x,
 | 
			
		||||
                               device_event->root_y,
 | 
			
		||||
                               device_event->mods.effective,
 | 
			
		||||
                               device_event->flags);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  *name_p = name;
 | 
			
		||||
@@ -4021,7 +4106,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
 | 
			
		||||
   *   key grab on the RootWindow.
 | 
			
		||||
   */
 | 
			
		||||
  if (grab_window)
 | 
			
		||||
    grab_xwindow = grab_window->frame ? grab_window->frame->xwindow : grab_window->xwindow;
 | 
			
		||||
    grab_xwindow = meta_window_get_toplevel_xwindow (grab_window);
 | 
			
		||||
  else
 | 
			
		||||
    grab_xwindow = screen->xroot;
 | 
			
		||||
 | 
			
		||||
@@ -4119,16 +4204,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
 | 
			
		||||
  g_assert (display->grab_window != NULL || display->grab_screen != NULL);
 | 
			
		||||
  g_assert (display->grab_op != META_GRAB_OP_NONE);
 | 
			
		||||
 | 
			
		||||
  /* Save the old stacking */
 | 
			
		||||
  if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
 | 
			
		||||
    {
 | 
			
		||||
      meta_topic (META_DEBUG_WINDOW_OPS,
 | 
			
		||||
                  "Saving old stack positions; old pointer was %p.\n",
 | 
			
		||||
                  display->grab_old_window_stacking);
 | 
			
		||||
      display->grab_old_window_stacking = 
 | 
			
		||||
        meta_stack_get_positions (screen->stack);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (display->grab_window)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_refresh_resize_popup (display->grab_window);
 | 
			
		||||
@@ -4170,20 +4245,6 @@ meta_display_end_grab_op (MetaDisplay *display,
 | 
			
		||||
      if (!display->grab_threshold_movement_reached)
 | 
			
		||||
        meta_window_raise (display->grab_window);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) ||
 | 
			
		||||
      display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING)
 | 
			
		||||
    {
 | 
			
		||||
      if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
 | 
			
		||||
        meta_screen_tab_popup_destroy (display->grab_screen);
 | 
			
		||||
      else
 | 
			
		||||
        meta_screen_workspace_popup_destroy (display->grab_screen);
 | 
			
		||||
 | 
			
		||||
      /* If the ungrab here causes an EnterNotify, ignore it for
 | 
			
		||||
       * sloppy focus
 | 
			
		||||
       */
 | 
			
		||||
      display->ungrab_should_not_cause_focus_window = display->grab_xwindow;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  /* If this was a move or resize clear out the edge cache */
 | 
			
		||||
  if (meta_grab_op_is_resizing (display->grab_op) || 
 | 
			
		||||
@@ -4549,6 +4610,7 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
 | 
			
		||||
      MetaWindow *window = tmp->data;
 | 
			
		||||
      
 | 
			
		||||
      meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
 | 
			
		||||
      meta_window_frame_size_changed (window);
 | 
			
		||||
      if (window->frame)
 | 
			
		||||
        {
 | 
			
		||||
          meta_frame_queue_draw (window->frame);
 | 
			
		||||
@@ -5932,3 +5994,28 @@ meta_display_clear_mouse_mode (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  display->mouse_mode = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_display_show_restart_message (MetaDisplay *display,
 | 
			
		||||
                                   const char  *message)
 | 
			
		||||
{
 | 
			
		||||
  gboolean result = FALSE;
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (display,
 | 
			
		||||
                 display_signals[SHOW_RESTART_MESSAGE], 0,
 | 
			
		||||
                 message, &result);
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_display_request_restart (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  gboolean result = FALSE;
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (display,
 | 
			
		||||
                 display_signals[RESTART], 0,
 | 
			
		||||
                 &result);
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
@@ -985,7 +983,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
 | 
			
		||||
        {
 | 
			
		||||
          MetaRectangle *new_rect;
 | 
			
		||||
          new_rect = g_new (MetaRectangle, 1);
 | 
			
		||||
          meta_window_get_outer_rect (cur_window, new_rect);
 | 
			
		||||
          meta_window_get_frame_rect (cur_window, new_rect);
 | 
			
		||||
          obscuring_windows = g_slist_prepend (obscuring_windows, new_rect);
 | 
			
		||||
          window_stacking = 
 | 
			
		||||
            g_slist_prepend (window_stacking, GINT_TO_POINTER (stack_position));
 | 
			
		||||
@@ -1010,7 +1008,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
 | 
			
		||||
    {
 | 
			
		||||
      MetaRectangle  cur_rect;
 | 
			
		||||
      MetaWindow    *cur_window = cur_window_iter->data;
 | 
			
		||||
      meta_window_get_outer_rect (cur_window, &cur_rect);
 | 
			
		||||
      meta_window_get_frame_rect (cur_window, &cur_rect);
 | 
			
		||||
 | 
			
		||||
      /* Check if we want to use this window's edges for edge
 | 
			
		||||
       * resistance (note that dock edges are considered screen edges
 | 
			
		||||
@@ -1151,7 +1149,7 @@ meta_window_edge_resistance_for_move (MetaWindow  *window,
 | 
			
		||||
  MetaRectangle old_outer, proposed_outer, new_outer;
 | 
			
		||||
  gboolean is_resize;
 | 
			
		||||
 | 
			
		||||
  meta_window_get_outer_rect (window, &old_outer);
 | 
			
		||||
  meta_window_get_frame_rect (window, &old_outer);
 | 
			
		||||
 | 
			
		||||
  proposed_outer = old_outer;
 | 
			
		||||
  proposed_outer.x += (*new_x - old_x);
 | 
			
		||||
@@ -1237,7 +1235,7 @@ meta_window_edge_resistance_for_resize (MetaWindow  *window,
 | 
			
		||||
  int proposed_outer_width, proposed_outer_height;
 | 
			
		||||
  gboolean is_resize;
 | 
			
		||||
 | 
			
		||||
  meta_window_get_outer_rect (window, &old_outer);
 | 
			
		||||
  meta_window_get_frame_rect (window, &old_outer);
 | 
			
		||||
  proposed_outer_width  = old_outer.width  + (*new_width  - old_width);
 | 
			
		||||
  proposed_outer_height = old_outer.height + (*new_height - old_height);
 | 
			
		||||
  meta_rectangle_resize_with_gravity (&old_outer, 
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_EDGE_RESISTANCE_H
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -18,9 +18,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
@@ -51,9 +49,6 @@ meta_window_ensure_frame (MetaWindow *window)
 | 
			
		||||
  if (window->frame)
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  /* See comment below for why this is required. */
 | 
			
		||||
  meta_display_grab (window->display);
 | 
			
		||||
  
 | 
			
		||||
  frame = g_new (MetaFrame, 1);
 | 
			
		||||
 | 
			
		||||
  frame->window = window;
 | 
			
		||||
@@ -66,8 +61,8 @@ meta_window_ensure_frame (MetaWindow *window)
 | 
			
		||||
  frame->right_width = 0;
 | 
			
		||||
  frame->current_cursor = 0;
 | 
			
		||||
 | 
			
		||||
  frame->mapped = FALSE;
 | 
			
		||||
  frame->is_flashing = FALSE;
 | 
			
		||||
  frame->borders_cached = FALSE;
 | 
			
		||||
  
 | 
			
		||||
  meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
 | 
			
		||||
                window->desc,
 | 
			
		||||
@@ -116,14 +111,6 @@ meta_window_ensure_frame (MetaWindow *window)
 | 
			
		||||
  
 | 
			
		||||
  meta_display_register_x_window (window->display, &frame->xwindow, window);
 | 
			
		||||
 | 
			
		||||
  /* Reparent the client window; it may be destroyed,
 | 
			
		||||
   * thus the error trap. We'll get a destroy notify later
 | 
			
		||||
   * and free everything. Comment in FVWM source code says
 | 
			
		||||
   * we need a server grab or the child can get its MapNotify
 | 
			
		||||
   * before we've finished reparenting and getting the decoration
 | 
			
		||||
   * window onscreen, so ensure_frame must be called with
 | 
			
		||||
   * a grab.
 | 
			
		||||
   */
 | 
			
		||||
  meta_error_trap_push (window->display);
 | 
			
		||||
  if (window->mapped)
 | 
			
		||||
    {
 | 
			
		||||
@@ -166,7 +153,7 @@ meta_window_ensure_frame (MetaWindow *window)
 | 
			
		||||
  /* Move keybindings to frame instead of window */
 | 
			
		||||
  meta_window_grab_keys (window);
 | 
			
		||||
 | 
			
		||||
  meta_display_ungrab (window->display);
 | 
			
		||||
  meta_ui_map_frame (frame->window->screen->ui, frame->xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -327,9 +314,23 @@ meta_frame_calc_borders (MetaFrame        *frame,
 | 
			
		||||
  if (frame == NULL)
 | 
			
		||||
    meta_frame_borders_clear (borders);
 | 
			
		||||
  else
 | 
			
		||||
    meta_ui_get_frame_borders (frame->window->screen->ui,
 | 
			
		||||
                               frame->xwindow,
 | 
			
		||||
                               borders);
 | 
			
		||||
    {
 | 
			
		||||
      if (!frame->borders_cached)
 | 
			
		||||
        {
 | 
			
		||||
          meta_ui_get_frame_borders (frame->window->screen->ui,
 | 
			
		||||
                                     frame->xwindow,
 | 
			
		||||
                                     &frame->cached_borders);
 | 
			
		||||
          frame->borders_cached = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      *borders = frame->cached_borders;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_frame_clear_cached_borders (MetaFrame *frame)
 | 
			
		||||
{
 | 
			
		||||
  frame->borders_cached = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_FRAME_PRIVATE_H
 | 
			
		||||
@@ -41,15 +39,17 @@ struct _MetaFrame
 | 
			
		||||
   */
 | 
			
		||||
  MetaRectangle rect;
 | 
			
		||||
 | 
			
		||||
  MetaFrameBorders cached_borders; /* valid if borders_cached is set */
 | 
			
		||||
 | 
			
		||||
  /* position of client, size of frame */
 | 
			
		||||
  int child_x;
 | 
			
		||||
  int child_y;
 | 
			
		||||
  int right_width;
 | 
			
		||||
  int bottom_height;
 | 
			
		||||
 | 
			
		||||
  guint mapped : 1;
 | 
			
		||||
  guint need_reapply_frame_shape : 1;
 | 
			
		||||
  guint is_flashing : 1; /* used by the visual bell flash */
 | 
			
		||||
  guint borders_cached : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void     meta_window_ensure_frame           (MetaWindow *window);
 | 
			
		||||
@@ -68,6 +68,8 @@ gboolean meta_frame_sync_to_window (MetaFrame         *frame,
 | 
			
		||||
                                    gboolean           need_move,
 | 
			
		||||
                                    gboolean           need_resize);
 | 
			
		||||
 | 
			
		||||
void meta_frame_clear_cached_borders (MetaFrame *frame);
 | 
			
		||||
 | 
			
		||||
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
 | 
			
		||||
 | 
			
		||||
void meta_frame_get_mask (MetaFrame *frame,
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_GROUP_PRIVATE_H
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_GROUP_PROPS_H
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_ICON_CACHE_H
 | 
			
		||||
 
 | 
			
		||||
@@ -21,9 +21,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_KEYBINDINGS_PRIVATE_H
 | 
			
		||||
@@ -32,6 +30,7 @@
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <meta/keybindings.h>
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaKeyHandler MetaKeyHandler;
 | 
			
		||||
struct _MetaKeyHandler
 | 
			
		||||
{
 | 
			
		||||
  char *name;
 | 
			
		||||
@@ -49,9 +48,48 @@ struct _MetaKeyBinding
 | 
			
		||||
  KeyCode keycode;
 | 
			
		||||
  unsigned int mask;
 | 
			
		||||
  MetaVirtualModifier modifiers;
 | 
			
		||||
  gint flags;
 | 
			
		||||
  MetaKeyHandler *handler;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MetaKeyCombo:
 | 
			
		||||
 * @keysym: keysym
 | 
			
		||||
 * @keycode: keycode
 | 
			
		||||
 * @modifiers: modifiers
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _MetaKeyCombo MetaKeyCombo;
 | 
			
		||||
struct _MetaKeyCombo
 | 
			
		||||
{
 | 
			
		||||
  unsigned int keysym;
 | 
			
		||||
  unsigned int keycode;
 | 
			
		||||
  MetaVirtualModifier modifiers;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  char *name;
 | 
			
		||||
  GSettings *settings;
 | 
			
		||||
 | 
			
		||||
  MetaKeyBindingAction action;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * A list of MetaKeyCombos. Each of them is bound to
 | 
			
		||||
   * this keypref. If one has keysym==modifiers==0, it is
 | 
			
		||||
   * ignored.
 | 
			
		||||
   */
 | 
			
		||||
  GSList *combos;
 | 
			
		||||
 | 
			
		||||
  /* for keybindings that can have shift or not like Alt+Tab */
 | 
			
		||||
  gboolean      add_shift:1;
 | 
			
		||||
 | 
			
		||||
  /* for keybindings that apply only to a window */
 | 
			
		||||
  gboolean      per_window:1;
 | 
			
		||||
 | 
			
		||||
  /* for keybindings not added with meta_display_add_keybinding() */
 | 
			
		||||
  gboolean      builtin:1;
 | 
			
		||||
} MetaKeyPref;
 | 
			
		||||
 | 
			
		||||
void     meta_display_init_keys             (MetaDisplay *display);
 | 
			
		||||
void     meta_display_shutdown_keys         (MetaDisplay *display);
 | 
			
		||||
void     meta_screen_grab_keys              (MetaScreen  *screen);
 | 
			
		||||
@@ -79,6 +117,9 @@ gboolean meta_prefs_add_keybinding          (const char           *name,
 | 
			
		||||
 | 
			
		||||
gboolean meta_prefs_remove_keybinding       (const char    *name);
 | 
			
		||||
 | 
			
		||||
GList *meta_prefs_get_keybindings (void);
 | 
			
		||||
void meta_prefs_get_overlay_binding (MetaKeyCombo *combo);
 | 
			
		||||
const char *meta_prefs_get_iso_next_group_option (void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -17,9 +17,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -44,15 +42,16 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
#define _SVID_SOURCE /* for putenv() and some signal-related functions */
 | 
			
		||||
#define _XOPEN_SOURCE /* for putenv() and some signal-related functions */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <meta/main.h>
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
#include "session.h"
 | 
			
		||||
#include "stereo.h"
 | 
			
		||||
#include <meta/prefs.h>
 | 
			
		||||
#include <meta/compositor.h>
 | 
			
		||||
 | 
			
		||||
@@ -287,8 +286,12 @@ event_dispatch (GSource    *source,
 | 
			
		||||
                gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterEvent *event = clutter_event_get ();
 | 
			
		||||
 | 
			
		||||
  if (event)
 | 
			
		||||
    clutter_do_event (event);
 | 
			
		||||
    {
 | 
			
		||||
      clutter_do_event (event);
 | 
			
		||||
      clutter_event_free (event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -382,6 +385,7 @@ meta_init (void)
 | 
			
		||||
  struct sigaction act;
 | 
			
		||||
  sigset_t empty_mask;
 | 
			
		||||
  GIOChannel *channel;
 | 
			
		||||
  ClutterSettings *clutter_settings;
 | 
			
		||||
  
 | 
			
		||||
  sigemptyset (&empty_mask);
 | 
			
		||||
  act.sa_handler = SIG_IGN;
 | 
			
		||||
@@ -441,10 +445,21 @@ meta_init (void)
 | 
			
		||||
  
 | 
			
		||||
  meta_ui_init ();
 | 
			
		||||
 | 
			
		||||
  meta_restart_init ();
 | 
			
		||||
 | 
			
		||||
  meta_stereo_init ();
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Clutter can only be initialized after the UI.
 | 
			
		||||
   */
 | 
			
		||||
  meta_clutter_init ();
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * XXX: We cannot handle high dpi scaling yet, so fix the scale to 1
 | 
			
		||||
   * for now.
 | 
			
		||||
   */
 | 
			
		||||
  clutter_settings = clutter_settings_get_default ();
 | 
			
		||||
  g_object_set (clutter_settings, "window-scaling-factor", 1, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -14,9 +14,7 @@
 | 
			
		||||
 * 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.
 | 
			
		||||
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Giovanni Campagna <gcampagn@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user