Compare commits

...

498 Commits

Author SHA1 Message Date
Owen W. Taylor
cbedfd680f Bump version to 2.91.0 2010-10-04 13:38:24 -04:00
Owen W. Taylor
a1e2e2a13d Fix builddir != srcdir builds
An accidental removal of $$pwd was causing Meta-<version>.gir to
be generated in srcdir.
2010-10-04 13:38:24 -04:00
William Jon McCann
a53a40c43e Use the correct image missing icon name from the icon naming spec
Fixes an assertion when the wrong icon can't be found.
2010-10-02 16:35:19 -04:00
Benjamin Otte
33489c8cb8 Adapt to GTK API changes
This code adapts mutter to the latest changes to GTK in
http://git.gnome.org/browse/gtk+/commit/?id=872ef111ecabf6cd4453590b1e17afd3c9757f28
that remove the dest argument from gdk_pixbuf_get_from_window() and
gdk_pixbuf_get_from_surface().

It also removes the dest argument from meta_gdk_pixbuf_get_from_pixmap()
to match. The function is internal and the argument wasn't used.

https://bugzilla.gnome.org/show_bug.cgi?id=631147
2010-10-02 04:27:05 +02:00
Florian Müllner
c382d8f7ea Remove unused variable 2010-09-30 18:49:21 +02:00
Adel Gadllah
f2ccf70f8d mutter-window: Don't track the window type twice
Currently mutter-window has its own type field, even though the same
information is already present in meta_window.

And while at it get rid of MetaCompWindowType, it is equally redundant.

https://bugzilla.gnome.org/show_bug.cgi?id=630363
2010-09-30 18:35:12 +02:00
Alban Browaeys
ff04e38326 Replace gtk_window_set_visual() with gtk_widget_set_visual()
gtk_window_set_visual() was changed back to work on a widget level
for more compatibility with 2.x.

https://bugzilla.gnome.org/show_bug.cgi?id=630843
2010-09-28 15:37:53 -04:00
Adel Gadllah
1123fca3f2 mutter-window: Add error traps check_needs_reshape
A window might change its shape and close immediately and thus causing
XShapeGetRectangles to produce a BadWindow, use an error trap
to avoid that.
2010-09-27 20:11:53 +02:00
Matthias Clasen
33e2d15495 Adapt to GtkObject removal in GTK3
The destroy signal has been moved to GtkWidget, so change the class_init
functions of MetaFrames and MetaAccelLabel to match.

https://bugzilla.gnome.org/show_bug.cgi?id=630671
2010-09-27 13:58:36 -04:00
Benjamin Otte
b265e8099a theme: Get rid of x/y_offset usage when drawing frames
Commit aa65f94c67 that started passing
cairo_t around broke offsets. Since passing cairo_t makes them
unnecessary, this patches removes them rather than fixing them.

This patch changes API.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-27 17:07:23 +02:00
Benjamin Otte
a2b3f9aeb0 frames.c: Clip the client area correctly
The code switched the x and y variables. Oops.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-27 17:07:23 +02:00
Yaron Shahrabani
d19295a68e Updated Hebrew translation. 2010-09-26 23:55:12 +02:00
Benjamin Otte
9f5d8d1a2a Fix compilation against latest GTK3 changes
With the newest changes to GTK3, some things were changed. This patch
now uses the features introduced in gtk3-compat.h in previous patches.

This patch also introduces a macro named USE_GTK3 that is used to
differentiate between GTK3 and GTK2. Its main use is differenting
between expose and draw handlers for GtkWidget subclasses.

The draw vs expose handlers question is usually handled by using ifdefs
at the beginning and end to set up/tear down a cairo_t and then use it.

However, when the function is too different and too many ifdefs would be
necessary, two versions of the function are written. This is currently
the case for:
- MetaAccelLabel
- MetaFrames

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-26 17:09:20 +02:00
Benjamin Otte
e75abacec6 frames.c: Make cached_pixels_draw() take a cairo_t
This basically just moves the creation of the cairo_t out of the
function. It is done in preparation for GTK3.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-26 17:09:20 +02:00
Benjamin Otte
1c31e8ffc2 ui: Port draw_workspace() to take a cairo_t
https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-26 17:09:20 +02:00
Benjamin Otte
1083a4c0b7 Introduce MetaPixmap compatibility wrapper
Similar to the region compatibility shim, we will soon need a
compatibility shim around GdkPixmap/cairo_surface_t. For now, the patch
just introduces the compatibility layer.

This patch also does not include the function
meta_gdk_pixbuf_get_from_pixmap() as that function will need special
treatment in GTK3 anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-26 17:09:20 +02:00
Benjamin Otte
d212be799a frames.c: Merge clear_backing() function into its only user
Avoids creating a cairo_t twice. And without the code to create a
cairo_t, there was not a lot left to warrant a separate function.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-26 17:09:20 +02:00
Benjamin Otte
84986c7695 frames.c: Change meta_frames_paint() to take a cairo_t
Rename meta_frames_paint_to_drawable() to meta_frames_paint() and make
it take a cairo_t as an argument instead of creating the cairo_t itself.

This patch refactors code for GTK3 changes where code needs to handle
cairo_t and not GdkDrawable arguments.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-26 17:09:20 +02:00
Benjamin Otte
aa65f94c67 theme: Upgrade to use Cairo for painting (changes API)
This commit is in preparation for the work happening in GTK3, which will
use Cairo for drawing exclusively. So it is necessary to move all
drawing code to Cairo. In this commit the "gtk2" code is used for both
gtk2 and gtk3; compatibility with newer versions of gtk3 where different
code is needed will be added subsequently.
For compatibility with older GTK versions, the file gdk2-drawing-utils.h
provides a compatibility layer.

The commit changes the API of libmutter-private.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-26 17:09:20 +02:00
Benjamin Otte
dc80242e51 build: Only install libmutter-private for GTK3 builds
Define INSTALL_LIBMUTTER_PRIVATE with AM_CONDITIONAL and use it to build
an installed or uninstalled libmutter-private.so

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-26 17:09:20 +02:00
Benjamin Otte
f2c63e5eec ui: Remove unused meta_gdk_pixbuf_get_from_window()
https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-26 17:09:20 +02:00
Kjartan Maraas
1fc91dc459 Updated Norwegian bokmål translation 2010-09-26 11:44:57 +02:00
Florian Müllner
a2e4789b3e tiling: Limit tiling to landscape orientation
Tiling is arguably only useful for monitors in landscape orientation,
so disable it when the current monitor is in portrait orientation.
2010-09-24 17:46:57 +02:00
Owen W. Taylor
7d58524185 Fix use of (closure) annotation
For functions (but not callback types), '(closure)' is used on the
callback parameter, and takes the name of the parameter which is
the closure/user data.
2010-09-24 11:28:26 -04:00
Florian Müllner
635e20d057 Allow breaking out from tiling during a mouse resize
Extend the code which allows resizing maximized windows using
alt-middle-drag, so that it applies to tiled windows as well.

https://bugzilla.gnome.org/show_bug.cgi?id=629931
2010-09-23 13:32:35 +02:00
Owen W. Taylor
1c3f7c4088 Allow breaking out from maximization during a mouse resize
A maximized window can't be resized from the screen edges (preserves
Fitts law goodness for the application), but it's still possible
to start a resize drag with alt-middle-button. Currently we just
don't let the user resize the window, while showing drag feedback;
it's more useful to let the user "break" out from the resize.

This provides a fast way to get a window partially aligned with
the screen edges - maximize, then alt-drag it out from one edge.

Behavior choices in this patch:

 - You can drag out a window out of maximization in both directions -
   smaller and larger. This can be potentilaly useful in multihead.

 - Dragging a window in only one direction unmaximizes the window
   fully, rather than leaving it in a horizontally/vertically
   maximized state. This is done because the horizontally/vertically
   maximzed states don't have clear visual representation and can
   be confusing to the user.

 - If you drag back to the maximized state after breaking out,
   maximization is restored, but you can't maximize a window by
   dragging to the full size if it didn't start out that way.

A new internal function meta_window_unmaximize_with_gravity() is
added for implementing this; it's a hybrid of
meta_window_unmaximize() and meta_window_resize_with_gravity().

Port of the metacity patch from Owen Taylor in bug 622517.

https://bugzilla.gnome.org/show_bug.cgi?id=629931
2010-09-23 13:32:35 +02:00
Benjamin Otte
5c3b0cda2e ui: gtk_widget_show() the MetaFrames object
The widget needs to be visible and mapped for GTK3 to deliver expose
events to the widget. This is achieved by making the map function a
no-op and calling gtk_widget_show() instead of just calling
gtk_widget_realize().
Apart from making GTK think the widget is drawable, the effect is the
same.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:54:14 +02:00
Benjamin Otte
a3c6486e52 Remove MetaImageWindow
The code isn't used anymore.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:54:14 +02:00
Benjamin Otte
741d2b761a frames.c: Simplify cached area subtraction code
Because we store the affected rectangle in the piece, we can just
subtract it and don't need any complicated computations.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:54:14 +02:00
Benjamin Otte
a0ffe71db3 Change the cached rectangle ares to a GdkRectangle
Simplifies the code as the rectangle is mainly interacting with GDK
APIs.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:54:14 +02:00
Benjamin Otte
ecf812db83 frames.c: Do not create pixmaps when there's nothing to draw
https://bugzilla.gnome.org/show_bug.cgi?id=630203

Take advantage of existing handling for CachedFramePiece.piece == NULL
to avoid generating pixmaps when width/height are 0
2010-09-23 12:54:14 +02:00
Benjamin Otte
afd3b96e2e Simplify code: Use cairo_paint() to paint the whole pixmap
Also, gdk_drawable_get_size() is going away soon

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:54:14 +02:00
Benjamin Otte
b79e6c0b3e Remove unused code
https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:54:14 +02:00
Benjamin Otte
c6f8ad24bd Remove MetaArea widget
It's unused.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:54:14 +02:00
Benjamin Otte
d4d05e496a Remove meta_ui_get_pixbuf_from_pixmap() function
https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:54:14 +02:00
Benjamin Otte
0a88329526 Move begin_paint() handling to expose handler
This way, we can remove the special casing in
meta_frames_paint_to_drawable().
Since the setup in meta_frames_paint_to_drawable() is relatively cheap,
doing it once per rectangle in the expose area should be fine.

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:54:00 +02:00
Benjamin Otte
b4344b5ab5 Remove NULL checks in meta_frame_layout_get_borders()
This function actually handles NULL. (And I'm going to pass some NULLs
soon).

https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:31:02 +02:00
Benjamin Otte
4ac836fde4 Remove client area from region in expose event
https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:31:02 +02:00
Benjamin Otte
7897448a5b frames.c: Remove workaround now that clip_to_screen() works properly
This code seems to be basically broken. It looks like it tried to clip
the expose area to the screen, but used screen coordinates for the
screen area but frame coordinates for the frame area. So someone tried
to work around this by adding a border around the screen, which made the
broken clipping work most of the time (see bugs below for examples where
it didn't).
Anyway, all of this is gone now.

https://bugzilla.gnome.org/show_bug.cgi?id=399529
https://bugzilla.redhat.com/show_bug.cgi?id=557402
https://bugzilla.gnome.org/show_bug.cgi?id=538438
https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:31:01 +02:00
Benjamin Otte
94f4011844 frames.c: Make clip_to_screen() actually clip to the screen
https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:31:01 +02:00
Benjamin Otte
3f8e6020f7 ui: Clip the region once, not every rectangle manually
https://bugzilla.gnome.org/show_bug.cgi?id=630203
2010-09-23 12:31:01 +02:00
Florian Müllner
beb65f011d tile-preview: Fix crash when falling back to default style
gtk_rc_get_style_by_paths() returns NULL if no matching style was
found and the default style should be used. Actually use the default
style in this case.

https://bugzilla.gnome.org/show_bug.cgi?id=630003
2010-09-22 00:11:14 +02:00
Owen W. Taylor
c2f894963a Use GDK error trapping straight-up
The hacks we were playing by calling gdk_error_trap_push() and then
resetting the error handler are incompatible with the rewrite of
GDK error traps.

Since the new error code has some features that simplify what we
are doing (like automatically figuring out whether a XSync() is needed)
and because our custom error handler didn't have a lot of a point,
use a separate code path for GTK+ 3.0 builds that just uses the
GDK error traps straight-up without a custom error handler.

https://bugzilla.gnome.org/show_bug.cgi?id=630195
2010-09-20 18:41:21 -04:00
Nickolas Lloyd
dacea8edf9 Fix behavior of the window resize popup to only appear when resizing
This patch reverts part of commit 94f6479, which accidentally removed
a section of code and introduced this bug.

https://bugzilla.gnome.org/show_bug.cgi?id=598603
2010-09-20 11:14:45 -04:00
Adel Gadllah
3fed2ab64d [mutter-shaped-texture] Use a base material for all instances
Use a base material for all textures rather than recreating it for every instance,
this should allow Cogl to optimize the program generation.

Idea 'stolen' from:

http://git.clutter-project.org/clutter/commit/?id=7e56a98413817479d0501ce8af9fad3e6411104d

https://bugzilla.gnome.org/show_bug.cgi?id=629350
2010-09-19 16:17:36 +02:00
Mario Blättermann
476652da0a [i18n] Updated German translation 2010-09-19 13:52:05 +02:00
Bruno Brouard
35289050e4 Updated French translation 2010-09-19 00:22:14 +02:00
Owen W. Taylor
ed9d7f18a6 Avoid confusion when _NET_WM_USER_TIME_WINDOW is in the window stack
Wine sets _NET_WM_USER_TIME_WINDOW to point to an unmapped toplevel;
this was causing much confusion because both the real window and
the unmapped window were in the window stack and mapped back to the
same MetaWindow.

Debugged by Alban Browaeys
https://bugzilla.gnome.org/show_bug.cgi?id=593887
2010-09-17 14:23:33 -04:00
Jorge González
a7d1053ff5 Updated Spanish translation 2010-09-17 19:47:59 +02:00
Florian Müllner
97e2b4666b Implement side-by-side tiling
When dragging a window over a screen edge and dropping it there,
maximize it vertically and scale it horizontally to cover the
corresponding half of the current monitor.

Whenever a "hot area" which triggers this behavior is entered, an
indication of window's target size is displayed after a short delay
to avoid distraction when moving a window between monitors.

https://bugzilla.gnome.org/show_bug.cgi?id=606260
2010-09-17 16:00:03 +02:00
Florian Müllner
7d8cc4f940 Fix build error introduced in the last commit 2010-09-15 03:15:46 +02:00
Florian Müllner
ee2f995fc7 introspection: Fix annotations
The scanner got stricter again - some annotations need fixing.
2010-09-15 02:31:47 +02:00
Gabor Kelemen
7e852f8c14 Updated Hungarian translation 2010-09-14 12:07:08 +02:00
Matej Urbančič
b4c1692d14 Updated Slovenian translation 2010-09-11 20:29:06 +02:00
Dr.Tirumurti Vasudevan
c0858b247f Updated Tamil translation 2010-09-11 15:16:58 +05:30
A S Alam
0a956f56aa update for Punjabi 2010-09-11 08:35:26 +05:30
Maxim Ermilov
66105c6e7e Optionally attach modal dialogs
Add a preference /apps/mutter/general/attach_modal_dialogs. When true, instead
of having independent titlebars, modal dialogs appear attached to the titlebar
of the parent window and are moved together with the parent window.
https://bugzilla.gnome.org/show_bug.cgi?id=612726
2010-09-11 05:36:12 +04:00
Maxim Ermilov
bb1ab0afd9 Lower a window and all its transients as a unit
It's strange to leave transients windows around, after ancestor window was
lowered and unfocused.
https://bugzilla.gnome.org/show_bug.cgi?id=612726
2010-09-11 05:36:02 +04:00
Jasper St. Pierre
0d51d9e4cf Remove usage of 'gdk_display', a removed symbol in gtk3.
https://bugzilla.gnome.org/show_bug.cgi?id=629232
2010-09-10 15:18:06 -04:00
Colin Walters
e3789e31ef introspection: Remove workaround MetaMutter comment
The scanner should understand this better now.
2010-09-09 11:45:08 -04:00
Florian Müllner
8a6b583cdc Adjust for API break in gdkkeysyms.h
The key symbols were renamed to avoid namespace conflicts with
gobject-introspection.
2010-09-09 17:37:48 +02:00
Piotr Drąg
86b8b9051f Updated Polish translation 2010-09-07 18:17:25 +02:00
Colin Walters
4c0763792d introspection: Build with --warn-fatal, drop fix-meta-rectangle.py hack
Cleanly build with --warn-fatal.  Implementation:

* Liberally apply (skip) where the API is clearly C only, e.g. uses
  XLib.  The theming code and MutterPlugin are skipped too.
* Add missing (transfer) and (element-type) annotations

For a few functions that had a comment, I turned it into gtk-doc, but
I didn't (with a few exceptions) try to write new documentation in
this pass.
2010-09-07 10:48:07 -04:00
Duarte Loreto
599eb5e3e4 Updated Portuguese translation 2010-09-04 23:06:24 +01:00
Luca Ferretti
31fe25aa78 Unfuzzy translations 2010-09-02 22:58:12 +02:00
Luca Ferretti
252657905f Updated Italian translation 2010-09-02 22:56:20 +02:00
Colin Walters
77a5e817a5 introspection: Use new --accept-unprefixed
Also depend on an introspection version which has this.
2010-09-01 13:20:39 -04:00
Michael Kotsarinis
2521e8103d l10n: Updated Greek translation for mutter 2010-09-01 11:50:37 +03:00
Colin Walters
47fcb998f5 introspection: Enable warnings
Also depend on Makefile to ensure we rerun on build changes.
2010-08-31 19:50:43 -04:00
Philip Withnall
455c40677b Update British English translation 2010-08-31 09:56:30 +01:00
Gabor Kelemen
9ae8e4c006 Updated Hungarian translation 2010-08-31 01:19:09 +02:00
Antonio Fernandes C. Neto
d514516543 Updated Brazilian Portuguese translation 2010-08-30 15:11:24 -03:00
Rob Staudinger
1024eae742 Really install region.h as private header
Libmutter-private's preview-widget.h depends on region.h, so that one
needs to be installed as well in order to keep dependees build.

Signed-off-by: Tomas Frydrych <tf@linux.intel.com>
2010-08-27 10:59:21 +01:00
Tomas Frydrych
dad1f01c5b Fixed incorrect location of regin.h in the previous commit
region.h lives in include, not ui
2010-08-27 10:06:37 +01:00
Tomas Frydrych
ce53f35974 Added region.h to installed headers
region.h is explicictely included by the installed preview-widget.h
2010-08-27 09:59:08 +01:00
Alexander Shopov
3d19e800ab Updated Bulgarian translation 2010-08-24 15:45:58 +03:00
Adel Gadllah
2a54baf60e Trap xerrors in mutter_window_pre_paint
XDamageSubstract can create a BadDamage
(when the window goes away before XDamageSubstract is called)
and thus resulting into a crash.

Fix it by protecting the call with an error trap.

https://bugzilla.gnome.org/show_bug.cgi?id=623235
2010-08-23 22:31:51 +02:00
Thierry Reding
4544fe7571 Fix build against gtk+ older than 2.21.6.
The gdk_window_get_background_pattern() function copied from GDK and
introduced in commit 0839c10 has a small syntax error and uses a private
API (_gdk_drawable_ref_cairo_surface()). This patch imports the missing
API and fixes the syntax error.

https://bugzilla.gnome.org/show_bug.cgi?id=626583
2010-08-23 11:11:50 +01:00
Tomas Frydrych
a125b0179a Do not cancel Alt+Tab grab due to modifier key events
If the user just presses a modifier (e.g., shift) during Alt+Tab grab, we need
to keep the grab in place to allow the custom Alt+Tab handler to deal with what
might simply be a change of tabbing direction.

https://bugzilla.gnome.org/show_bug.cgi?id=613126
2010-08-23 10:35:10 +01:00
Милош Поповић
6b69acdf8b Updated Serbian translation 2010-08-22 15:47:20 +02:00
Ask H. Larsen
8c11a2e5a3 Updated Danish translation 2010-08-22 13:36:05 +02:00
Chao-Hsiung Liao
693c2bc175 Updated Traditional Chinese translation(Hong Kong and Taiwan) 2010-08-21 21:01:55 +08:00
Owen W. Taylor
8b34b4bd0b MutterShapedWindow: drop all indirect references to textures
We don't get correct notifications for the ::cogl-texture property of
ClutterTexture in the case when we are unsetting the pixmap before calling
XFreePixmap. (This is because ClutterX11TexturePixmap is a hack on top
of ClutterTexture and we're a hack on top of that.) So we need to manually
clear everything out.

For consistency we also make sure that we drop all references to dead
textures:

 - When the shape changes
 - If the window pixmap texture changes without first being cleared
   (this is not expected to happen)

https://bugzilla.gnome.org/show_bug.cgi?id=627210
2010-08-19 16:12:11 -04:00
Милош Поповић
8cce57ba44 Updated Serbian translation 2010-08-19 14:48:31 +02:00
Nickolas Lloyd
63f81ed027 Fix meta_window_set_user_time: assertion `!window->override_redirect' failed error messages
This patch adds a check in event_callback () to check whether the
window is override-redirect or not, and avoids unnecessarily calling
meta_window_set_user_time () if it is.

https://bugzilla.gnome.org/show_bug.cgi?id=606158
2010-08-18 17:22:01 -04:00
Owen W. Taylor
c9ebc0ea25 Always use mipmap emulation
Rather than trying to find out from Clutter whether mipmap generation
can be used together with texture_from_pixmap, just always assume
it can't and use the MutterTextureTower emulation code.

This fixes a problem with our previous hack for doing the query
no longer working. In the rare cases where mipmap generation
is supported, it is unlikely to produce significantly more efficient
or better looking results than the emulation. (In terms of efficiency,
we have better knowledge of when we need to update the lower mipmaps
and when we don't than CoglTexturePixmapX11.)

Some care is taken so mutter_shaped_texture_set_create_mipmaps() works
when changed on the fly and properly discards the old mipmap levels.
This isn't necesary currently, since it can only be controlled via
envvar, but is easier than future-proofing through documentation.

https://bugzilla.gnome.org/show_bug.cgi?id=627087
2010-08-18 14:02:32 -04:00
Owen W. Taylor
15a214e435 Fix order of pixmap = None and XFreePixmap() in last commit
The last commit set MutterWindow->priv->back_pixmap to None before
calling XFreePixmap on it. Fix.
2010-08-17 19:07:49 -04:00
Owen W. Taylor
0b3327f04d Unset window pixmaps from MutterShapedWindow before freeing them
At least with the Mesa/DRI implementation of GLX, calling XFreePixmap()
on a pixmap before glxDestroyPixmap() on the corresponding GLX pixmap
causes an X error. To avoid triggering this with the new
ClutterTexturePixmapX11 code, we need to move our XFreePixmap after
unsetting the pixmap from the actor.

https://bugzilla.gnome.org/show_bug.cgi?id=627210
2010-08-17 18:42:02 -04:00
Florian Müllner
0839c100c0 Use gdk_window_get_background_pattern() to clear the background
gdk_window_get_back_pixmap() and gdk_window_get_background() have
been removed/deprecated. Use gdk_window_get_background_pattern()
as replacement.

https://bugzilla.gnome.org/show_bug.cgi?id=626583
2010-08-17 20:57:47 +02:00
Florian Müllner
08cfdcd802 Replace GDK drawing API with cairo
The GDK drawing API was deprecated/removed.

https://bugzilla.gnome.org/show_bug.cgi?id=626583
2010-08-17 20:42:05 +02:00
Adel Gadllah
a1bb3835cc [mutter-shaped-texture] Remove material_workaround
It is no longer needed as the workaround has been removed in
452025e984,
but the material is still around and unused.

https://bugzilla.gnome.org/show_bug.cgi?id=625712
2010-08-16 23:06:46 +02:00
Owen W. Taylor
e590cd2b99 Don't screw up the event mask when "managing" our own windows
When we do pseudo-management on an override-redirect window, we have to be
careful to augment the existing event mask, not replace it, or
delivery of pointer events will be disrupted.

When we unmanage a window, we shouldn't try to unselect events at all,
since that will interfere with event selection done by GDK.

http://bugzilla.gnome.org/show_bug.cgi?id=597763
2010-08-09 12:57:57 -04:00
Nils-Christoph Fiedler
77b620e50e Updated LowGerman translation 2010-08-08 15:45:58 +02:00
drtv
9bc723d256 Updated Tamil translation 2010-08-05 11:51:01 +05:30
A S Alam
b9f9a230e6 update Translation in master for Punjabi by A S Alam 2010-08-04 15:17:03 +05:30
Adel Gadllah
ce1ffa4624 Check for TFP usage after actually setting the pixmap
Starting with clutter 1.4 clutter / cogl only knows whether TFP is in use after
setting the pixmap, so doing the check before setting the pixmap will just
lead to a wrong message.

https://bugzilla.gnome.org/show_bug.cgi?id=624757
2010-07-30 16:16:55 +02:00
Aron Xu
17aa36d343 Update Simplified Chinese translation. 2010-07-24 18:36:51 +08:00
Fran Diéguez
cc0965f9f9 Updated Galician translations 2010-07-21 14:36:14 +02:00
Chao-Hsiung Liao
0e728d7751 Updated Traditional Chinese translation(Hong Kong and Taiwan) 2010-07-20 19:28:28 +08:00
Claude Paroz
3e6cf75d73 Updated French translation 2010-07-19 17:50:22 +02:00
Aron Xu
bbedba8b18 Update Simplified Chinese translation. 2010-07-18 11:10:55 +08:00
Mario Blättermann
c8d756dde3 [i18n] Updated German translation 2010-07-16 21:23:23 +02:00
Matej Urbančič
97a8dbb71e Updated Slovenian translation 2010-07-14 15:03:24 +02:00
Kjartan Maraas
6835804dab Updated Norwegian bokmål translation 2010-07-13 18:54:08 +02:00
Owen W. Taylor
1a2a374380 Bump version to 2.31.5 2010-07-12 11:44:09 -04:00
Andreas Mueller
2b84afc1e3 src/core/util.c: Fix warning in case WITH_VERBOSE_MODE is not set
Signed-off-by: Andreas Mueller <schnitzeltony@gmx.de>

https://bugzilla.gnome.org/show_bug.cgi?id=624166
2010-07-12 11:07:26 -04:00
Nickolas Lloyd
bb3d23f7f6 Add --enable-compile-warnings option to configure script.
This patch adds the option to disable or enable compiler warnings
to maintain compatibility with gnome standard configure options, and
allow users to work around warnings from compiler incompatibility.

--enable-compile-warnings=no disables compile warnings completely,
while --enable-compile-warnings=yes turns on non-fatal warnings.
The default --enable-compile-warnings=error gives the previous behavior.

Dead code for enabling '-ansi -pendantic' is removed, and the
default enabling of -ansi is removed as well. Blanket disabling
GCC extensions and C99 features causes various problems; we're
better off enforcing the dialect we want to use at code review
time.

https://bugzilla.gnome.org/show_bug.cgi?id=616275
2010-07-12 11:07:26 -04:00
Petr Kovar
7511ea27e2 Update Czech translation 2010-07-11 22:05:46 +02:00
Florian Müllner
adbe3a2312 Fix gtk+ dependency in libmutter-private pkg-config file 2010-07-09 18:05:02 +02:00
Fran Diéguez
eda50a91df Updated Galician translations 2010-07-07 18:05:50 +02:00
Owen W. Taylor
7853bb8042 Work around g-ir-scanner problem with Gdk.Rectangle
g-ir-scanner is currently buggy and confuses the Gdk.Rectangle alias
with MetaRectangle. Since this is moderately hard to fix in
gobject-introspection and the fix would conflict with in-progress
changes, work around by doing a 'sed job' on the generated Meta.gir.

https://bugzilla.gnome.org/show_bug.cgi?id=623639
2010-07-06 15:11:13 -04:00
Matej Urbančič
37de1b2d25 Updated Slovenian translation 2010-07-06 15:14:58 +02:00
Jorge González
0c4ac0b48a Updated Spanish translation 2010-07-03 12:35:52 +02:00
Yaron Shahrabani
c24cf44c6a Updated Hebrew translation. 2010-07-03 02:05:52 +03:00
Owen W. Taylor
11a8ab47fa Make MetaRectangle a boxed type
Export a boxed type for MetaRectangle; this is mostly of interest
because GdkRectangle has been turned into a typedef for
cairo_rectangle_int_t which causes massive problems for using it from
gobject-introspection based language bindings.

https://bugzilla.gnome.org/show_bug.cgi?id=623335
2010-07-02 13:14:39 -04:00
Florian Müllner
7feeb72721 Use cairo_region_t when building with gtk+-3.0
GdkRegion has been removed from Gtk+. The replacement is a
yet-unreleased cairo API, so use it only when building with
Gtk+-3.0.

https://bugzilla.gnome.org/show_bug.cgi?id=587991
2010-07-02 04:36:28 +02:00
Florian Müllner
01447d94d1 Allow building with Gtk+-3.0
Add a configure switch to select the Gtk+ version to build with. The
default is to build against Gtk+-2.0 >= 2.18.

https://bugzilla.gnome.org/show_bug.cgi?id=622303
2010-07-02 04:36:27 +02:00
Florian Müllner
e267a63330 Add compatibility with GTK+ 2.18
In order to replace calls to deprecated GDK code, the current
development version of GTK+ is required. Add some basic compatibility
code to allow building mutter with GTK+ 2.18.

https://bugzilla.gnome.org/show_bug.cgi?id=587991
2010-07-01 20:55:12 +02:00
Florian Müllner
c65a24486d Replace deprecated GDK symbols
The fix depends on new API added in this cycle, so the required
GTK+ version is bumped to 2.21.1.

https://bugzilla.gnome.org/show_bug.cgi?id=587991
2010-07-01 20:55:11 +02:00
Nickolas Lloyd
42e786b15b Remove deprecated Gtk+ symbols
This patch removes all uses of deprecated Gtk+ symbols from mutter.

https://bugzilla.gnome.org/show_bug.cgi?id=587991
2010-07-01 20:55:11 +02:00
Claudio Saavedra
7a04673dd7 Don't use deprecated GtkTooltips type unnecessarily
Bug 622800.
2010-06-30 01:35:42 +03:00
Claudio Saavedra
c47d2da0cb Don't incĺude internal gdk headers directly
Bug 622800.
2010-06-30 01:35:35 +03:00
Claudio Saavedra
fd12eddb5d Use g_signal_connect_data() instead of deprecated gtk_signal_connect_full()
Bug 622800.
2010-06-30 01:35:26 +03:00
Claudio Saavedra
0b56599d28 Don't use gtk_type_unique()
Replace usage of deprecated gtk_type_unique() by switching to defining
types with G_DEFINE_TYPE.

Bug 622800.
2010-06-30 01:34:54 +03:00
Owen W. Taylor
27de94b915 Bump version to 2.31.4 2010-06-25 16:18:39 -04:00
Kjartan Maraas
9e31f2b1de Added Norwegian bokmål translation 2010-06-20 11:41:52 +02:00
Maxim Ermilov
13ad103823 Clean up MutterPlugin effect interface
The current effect API passes an unnecessary list of windows to
switch_workspace() and forces a window to be passed in when killing
the switch_workspace() effect.

We can simplify the interface to correspond more closely to how
it is actually used and fix these problems:

Remove the actors parameter to plugin->switch_workspace
Remove the events parameter to plugin->kill_effect and rename it to kill_window_effects
Add plugin->kill_switch_workspace

Remove mutter_plugin_manager_kill_effect
Add mutter_plugin_manager_kill_window_effects
Add mutter_plugin_manager_kill_switch_workspace

Remove mutter_plugin_effect_completed
Add mutter_plugin_[minimize/map/destroy/maximize/unmaximize]_completed
https://bugzilla.gnome.org/show_bug.cgi?id=621082
2010-06-17 01:40:43 +04:00
Owen W. Taylor
ff5a73de49 Fix problem with window unmaximization
A mismerge of the Metacity commit "4943d79 Prevent window self-maximisation"
caused the window's user set size and position to be saved *before*
actually resizing the window to the unmaximized position rather than after.

This meant that after unmaximization the window was in an inconsistent
state and anything that caused a resize to be queued (like a change in
window properties by the application) would cause it to pop back to
the maximized size and position.

https://bugzilla.gnome.org/show_bug.cgi?id=621413
2010-06-14 16:44:28 -04:00
A S Alam
275a6ec63f update Punjabi Translation 2010-06-14 08:09:49 +05:30
Colin Walters
604da0f6ea Add _XOPEN_SOURCE display.c for gethostname()
We shouldn't need _GNU_SOURCE in delete.c anymore either.

https://bugzilla.gnome.org/show_bug.cgi?id=620860
2010-06-07 14:26:45 -04:00
Colin Walters
72a19dd448 [display] Include unistd.h for gethostname
https://bugzilla.gnome.org/show_bug.cgi?id=620860
2010-06-07 12:32:56 -04:00
Colin Walters
3a73f6b8ec Add meta_window_is_remote
It's useful for plugins to be able to easily detect whether
or not a window is from a remote host.  Also, make use of this
in the window delete codepath, instead of looking up the hostname
each time.

https://bugzilla.gnome.org/show_bug.cgi?id=620585
2010-06-07 09:44:14 -04:00
Colin Walters
343474a570 Allow logging only specific debug topics
While debugging a focus problem, I noticed that Mutter had exactly
the debug statements I wanted under the META_DEBUG_FOCUS topic.
However, calling meta_set_verbose (true) results in enormous amounts
of other messages, and it's inconvenient to filter after having
started mutter.

This patch allows one to call Meta.add_debug_topic(Meta.DebugTopic.FOCUS)
from a console, and get just what one wants.

https://bugzilla.gnome.org/show_bug.cgi?id=620359
2010-06-04 11:27:48 -04:00
Robert Bragg
91d82bf8c7 mutter-window: request DamageReportBoundingBox report level
In commit d34ae764769 I switched mutter-window to ask for Raw rectangles
from the X server. This avoided 2 non synchronous and 2 synchronous X
requests per window with damage, per frame; 2 (non-sync) to
create/destroy a temporary region to copy the damage region into, 1 to
request the server to copy the damage region into a our given region and
another to fetch that region back into the client. The problem with raw
events though is that it's possible to DOS the compositor with them.

Instead of receiving an event for every bit of damage this patch instead
asks the server to only report BoundingBox changes to the damage region.

https://bugzilla.gnome.org/show_bug.cgi?id=611838
2010-06-04 00:36:08 +01:00
Fran Diéguez
ed19060074 Updated Galician translations 2010-06-03 23:46:58 +02:00
Yaron Shahrabani
f230a67b94 Updated Hebrew translation. 2010-06-03 14:33:17 +03:00
Owen W. Taylor
849f101feb Bump version to 2.31.2 2010-05-25 14:16:40 -04:00
Owen W. Taylor
f45083ce82 Fix crash with --sync option
If the display hasn't been initialized yet, just change the
start variable and don't update the display.

https://bugzilla.gnome.org/show_bug.cgi?id=618613
2010-05-25 13:24:42 -04:00
Claude Paroz
4c143ae9af Updated French translation 2010-05-17 20:39:44 +02:00
Khaled Hosny
cd1a1d5778 Updated Arabic translation 2010-05-15 23:55:34 +03:00
Tomas Frydrych
e28e7a72aa [MetaDisplay] meta_display_get_leader_window()
This function returns xid of the WM leader window (as defined by the
_NET_SUPPORTING_WM_CHECK mechanism of EWMH). For use by plugins that wish to
attach custom properties to this window.

https://bugzilla.gnome.org/show_bug.cgi?id=613125
2010-05-14 12:44:38 +01:00
Tomas Frydrych
fc9488211f [MetaScreen] Keep num_workspaces key in sync with the actual workspace number
Changing the number of workspaces via an external pager relies on the gconf
key; if a plugin adds or removes workspaces on the fly, we can get into a
situation when the stale number stored by the preferences matches the new
number requested by the pager, in which case the pager request becomes a nop.

This commit ensures that when the meta_screen_append_new_workspace() or
meta_screen_remove_workspace() functions are called, the stored value is
updated accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=613127
2010-05-14 12:31:38 +01:00
Tomas Frydrych
28767c4d34 _MUTTER_HINTS
A per-window _MUTTER_HINTS property allowing plugins to use custom hints. The
property holds a colon separated list of key=value pairs; plugin-specific keys
must be suitably namespaced, while 'mutter-' prefix is reserved for internal
Mutter use only.

This commit adds MetaWindow::mutter-hints property, and
meta_window_get_mutter_hints() accessor, as well as the internal machinery for
reading and updating of the hints.

https://bugzilla.gnome.org/show_bug.cgi?id=613123
2010-05-14 12:20:56 +01:00
Florian Müllner
c6c7b05d7b Add compatibility with GTK+ 2.18
To replace all calls to deprecated code, GTK+ 2.20 is required - add
some basic compatibility code, so that it is still possible to build
mutter with GTK+ 2.18 when not using -DGSEAL_ENABLE.

https://bugzilla.gnome.org/show_bug.cgi?id=595496
2010-05-12 11:02:52 +02:00
Florian Müllner
5526e91b6e Replace left-over accesses of struct members
When replacing direct accesses with accessor functions, two snippets
were left out. Mutter now builds with GSEAL_ENABLE.

https://bugzilla.gnome.org/show_bug.cgi?id=595496
2010-05-12 11:02:52 +02:00
Javier Jardón
9e123695d0 Use accessor functions instead direct access.
GTK+ 2.20 is now the required version

Still missing:
GTK_MENU_SHELL ()->have_xgrab

https://bugzilla.gnome.org/show_bug.cgi?id=595496
2010-05-12 11:02:45 +02:00
Owen W. Taylor
092cc47afc Work around COGL bug causing flash for new windows
COGL bug http://bugzilla.openedhand.com/show_bug.cgi?id=2110 results
in pending drawing at the time of cogl_offscreen_new_to_texture() going
to the newly created framebuffer rather than the stage.

This would result in most windows being missing for the first frame
when a new window is mapped.

Work around this by calling cogl_flush() before
cogl_offscreen_new_to_texture().

https://bugzilla.gnome.org/show_bug.cgi?id=618138
2010-05-09 14:30:18 -04:00
Colin Walters
fd20059f68 Add public function to sort windows by stacking
https://bugzilla.gnome.org/show_bug.cgi?id=616050
2010-05-05 17:18:22 -04:00
Colin Walters
609aae684f Export functions to iterate over window transients
https://bugzilla.gnome.org/show_bug.cgi?id=616050
2010-05-05 17:17:41 -04:00
Colin Walters
49940877d1 Export meta_window_raise and meta_window_lower
For plugins that want fine grained control over window stacking.

https://bugzilla.gnome.org/show_bug.cgi?id=616050
2010-05-05 17:13:08 -04:00
Mario Blättermann
22ae86104b Updated German translation 2010-05-02 12:26:41 +02:00
Edward Sheldrake
f8dd4c160b Fix crash when right-clicking on window frame
This is a regression added in 333446ab.

https://bugzilla.gnome.org/show_bug.cgi?id=614592
2010-04-26 17:04:07 -04:00
Vincent Untz
11061a23b1 Fix build with gcc 4.5
Based on patch by Dominique Leuenberger
<dominique-gnomezilla@leuenberger.net>

https://bugzilla.gnome.org/show_bug.cgi?id=606719
2010-04-26 17:02:23 -04:00
Owen W. Taylor
d8b0f213b2 Fix accounting of frozen with maximize/unmaximize
The beginning maximization/unmaximization don't go through
start_effect_simple(), so we need to freeze the window
separately.

Change MutterWindow.freeze_count to a signed integer for
consistency with other counts, and so the logic for
checking for errors works properly.

https://bugzilla.gnome.org/show_bug.cgi?id=616546
2010-04-26 16:57:06 -04:00
Colin Walters
e9fbe4b2c1 Export the functions to control demands_attention
Plugins can want a finer grained control over this.

https://bugzilla.gnome.org/show_bug.cgi?id=616050
2010-04-24 13:13:54 -04:00
Colin Walters
edcb351107 Export methods interact with user_time
This is useful when calling some of the lower level mutter functions,
e.g. controlling window stacking.

https://bugzilla.gnome.org/show_bug.cgi?id=616050
2010-04-24 13:13:54 -04:00
Robert Bragg
0c14640352 mutter-window: stream raw updates to ClutterX11TexturePixmap
This changes the way we handle Damage events so instead of getting an
event when the damage region of a pixmap becomes non-empty we now get
sent all damage rectangles and stream those all though to
ClutterX11TexturePixmap using clutter_x11_texture_pixmap_update_area()

For Clutter 1.2, ClutterGLXTexturePixmap was updated so that calls to
clutter_x11_texture_pixmap_update_area are now cheap (glXBindTexImageEXT
calls are now deferred until just before painting) and since
ClutterGLXTexturePixmap is now capable of queueing clipped redraws that
can result in only updating a sub-region of the stage during a repaint
cycle (and using glXCopySubBufferMESA to present the sub-region redraw
to the front buffer) this should improve performance and reduced power
consumption for a range of use cases. (For example viewing a website
that has animated adverts doesn't force the whole screen to be redrawn
for each frame of the advert)

Besides being able to take advantage of glXCopySubBuffer to only update
a small region of the stage the fact that this patch makes Mutter now
request RawRectangles from the X server means we no longer do a
synchronous X request for a complete Damage Region for every window
damaged each frame. This should also improve performance.

CLUTTER_PAINT=redraws can be used to visualize what parts of the stage
are redrawn and with this patch applied I can open a terminal and as I
type I see that only the damaged areas of the terminal are being
redrawn.
2010-04-21 16:40:46 +01:00
Robert Bragg
cfa30f9876 make sure we create a pixmap for all new mutter windows
In the case where a mutter window is created for an X Window that is
already mapped then we weren't calling mutter_window_mark_for_repair and
so we weren't calling XCompositeNameWindowPixmap e.g. for menu windows.

This doesn't get noticed because as soon as some damage gets delivered
for such windows the pixmap will be named anyway, but if we were to
change how damage is handled this would result in broken menus.

We now call mutter_window_mark_for_repair in mutter_window_new when the
given Window is already mapped.
2010-04-21 16:40:34 +01:00
Luca Ferretti
af60dd3634 Add a missing space 2010-04-21 14:09:12 +02:00
Matej Urbančič
ccabce1b34 Updated Slovenian translation 2010-04-17 19:39:08 +02:00
Owen W. Taylor
9915a18810 Avoid triggering strict-aliasing checks when iterating preferences
Rewrite the code to iterate generically over Meta*Preference
arrays to avoid running into GCC's strict-aliasing warnings.

https://bugzilla.gnome.org/show_bug.cgi?id=615672
2010-04-14 22:18:45 -04:00
Jorge González
a78373f324 Updated Spanish translation 2010-04-14 19:53:44 +02:00
Owen W. Taylor
1d7476a725 Allow a theme to specify ellipsize width for a title
It's nice to indicate when a title is truncated with an ellipsis.
Because themes may draw a title multiple times to draw a shadow, or
may include the window icon within the title area, we can't determine
the proper ellipsization width automatically, so add an optional
attribute to the <title/> element "ellipsize_width" which, if set,
is the width to ellipsize at.

This is only enabled if a theme version of 3.1 is required.

When it's not set, we keep the old behavior of just letting the
title be clipped with a hard edge.

https://bugzilla.gnome.org/show_bug.cgi?id=591842
2010-04-13 14:10:54 -04:00
Owen W. Taylor
e8e78ebfdd Add frame_x_center/frame_y_center variables for themes
Sometimes you want to position something (usually the title) to be centered
with respect to the entire frame instead of centered with respect to the
individual piece currently being drawn.

This patch adds frame_x_center and frame_y_center variables that represent
the X/Y centers of the frame in the coordinate system of the piece being
drawn.

The theme version is bumped from 3.0 to 3.1 (3.0 is just the new version
system, 3.1 will have all the features we add for Mutter-2.28.)
position expressions

https://bugzilla.gnome.org/show_bug.cgi?id=591842
2010-04-13 14:07:50 -04:00
Owen W. Taylor
b77b0a3d81 Load one copy of plugins early
Although multi-screen support has not been tested and probably
doesn't fully work, the basic setup for multi-screen is that
we have the same list of plugins for all screens, but a different
instance of the plugins for each screen.

To allow plugins to do setup that is screen independent and needs
to occur early in the setup process, we identify a "default plugin
manager" and load (but not start) that plugin manager's plugins
immediately after we know our list of plugins.

That plugin manager is then reused for the first screen we open
and the plugins are started at that time. Separate plugin managers
are loaded and started for any other screens we open.

(A plugin could keep track of whether the screen-independent
setup has been done in a static variable, or it could do everything
in a way that is safe to do repeatedly.)

https://bugzilla.gnome.org/show_bug.cgi?id=615586
2010-04-13 13:53:55 -04:00
Owen W. Taylor
95b260f3a9 Add meta_prefs_override_preference_location()
Allow a plugin to redirect preferences from one GConf location
to another GConf location. This is useful for keys that need to be
set differently in a plugin-managed environment (like GNOME Shell)
as compared to in standalone Metacity.

Overriding is implemented by overwriting the keys in the arrays
of preferences; a list of the current overrides is stored to allow
proper memory management when an override is itself overriden.
(we need to know whether to free the old keys or not)

This patch cleans up the comments in prefs.c a bit as well; some ideas
about less-exciting potential improvements were removed to make the
comments explaining the structure easier to figure out.

https://bugzilla.gnome.org/show_bug.cgi?id=615586
2010-04-13 13:52:39 -04:00
Owen W. Taylor
97a9726845 Add an explicit start() method for plugins
Rather than using the plugin objects constructed() method for doing
setup that requires the MetaScreen, add an explicit start() method
that is called after the screen is set.

The reason for this is that this allows plugin objects to be created
early before the bulk of Metacity setup, which then allows plugins
to affect how the setup happens. (For example, to change the way
that preferences are loaded.)

This is an incompatible change, since 'screen' is now not set in the
constructed method, so the plugin API version is bumped.

https://bugzilla.gnome.org/show_bug.cgi?id=615586
2010-04-13 13:40:16 -04:00
Owen W. Taylor
020aea033c metacity-theme-3.xml: Add a flexible version mechanism
The current mechanism of metacity-theme-1.xml and metacity-theme-2.xml
is not flexible for allowing small-scale additions. With this patch
we bump the major version version once more to metacity-theme-3.xml
and add a single feature:

Any element in the DTD can have an attribute:

 version="[<|<=|=>|>] MAJOR.MINOR"

And it will be ignored unless the predicate is met. (< and > should
be to be entity escaped as &lt; and &gt;)

This allows having alternate sections of the theme file for older and
newer version.

* Required GLib version is bumped to 2.14 so we can parse versions
  with a regular expression.

* We switch internal version numbers to be "1000 * major + minor"

* We keep a stack of the maximum required version for the current portion
  the XML tree so that the "cannot use versions you don't require" stricture
  of the old code can be made local to a subpart of the tree.

* A version on the top metacity_theme element causes the entire file to
  be ignored; this allows having one metacity-theme-3.xml for version 3.2
  and newer (say) and a metacity-1.xml for everything old.

Actual new features will be added starting with 3.1 - 3.0 is just the
version="" feature.

http://bugzilla.gnome.org/show_bug.cgi?id=592503
2010-04-13 13:40:16 -04:00
Owen W. Taylor
0ac46316af Clean up code to find themes
Simplify code to find the right theme to load and loading it by moving
all the loading code into a load_theme() helper function, and making
meta_load_theme() use that as it searches through the directories.

Look for old-version themes even when loading relative to the working
in debug mode.

Don't unnecessarily duplicate and then free info->theme_file and
info->theme_dir.

http://bugzilla.gnome.org/show_bug.cgi?id=592503
2010-04-13 11:15:10 -04:00
Owen W. Taylor
94d47dc25e Make sure all workspaces have a non-empty, non-null name
The change to using gconf_client_all_entries() in commit 2d57b1b4
meant that workspaces without a GConf key for their name were not
getting a name at all. Fix this by doing a post-processing loop
to set workspace names that were not otherwise set.

Alternate to patch from Tomas Frydrych
https://bugzilla.gnome.org/show_bug.cgi?id=613136
2010-04-13 08:51:06 -04:00
Dan Winship
debf08cac0 Fix handling of grabbed key events
https://bugzilla.gnome.org/show_bug.cgi?id=596659
2010-04-12 17:52:19 -04:00
Javier Jardón
ce1393d2d4 Fix missing comma in previous commit 2010-04-11 19:59:29 +02:00
Javier Jardón
fac482c442 Stop using gtk_widget_set_uposition
Replace with non-deprecated gtk_window_move()

http://bugzilla.gnome.org/show_bug.cgi?id=587991
2010-04-11 18:35:22 +02:00
Owen W. Taylor
ee35540b6e Remove compositor-internal window lookup code
Since all windows are now MetaWindows as well as compositor
windows, there's no reason to keep a compositor-specific hash table
mapping from XID to MutterWindow.

This reduces complexity and removes a call to XQueryTree that could
potentially produce a BadWindow error if not error-trapped.

https://bugzilla.gnome.org/show_bug.cgi?id=613398
2010-04-07 10:22:30 -04:00
Adel Gadllah
f77507e825 Don't trap XErrors in meta_compositor_process_event
meta_compositor_process_event uses meta_error_trap_push/pop for
every event processed by meta_compositor_process_event which isn't needed
and can cause performance problems.

https://bugzilla.gnome.org/show_bug.cgi?id=613398
2010-04-07 13:28:19 +02:00
Luca Ferretti
0021efd593 Updated Italian translation 2010-04-06 22:53:15 +02:00
Xandru Armesto Fernandez
0d955bb873 Updated asturian translation 2010-03-30 06:03:10 +02:00
Pavol Šimo
7fa2e8d2d3 Updated Slovak translation 2010-03-27 16:48:20 +01:00
Gintautas Miliauskas
713d94d881 Updated Lithuanian translation. 2010-03-27 12:06:07 +02:00
Petr Kovar
4ecf8964b8 Update Czech translation 2010-03-20 02:54:09 +01:00
Inaki Larranaga Murgoitio
11d044fa6e Updated Basque language 2010-03-19 17:28:47 +01:00
Owen W. Taylor
a2104c5404 Bump version to 2.29.1 2010-03-18 18:29:48 -04:00
Dan Winship
1abed05413 meta_display_get_keybinding_action: strip out uninteresting modifiers
That is, don't consider the state of num lock, xkb group number, etc,
when looking up keybindings.

https://bugzilla.gnome.org/show_bug.cgi?id=613278
2010-03-18 17:57:47 -04:00
Bruno Brouard
1465895ff7 Updated French translation 2010-03-17 21:39:21 +01:00
Robert Bragg
452025e984 Remove the workaround for multi-texturing with old intel drivers
The 2009 Q2 release of the drivers includes the relevent bug fix.

https://bugzilla.gnome.org/show_bug.cgi?id=613121
2010-03-17 16:13:24 +00:00
Tomas Frydrych
d537dd93d5 [MetaWindow] Accessor for the instance part of WM_CLASS property
https://bugzilla.gnome.org/show_bug.cgi?id=613128
2010-03-17 16:10:03 +00:00
Colin Walters
650a1e807c [MetaDisplay] Expose meta_display_get_keybinding_action
This can be used when a plugin has control of input to determine
what action would be done, and thus filter to a subset of them.

https://bugzilla.gnome.org/show_bug.cgi?id=613100
2010-03-17 07:22:04 -04:00
Owen W. Taylor
67f8a33cad Include <sys/wait.h> for WIFEXITSTATUS/WIFEXITED
Exit status macros are specified by POSIX to be in <sys/wait.h>.
Fixes compilation on Solaris.

Reported by Brian Cameron
https://bugzilla.gnome.org/show_bug.cgi?id=612506
2010-03-15 11:09:49 -04:00
Owen W. Taylor
ff4f096f1d Support and require Clutter 1.2
- Specify a minimum version of Clutter-1.2.0
- Remove conditionalizatin and always use Clutter-1.1 framebuffer
  API rather than raw GL fbos
- Replace deprecated cogl_material/texture_unref() with
  cogl_handle_unref()

https://bugzilla.gnome.org/show_bug.cgi?id=610862
2010-03-11 15:06:06 -05:00
Alexander Shopov
b5cb353ab5 Added Bulgarian translation 2010-02-27 10:50:32 +02:00
Nils-Christoph Fiedler
17a38dfbed Updated LowGerman translation 2010-02-25 16:59:48 +01:00
Piotr Drąg
f773683601 Updated Polish translation 2010-02-24 19:29:54 +01:00
Aron Xu
abeaf828a3 Update Simplified Chinese translation. 2010-02-24 18:58:13 +08:00
Mario Blättermann
23a8a4201a Updated German translation 2010-02-21 17:00:06 +01:00
Nguyễn Thái Ngọc Duy
2d409e5c09 Remove executable bit from mutter-shaped-texture.c 2010-02-21 21:23:17 +07:00
Owen W. Taylor
2d57904bf4 Bump version to 2.29.0 2010-02-18 17:08:21 -05:00
Owen W. Taylor
8fa83e1be7 Fix fallback to builtin defaults for key bindings
The change to reduce GConf trips by using
gconf_client_all_entries() broke the fallback to builtin values
because update_binding() was no longer called for bindings not
found in GConf. Fix this by keeping track of the bindings we
find from GConf in a hash table, then looping through and setting
all the bindings at the end.

This also improves efficiency by avoiding a linear scan for each
binding in GConf.

https://bugzilla.gnome.org/show_bug.cgi?id=609710
2010-02-18 14:26:12 -05:00
Owen W. Taylor
8875e73765 Fix crash on startup with list bindings
When we are reading bindings initially, update_list_binding() needs
to be passed the correct "string list type" since we are calling
it with a list of strings instead of a list of GConfValue.

https://bugzilla.gnome.org/show_bug.cgi?id=609101
2010-02-18 14:26:12 -05:00
Richard Hughes
65766fcaac Fix the build when using a compiler that defaults to --no-add-needed
https://bugzilla.gnome.org/show_bug.cgi?id=606388
2010-02-16 16:32:11 -05:00
Owen W. Taylor
4cd4010a70 Fix compiling with --disable-gconf
Make the body of meta_prefs_set_clutter_plugins()
conditional on compiling with GConf support.
2010-02-16 15:17:01 -05:00
Florian Müllner
d21da5643b [MetaWindow] Expose maximized state as properties
Add properties for the EWMH _NET_WM_STATE_MAXIMIZED_HORZ and
_NET_WM_STATE_MAXIMIZED_VERT hints.

https://bugzilla.gnome.org/show_bug.cgi?id=590706
2010-02-15 21:40:46 +01:00
Jorge González
ba700e6387 Updated Spanish translation 2010-02-15 11:31:58 +01:00
Neil Roberts
bd90fd7033 Add the group from cogl_get_option_group() to the GOptionContext
Otherwise it's not possible to use the COGL_DEBUG environment variable.

https://bugzilla.gnome.org/show_bug.cgi?id=609350
2010-02-12 11:40:05 +00:00
Tomas Frydrych
fb3d352d3a [MutterShapedTexture] Use cogl multitexture API
The older code relied on Clutter providing default texture coords for any
layers for which texture coords were not specified, which does not work as
of Clutter 1.1.6 (due to commit 8b950bdc87).

https://bugzilla.gnome.org/show_bug.cgi?id=609657
2010-02-12 11:37:30 +00:00
Gabor Kelemen
690852e157 Hungarian translation updated 2010-02-11 23:34:53 +01:00
Matej Urbančič
aa84d21bcf Updated Slovenian translation 2010-02-11 20:59:51 +01:00
Owen W. Taylor
4d62977c7b Accept an empty string as well as "disabled" for keybindings
Treat the empty string the same as "disabled" for GConf keybinding
keys. gnome-keybinding-properties was changed to write disabled
keys as the empty string a year or so ago.

https://bugzilla.gnome.org/show_bug.cgi?id=559816
2010-02-11 13:02:50 -05:00
Owen W. Taylor
cbac2e7bbb Allow applications to raise windows when raise_on_click is off
Whether Metacity honors a raise request from an application should
not be affected by the raise_on_click setting; remove a check that
seems to have been added in error.

https://bugzilla.gnome.org/show_bug.cgi?id=445447
2010-02-11 13:02:50 -05:00
Owen W. Taylor
88ee4c5b30 Don't focus ancestor window on a different workspace
When we are moving a window with a modal dialog to a different
workspace, meta_workspace_focus_default_window() can be called
with 'not_this_one' being the focused modal dialog.

Since the ancestor of that window is also being moved, we must
not focus it as an alternative to the current window; this will
cause windows to be moved back and Metacity to get into an
inconsistent confused state.

https://bugzilla.redhat.com/show_bug.cgi?id=237158

https://bugzilla.gnome.org/show_bug.cgi?id=598995
2010-02-11 13:02:50 -05:00
Owen W. Taylor
12c46c5d8b Allow explicit raises from same client, not just same app
We currently allow XRaiseWindow when the same application (defined
by the window group) is focused, but the kind of old applications
that XRaiseWindow are frequently not setting the window group.

Expand the check to allow the same X client (defined by the looking
at client ID) to raise windows above the focus window.

https://bugzilla.gnome.org/show_bug.cgi?id=567528
2010-02-11 13:02:50 -05:00
Tomislav Vujec
ab7d4e0e60 Don't warn about a missing session file
When started without session related command line parameters (e.g. from
gnome-session), metacity picks up client_id from the DESKTOP_AUTOSTART_ID
environment variable. Unfortunately, there is no way to distinguish if this was
passed from a config file, representing old saved session, or generated by
gnome-session, therefore load_state is attempted in each case. If the client_id
is generated, there will be no session file, and metacity will report a
warning.

Just remove the warning so that users won't always find a warning at the
start of their .xsession-errors.

https://bugzilla.gnome.org/show_bug.cgi?id=577576
2010-02-11 13:02:49 -05:00
Owen W. Taylor
708c6162c4 Handle XError and XIOError for unknown displays
The atk-bridge GTK+ module opens its own display; if we get an
XIOError on that display, we shouldn't abort with a meta_bug()
but just exit normally. Also fix a segfault if we got an XError
for that display.

https://bugzilla.gnome.org/show_bug.cgi?id=604319
2010-02-11 13:02:49 -05:00
Owen W. Taylor
7834bba6f7 Merge changes from Metacity
Merge all relevant changes from Metacity as of Feb 10, 2010

For future merger's reference, the best way to merge changes from
Metacity is to add the Metacity git repository as a remote, then
cherry-pick the desired changes - this will exploit the shared
history of the two repositories when merging in the changes.

Then when finished, use 'git merge -s ours <head commit of metacity>'
to record the merge, and 'git commit --amend' to fix up the
commit message.
2010-02-11 12:15:29 -05:00
Owen W. Taylor
857c8aaaa2 Make libcanberra support optional
Add a configure switch:

 --with-libcanberra=[yes/no/auto]

(defaulting to auto); if libcanberra is not found or explicitly
disabled, then the default system bell will be used for the bell
sound and no switch workspace sound is played.

https://bugzilla.gnome.org/show_bug.cgi?id=609585
2010-02-11 12:04:11 -05:00
Lennart Poettering
1253e6c64e sound: ask libcanberra to cache alert/desktop switch sounds
These sounds are good candidates for caching in the sound server, to
save a bit of CPU and make reaction faster. Hence, tell libcanberra to
cache them.

https://bugzilla.gnome.org/show_bug.cgi?id=609585
2010-02-11 12:04:10 -05:00
Lennart Poettering
b610b2ecc7 tooltip: set window type hint for self-drawn tooltips to GDK_WINDOW_TYPE_HINT_TOOLTIP
libcanberra generates specific tooltip popup sounds and for that
recognizes the tooltip windows by the GtkWindowTypeHint set for them.

This trivial patch simply sets the hint for the self-drawn tooltips
metacity uses.

https://bugzilla.gnome.org/show_bug.cgi?id=609585
2010-02-11 12:04:10 -05:00
Lennart Poettering
11addbe9c8 bell: increase bell rate limit from 1/s to 1/100ms
Right now metacity issues only 1 bell event per second. This is
feels buggy when triggering multiple alarm sounds in a terminal.

This patch simple increases the limit to 1/100ms. 100ms is probably a
good choice since the HIG recommends that all user reaction should
happen within 100ms. With this applied pressing 'Left' in gnome-terminal
feels much more responsive.

https://bugzilla.redhat.com/show_bug.cgi?id=498608

https://bugzilla.gnome.org/show_bug.cgi?id=609585
2010-02-11 12:04:10 -05:00
Matthias Clasen
709ef05714 Don't force CA_PROP_CANBERRA_ENABLE to 1.
* src/core/bell.c: Don't force CA_PROP_CANBERRA_ENABLE to 1.
That was a misunderstanding on my part, and makes it impossible
to get rid of the bell.

svn path=/trunk/; revision=4165

https://bugzilla.gnome.org/show_bug.cgi?id=609585
2010-02-11 12:04:10 -05:00
Matthias Clasen
c51767eef1 Now that we are using libcanberra, don't tell the X server to play the bell
* src/core/bell.c (meta_bell_set_audible): Now that we are
using libcanberra, don't tell the X server to play the system
bell internally.

svn path=/trunk/; revision=4141

https://bugzilla.gnome.org/show_bug.cgi?id=609585
2010-02-11 12:04:10 -05:00
Matthias Clasen
5aab9e878f Use libcanberra to play system bell and workspace switch sounds
Patch by Lennart Poettering

* configure.in: Require libcanberra-gtk

* src/core/bell.c (meta_bell_notify): Play the alert sound from
the sound theme instead of the dreaded system bell.

* src/core/workspace.c (meta_workspace_activate_with_focus): Play
a sound on workspace switch.

https://bugzilla.gnome.org/show_bug.cgi?id=557921

https://bugzilla.gnome.org/show_bug.cgi?id=609585
2010-02-11 12:04:10 -05:00
Matej Urbančič
e7751e170e Updated Slovenian translation 2010-02-11 15:08:24 +01:00
Kjartan Maraas
776d345bc3 Updated Norwegian bokmål translation 2010-02-11 12:43:02 +01:00
Owen W. Taylor
a8fc30a13f Fix typo when checking the result of getpwuid
Was meant to be:

  errno==0 && pwd!=NULL

Not:

  errno==0 || pwd==NULL

https://bugzilla.gnome.org/show_bug.cgi?id=609586
2010-02-10 16:10:49 -05:00
Matthias Clasen
2d57b1b470 Reduce GConf roundtrips
metacity tries to do the right thing, by preloading all the relevant
directories before getting the keys one-by-one, but GConfClient isn't actually
smart enough to avoid server roundtrips in this case. That should certainly be
fixed in GConf.

In the meantime, here is a patch that reworks the metacity prefs initialization
to avoid roundtrips for individual keys anyway, by using
gconf_client_all_keys().

https://bugzilla.gnome.org/show_bug.cgi?id=574121
https://bugzilla.gnome.org/show_bug.cgi?id=607746
2010-02-10 14:32:48 -05:00
Thomas Hindoe Paaboel Andersen
90f21fa5db Replace usage of deprecated gtk api
Fixes part of GNOME Bug #572332
2010-02-10 14:03:12 -05:00
Vincent Untz
6638d0e507 Increase ping timeout delay to 5s
https://bugzilla.gnome.org/show_bug.cgi?id=568790
2010-02-10 12:49:15 -05:00
Peter Bloomfield
c6793d477a Prevent window self-maximisation
https://bugzilla.gnome.org/show_bug.cgi?id=461927
2010-02-10 12:48:10 -05:00
alexisdm59
11e01ec074 check window has frame before flashing it
https://bugzilla.gnome.org/show_bug.cgi?id=598231
2010-02-10 12:25:40 -05:00
Owen W. Taylor
1d827caaaf Don't call IceCloseConnection() behind libSM's back
The ICE connection is opened by libSM; we can't just close it when
we get an IOError on the ICE connection; instead call SmcCloseConnection()
and mark the connection as closed. This will prevent a segfault if we
exit out of the metacity main loop and get to meta_finalize().

https://bugzilla.gnome.org/show_bug.cgi?id=604867
2010-02-10 12:25:40 -05:00
Travis Watkins
ba4db78ed9 store timestamp for _NET_WM_CM_SX selection
https://bugzilla.gnome.org/show_bug.cgi?id=530702
2010-02-10 12:25:20 -05:00
Thomas Thurman
a321f4c842 Throw away result of write(); it's not important 2010-02-10 12:19:01 -05:00
Claude Paroz
b1c465eab0 Remove markup from translated string 2010-02-10 12:17:43 -05:00
Ray Strode
5134b05af9 Don't call meta_finalize from SIGTERM handler
It's not a legal function to call from a signal handler.
Instead defer until going back to the main loop.

https://bugzilla.gnome.org/show_bug.cgi?id=600864
2010-02-10 12:16:46 -05:00
Owen W. Taylor
dc3a93be99 Add XFCE Terminal as a terminal
Include the XFCE terminal program 'Terminal' in the list of terminals.

https://bugzilla.gnome.org/show_bug.cgi?id=599262
2010-02-10 12:12:58 -05:00
Ray Strode
49aabfec02 Change default cycle_group keybinding to Alt-grave
It makes more sense because the grave key is close
to the tab and escape keys which the other cycle
keybindings use.

This always works better for gnome-shell, which
switchings between applications by default with alt-tab.
The user can now alt-tab to the application they want,
and then move their finger to the grave key to select
the window they want.
2010-02-10 12:12:29 -05:00
Matthias Clasen
11d0d207fd unset _NET_SUPPORTING_WM_CHECK when shutting down 2010-02-10 12:10:55 -05:00
Tomeu Vizoso
eed3245b1b Add a switch to disable autofullscreen'ing maximized windows without decorations 2010-02-10 12:04:42 -05:00
Matt Kraai
a7bbde1699 Don't define meta_spew_event unless verbose mode is on. Closes #571126.
svn path=/trunk/; revision=4132
2010-02-10 11:13:30 -05:00
Matt Kraai
bacccafe3c Only put demands-attention windows into alt-tab if of appropriate type
Windows demanding attention should never appear in the alt-tab list
unless they're of a type which might have appeared there anyway. This
solves a problem under AWN where docks which were marked as demanding
attention appeared in all alt-tab lists; they were irrelevant and it
was impossible to remove them from the lists.

svn path=/trunk/; revision=4123
2010-02-10 11:12:41 -05:00
Thomas James Alexander Thurman
3a80bd47cc some commenting
* src/ui/theme.c: some commenting

svn path=/trunk/; revision=4122
2010-02-10 11:03:01 -05:00
Thomas James Alexander Thurman
152917d5e1 Lines where x1==x2 or y1==y2 may have the second element null
Lines where x1==x2 or y1==y2 may have the second element null. Lines
where both are null, and the width is zero, are points. This speeds
things up surprisingly much.

svn path=/trunk/; revision=4119
2010-02-10 10:53:50 -05:00
Owen W. Taylor
c588e173f8 Remove the year number from the copyright string into a constant
(This is inspired by Metacity commit 45cbaa2 by Thomas Thurman, but
much simpler - the use of g_date_strftime("%Y") ended up being just
%d for all 90+ current translations)
2010-02-10 10:27:48 -05:00
Thomas James Alexander Thurman
c0d2ead351 collapse several strings into one for the translators' benefit.
* src/ui/theme-parser.c: collapse several strings into one
        for the translators' benefit.

svn path=/trunk/; revision=4117
2010-02-10 09:59:28 -05:00
Owen W. Taylor
6ffe5f8343 meta_workspace_set_builtin_struts(): optimize out non-changes
meta_workspace_set_builtin_struts() is slightly expensive; it involves
discarding all our cached computed information about the layout of the
workspace. So catch calls to set_builtin_struts() that don't change
anything.

https://bugzilla.gnome.org/show_bug.cgi?id=609546
2010-02-10 09:56:47 -05:00
Owen W. Taylor
2a823ef3e4 Fix crash when struts change during grab operation
Since meta_workspace_invalidate_work_area() frees the edges
workspace->screen_edges and workspace->monitor_edges, we must clean up
our cached edge resistance data when the invalidate_work_area() is
called on the active workspace, or when the workspace changes.

Make the computation of the edge resistance data lazy so that it
will be recomputed the next time we try to access it.
meta_display_compute_resistance_and_snapping_edges() is made
private to edge-resistance.c

Invaliding the data when active workspace changes also will improve
correctness for edge resistance when the current workspace changes
during a grab operation. (Even with this fix we still don't try to
handle window positions changing during a grab operation; that can't
cause a crash since, unlike screen and monitor edges, the window edges
are freshly allocated, it will just cause slight oddness in that
corner case.)

Root cause tracked down due to much effort by Jon Nettleton.
https://bugzilla.gnome.org/show_bug.cgi?id=608800
2010-02-09 17:00:20 -05:00
Theppitak Karoonboonyanan
5159c3f3ca Updated Thai translation. 2010-02-07 20:20:59 +07:00
Petr Kovar
d092924961 Update Czech translation 2010-02-05 00:05:37 +01:00
Colin Walters
e14132b826 [introspection] Include xlib.gir
We need this for KeySym at least.

https://bugzilla.gnome.org/show_bug.cgi?id=607125
2010-02-03 14:17:41 -05:00
Simos Xenitellis
df36ff638e Updated Greek translation, closes #608572 2010-01-31 05:06:24 -08:00
Ivar Smolin
ad1fee8233 Updating Estonian translation 2010-01-31 10:39:20 +02:00
Ísis Binder
3883d511a9 Updated Brazilian Portuguese translation. 2010-01-29 12:40:29 -05:00
Thomas Thurman
10803b0d25 Update Shavian translation 2010-01-28 19:43:33 -05:00
Jamil Ahmed
a570a57863 Updated Bengali translation 2010-01-29 01:04:35 +06:00
Matej Urbančič
a7590f9717 Updated Slovenian translation 2010-01-27 12:48:28 +01:00
Thomas Thurman
35224ca8d4 post-release bump to 2.28.2 2010-01-25 19:30:02 -05:00
Thomas Thurman
40563e4f84 2.28.1 released 2010-01-25 19:28:50 -05:00
Alexander Shopov
c30901e9be Updated Bulgarian translation 2010-01-25 22:40:20 +02:00
Jorge González
4fc0a91b31 Updated Spanish translation 2010-01-25 19:41:10 +01:00
Dan Winship
576417648a Work around Xlib 64-bit "specialness"
When putting 32-bit properties into longs on 64-bit architectures,
XGetWindowProperty assumes the values are supposed to be signed, and
so it sign-extends values greater than 0x7fffffff. So if they *aren't*
supposed to be signed, we need to chop off the high bits ourselves.

(Most CARDINAL-valued properties only end up using small values
anyway, so it doesn't matter, but _NET_WM_WINDOW_OPACITY uses the full
range, and so was previously failing on 64-bit machines.)

https://bugzilla.gnome.org/show_bug.cgi?id=605678
2010-01-25 11:07:32 -05:00
Owen W. Taylor
0aace5230f Cleanup: split MetaSide from MetaDirection
The MetaDirection enumeration had META_SIDE_* values in it that
were used in some places where an enum with only four directions
was needed. Split this off into a separate enum called MetaSide
and use that enum name where appropriate.
2010-01-22 12:31:20 -05:00
Kjartan Maraas
8d5ba7a6d7 Updated Norwegian bokmål translation 2010-01-22 14:58:23 +01:00
Kjartan Maraas
f8153b84de Updated Norwegian bokmål translation 2010-01-22 14:35:54 +01:00
Matthias Clasen
fac5b0c9e7 Reduce GConf roundtrips 2010-01-21 16:54:22 -05:00
Luis Torres
eb06413188 Replace deprecated symbols in theme-viewer.c
-Replaced calls to gtk_toolbar_insert_stock with gtk_toolbar_insert
-Created appropriated GtkToolButtons
2010-01-21 16:32:35 -05:00
Luis Torres
066c870271 Replaced deprecated symbols in metacity-window-demo.c
-Replaced calls to gtk_toolbar_insert_stock with gtk_toolbar_insert
-Created appropriate GtkToolButton items
2010-01-21 16:31:13 -05:00
Thomas Hindoe Paaboel Andersen
1a92fa788d Replace usage of deprecated gtk api
Fixes part of GNOME Bug #572332
2010-01-21 15:03:47 -05:00
Theppitak Karoonboonyanan
3a0ab1cc0c fix documentation of mouse_button_modifier 2010-01-21 10:58:04 -05:00
Vincent Untz
8a7d588bb0 Increase ping timeout delay to 5s 2010-01-20 15:11:02 -05:00
Peter Bloomfield
4943d79d68 prevent window self-maximisation 2010-01-20 10:59:07 -05:00
Emmanuele Bassi
5de10c34b7 Update the Git ignore file 2010-01-19 02:06:31 +00:00
Emmanuele Bassi
2fbe4c2388 Do not use CGL_* symbols
The CGL_* defines in COGL were always meant to be private and should
have never been exposed in the first place. The API in COGL has been
updated to never require them starting from 1.1, but using the original
GL symbols has always been the intent of the API.

This commit removes the CGL_TEXTURE_RECTANGLE_ARB usage in favour of the
ARB-sanctioned GL_TEXTURE_RECTANGLE_ARB enumeration value.

Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>

https://bugzilla.gnome.org/show_bug.cgi?id=607398
2010-01-19 01:34:22 +00:00
alexisdm59
767cb27f78 check window has frame before flashing it 2010-01-17 13:41:59 -05:00
Erdal Ronahi
b8c75c3fc0 Updated Kurdish translations, author simurg56 2010-01-16 00:13:41 +01:00
Owen W. Taylor
edeadf62ef Don't call IceCloseConnection() behind libSM's back
The ICE connection is opened by libSM; we can't just close it when
we get an IOError on the ICE connection; instead call SmcCloseConnection()
and mark the connection as closed. This will prevent a segfault if we
exit out of the metacity main loop and get to meta_finalize().

https://bugzilla.gnome.org/show_bug.cgi?id=604867
2010-01-14 16:43:51 -05:00
Kjartan Maraas
5ac80057c4 Updated Norwegian bokmål translation 2010-01-13 22:29:55 +01:00
Inaki Larranaga Murgoitio
210e30556e Updated Basque language 2010-01-13 19:19:09 +01:00
Daniel Nylander
0487b4213f Updated Swedish translation 2010-01-09 17:33:27 +01:00
Maxim V. Dziumanenko
8f29c14ac4 Update Ukrainian translation 2010-01-06 17:38:35 +02:00
Matej Urbančič
9543d8be10 Updated Slovenian translation 2010-01-06 15:34:35 +01:00
Jorge González
43e0003e79 Updated Spanish translation 2010-01-06 14:37:45 +01:00
Travis Watkins
30e63a7244 store timestamp for _NET_WM_CM_SX selection 2010-01-05 17:29:06 -05:00
Thomas Thurman
575f520461 Throw away result of write(); it's not important 2010-01-05 15:44:01 -05:00
Claude Paroz
df618c9e91 Remove markup from translated string 2010-01-05 15:39:50 -05:00
Djavan Fagundes
ebd13a4bae Updated Brazilian Portuguese translation 2009-12-31 19:41:18 -02:00
Lucian Adrian Grijincu
7aa54b5a23 Update Romanian translation 2009-12-19 12:38:01 +02:00
Nickolas Lloyd
b20cb36f5d Migrate to new cogl framebuffer framework
The 1.2 API for draw-buffers/framebuffers has changed a bit
since the code in mutter-texture-tower.c was written; adapt to
the changes.

https://bugzilla.gnome.org/show_bug.cgi?id=604200
2009-12-14 11:59:08 -05:00
Owen W. Taylor
86f8c1863e Work around Mesa problem with PFNGLACTIVETEXTUREPROC
PFNGLACTIVETEXTUREPROC (a GL-1.2 addition) was inadvertently missing
from some recent versions of Mesa (like that in Fedora 11.) Use
the identical PFNGLACTIVETEXTUREARBPROC instead.
2009-11-30 10:51:45 -05:00
Frederic Peters
19d85c8566 Fix build failure from SIGCHLD nexus left overs
Looks like there are some leftovers in include/util.h:

/**
 * An object which exists purely to attach signals to; this is to receive
 * signals when a child process exits.  The signal is "sigchld" with no detail.
 */
extern MetaNexus *sigchld_nexus;

Removing those lines fixes the build
2009-11-29 20:40:12 -05:00
Khaled Hosny
4241f91a0a Updated Arabic translation 2009-11-28 06:25:49 +02:00
Khaled Hosny
05624f099a Updated Arabic translation 2009-11-28 05:59:23 +02:00
Nils-Christoph Fiedler
920f4099b6 Added LowGerman translation 2009-11-26 22:05:51 +01:00
Nils-Christoph Fiedler
aa26750e01 Added LowGerman translation 2009-11-26 22:05:03 +01:00
Owen W. Taylor
bdb3be7084 Fix compilation with older libGL
the mutlitexture and texture_rectangle extensions have recently
been incorporated into the GL core; fixes needed to work with
libGL that proceeds that:

GL_TEXTURE_RECTANGLE_ARB - use _ARB name
glActiveTextureARB() - use get_proc_address

https://bugzilla.gnome.org/show_bug.cgi?id=602870
2009-11-24 15:58:42 -05:00
Owen W. Taylor
14987f2b21 Remove XOR gc only used in removed reduced-resources mode
Remove screen.root_xor_gc; this was only used for XOR drawing
in reduced-resources mode, which was removed.

https://bugzilla.gnome.org/show_bug.cgi?id=602740
2009-11-24 15:40:35 -05:00
Owen W. Taylor
47af6a0bbf Nice looking scaledown with mipmap emulation
Add MutterTextureTower, an abstraction for getting a image with
the right level of detail for rendering at a particular scale,
by manually scaling down by powers of two.

This results in much better looking scaled window images when
mipmaps can't be used with texture_from_pixmap (which is the
typical case for current GL drivers.)

When framebuffer objects are available, they are used to do
the scaledown using the GPU without having to pull the data
back from video memory. A software codepath is also available
for the case when FBO's are not present, though performance
will suffer

https://bugzilla.gnome.org/show_bug.cgi?id=601032
2009-11-24 15:40:35 -05:00
Lennart Poettering
1487578ff4 sound: ask libcanberra to cache alert/desktop switch sounds
These sounds are good candidates for caching in the sound server, to
save a bit of CPU and make reaction faster. Hence, tell libcanberra to
cache them.
2009-11-20 11:38:21 -05:00
Lennart Poettering
5a03a5d578 tooltip: set window type hint for self-drawn tooltips to GDK_WINDOW_TYPE_HINT_TOOLTIP
libcanberra generates specific tooltip popup sounds and for that
recognizes the tooltip windows by the GtkWindowTypeHint set for them.

This trivial patch simply sets the hint for the self-drawn tooltips
metacity uses.
2009-11-20 11:36:25 -05:00
Lennart Poettering
2dd137329d bell: increase bell rate limit from 1/s to 1/100ms
Right now metacity issues only 1 bell event per second. This is
feels buggy when triggering multiple alarm sounds in a terminal.

This patch simple increases the limit to 1/100ms. 100ms is probably a
good choice since the HIG recommends that all user reaction should
happen within 100ms. With this applied pressing 'Left' in gnome-terminal
feels much more responsive.

https://bugzilla.redhat.com/show_bug.cgi?id=498608
2009-11-20 11:36:10 -05:00
Dan Winship
db37deb589 Fix handling of SIGCHLD
The commit that removed metacity-dialog added a global SIGCHLD handler
that caused problems by (a) calling waitpid(-1) and thus breaking
g_child_watch for everyone else, and (b) doing too much from a signal
handler and sometimes causing deadlocks (bug 596200).

This removes the global handler and has each zenity user create its
own child watch to watch for exit. (It also fixes the window class of
the zenity dialogs, so that meta_window_present_delete_dialog()
will work again.)
2009-11-20 11:34:50 -05:00
Ray Strode
ec7a3c516d Don't call meta_finalize from SIGTERM handler
It's not a legal function to call from a signal handler.
Instead defer until going back to the main loop.

https://bugzilla.gnome.org/show_bug.cgi?id=600864
2009-11-20 11:16:02 -05:00
Dan Winship
988d2ffab6 Fix handling of SIGCHLD
The commit that removed metacity-dialog added a global SIGCHLD handler
that caused problems by (a) calling waitpid(-1) and thus breaking
g_child_watch for everyone else, and (b) doing too much from a signal
handler and sometimes causing deadlocks (bug 596200).

This removes the global handler and has each zenity user create its
own child watch to watch for exit. (It also fixes the window class of
the zenity dialogs, so that meta_window_present_delete_dialog() will
work again.)
2009-11-20 11:15:58 -05:00
Tomas Frydrych
5e2c66e241 [MetaDisplay] added "window-marked-urgent" signal
Having a MetaDisplay window-marked-urgent signal when a window sets its urgent
hint allows for centralized processing

https://bugzilla.gnome.org/show_bug.cgi?id=600068
2009-11-20 08:57:36 +00:00
Tomas Frydrych
0ccfb0d781 [MetaWindow] added urgent property
Property tracking ICCCM urgency hint

https://bugzilla.gnome.org/show_bug.cgi?id=600068
2009-11-20 08:51:19 +00:00
Nickolas Lloyd
01ce961c00 Fix typo in test-resizing.c
Check heightp not *heightp before assigning to heightp

https://bugzilla.gnome.org/show_bug.cgi?id=602349
2009-11-19 17:40:50 -05:00
Tomas Frydrych
7579b691df [MetaDisplay] Added window-demands-attention signal
Having a MetaDisplay::window-demands-attention signal allows to deal with
windows demanding attention in a cetralized fashion.

The signal is emitted when a window is created with initial demands-attention
state and/or when the state changes later on.

Based on original patch by Jon Nettleton.

https://bugzilla.gnome.org/show_bug.cgi?id=597052
2009-11-17 10:06:25 +00:00
Tomas Frydrych
2a14deab0c [MetaWindow] Added boolean demands-attention property
https://bugzilla.gnome.org/show_bug.cgi?id=588065
2009-11-17 10:06:06 +00:00
Kjartan Maraas
1acefb9eac Updated Norwegian bokmål translation. 2009-11-15 15:06:26 +01:00
Owen W. Taylor
fb45b8f45c Correctly initialize window->input field
With the change from bug 582639, we no longer call the reload
functions for properties that are not initially set, so the
initialization of fields in window.c has to match what
window-props.c would set for a missing property.

There was only one discrepancy, window->input, which needs
to be set to TRUE by default (or a window missing a WM_HINTS
property won't get focus); we also add explicit initializers
for a couple of fields that were getting 0-initialized
to the correct default value of FALSE for consistency with
the explicit intialization of the rest of the fields.

Bug reported by Dominique Leuenberger
https://bugzilla.gnome.org/show_bug.cgi?id=601228
2009-11-12 13:57:11 -05:00
Maxim Ermilov
d59a9c2e8a Correct meta_workspace_list_windows annotation.
https://bugzilla.gnome.org/show_bug.cgi?id=591912
2009-11-12 11:50:07 -05:00
Gil Forcada
a1c3d8723d Minor fixes to Catalan translation 2009-11-05 00:24:21 +01:00
Carles Ferrando
c4bd65e97c Updated Catalan (Valencian) translation 2009-11-05 00:20:36 +01:00
Peteris Krisjanis
eac3a2d7ac Updated Latvian translation. 2009-11-02 22:41:55 +02:00
Thomas Thurman
55bb584778 Shavian translation 2009-10-31 21:57:06 -04:00
Reşat SABIQ
4584943531 Another tiny update for Crimean Tatar (Crimean Turkish) translation 2009-10-30 03:34:44 -05:00
Reşat SABIQ
55d2bc0e0b Another update for Crimean Tatar (Crimean Turkish) translation 2009-10-30 03:07:03 -05:00
Reşat SABIQ
c0cc2fa1b8 Minor wording change 2009-10-30 02:11:58 -05:00
Reşat SABIQ
c1ecbd4de1 Added Crimean Tatar (Crimean Turkish) translation 2009-10-30 01:59:58 -05:00
Khaled Hosny
0fb6b8a8ff Updated Arabic translation 2009-10-29 11:18:31 +02:00
Khaled Hosny
78ba9adfed Spelling fixes 2009-10-29 11:04:46 +02:00
Owen W. Taylor
3f642ea34f Add XFCE Terminal as a terminal
Include the XFCE terminal program 'Terminal' in the list of terminals.

https://bugzilla.gnome.org/show_bug.cgi?id=599262
2009-10-21 23:11:01 -04:00
Åsmund Skjæveland
1a3927b40c Updated Norwegian Nynorsk translation 2009-10-17 18:28:32 +02:00
Khaled Hosny
b09d73ab68 Updated Arabic translation 2009-10-16 20:27:15 +02:00
Colin Walters
9311addca3 Add "window-created" signal to MetaDisplay, "unmanaged" signal for MetaWindow
For some consumers it's significantly more convenient to be able
to directly connect to a signal on the Window to know when
Mutter is done with it, rather than having to connect to each
Workspace object (and handle workspace additions, etc.).

Similarly, add window-created which acts globally.

https://bugzilla.gnome.org/show_bug.cgi?id=598289
2009-10-14 14:39:33 -04:00
Richard Hughes
3c76478510 Bump version to 2.28.1 2009-10-14 17:02:44 +01:00
Leonid Kanter
545551e2bc Updated Russian translation 2009-10-11 16:24:24 +03:00
Petr Kovar
d5e0a95ff1 Updated Czech translation 2009-10-10 18:43:53 +02:00
Tomas Frydrych
e811109566 [MutterWindow] Fixed potential NULL dereference
Avoid dereferencing NULL when the window is not yet placed on a workspace.
Added doc comment, noting this function is deprecated.

https://bugzilla.gnome.org/show_bug.cgi?id=592567
2009-10-09 16:50:38 +01:00
Ray Strode
0f805bfdfb Change default cycle_group keybinding to Alt-grave
It makes more sense because the grave key is close
to the tab and escape keys which the other cycle
keybindings use.

This always works better for gnome-shell, which
switchings between applications by default with alt-tab.
The user can now alt-tab to the application they want,
and then move their finger to the grave key to select
the window they want.
2009-10-09 10:21:52 -04:00
Owen W. Taylor
200cd629df Bump version to 2.28.0 2009-10-07 18:40:18 -04:00
Owen W. Taylor
e8a29c1e82 Work around race condition focusing a window on a different workspace
When we focus a window on a different desktop, and the calc_showing
idle that hides/shows the windows gets run before we get focus events
back from X, we think that we are hiding the window with the focus
so we focus a "random" window to avoid leaving the user with no focus.

Work around this temporarily by checking display->expected_focus_window;
this isn't a perfect fix because there are cases where
display->expected_focus_window corresponds to a window we tried to
focus in the past but failed, but it makes things work fairly well.

https://bugzilla.gnome.org/show_bug.cgi?id=597352
2009-10-07 17:28:04 -04:00
Tomas Frydrych
8589e4f3d3 [MutterScreen] Added workareas-changed signal
This signal is emitted when workarea of any workspace belonging to the screen
changes.

https://bugzilla.gnome.org/show_bug.cgi?id=597009
2009-10-07 12:07:00 +01:00
Tomas Frydrych
948e54772d [MutterWindow] Added meta_window_get_transient_for_as_xid()
Accessor for the transient xid hint.

https://bugzilla.gnome.org/show_bug.cgi?id=597010
2009-10-07 11:56:49 +01:00
Claude Paroz
2d4b05a71b Updated French translation 2009-10-05 18:30:50 +02:00
Christian Kirbach
a6433e84f5 Updated German translation 2009-10-04 19:00:26 +02:00
Owen W. Taylor
083854e2de Create the dummy timeline for repaint laters with an "infinite" duration.
When we create the timeline dummy timeline to ensure that our later
functions that should be run during repaint get called called, pass in
G_MAXUINT to make the duration very long, not 0. (It will get reset
whenever there is no repaint later to run, so the fact that G_MAXUINT
is only ~40 days isn't a problem.)

This fixes a warning from Clutter, but also a real problem.
2009-10-02 16:12:11 -04:00
Owen W. Taylor
3508c4aa87 Use "later functions" to fix priority problems with Clutter redraw
There was a problem where if, for example, a restack was triggered
out of a clutter event handler, then after Clutter processed the
events, it would proceed immmediately on to repaint the stage without
ever returning control to the GLib main loop. So even though we
had an idle handler installed with a higher priority than the
Clutter stage repainting the clutter stage repainting would happen
first and we'd get a wrong frame.

Fix this by introducing the idea of "later functions", which abstract
the idea of "doing something later" away from g_idle_add() and use
a combination of GLib idle functions and Clutter "repaint functions"
to get our callbacks triggered at the right time, even when they
are installed from a clutter event handler.

https://bugzilla.gnome.org/show_bug.cgi?id=596334

This also resolve a FIXME where MUTTER_PRIORITY_BEFORE_REDRAW
could starve stage repainting.
2009-10-02 15:50:16 -04:00
Dan Winship
d04b15ee25 Remove MetaAltTabHandler
gnome-shell is no longer using MetaAltTabHandler, so there's no need
to keep that abstraction around.

This reverts commit 1d5117a6 (and a comment from 7b0ba87b), with a bit
of rebasing and whitespace cleanup.

https://bugzilla.gnome.org/show_bug.cgi?id=596210
2009-10-02 15:47:49 -04:00
Colin Walters
d6143e4c73 mutter_plugin_get_windows returns *Mutter*Window, not MetaWindow 2009-09-28 19:30:24 -04:00
Colin Walters
d8ffc3c187 [mutter_plugin_get_windows] Document it 2009-09-28 16:55:37 -04:00
Owen W. Taylor
2af788956e mutter_begin_modal_for_plugin(): Check result of XGrabKeyboard()
The return value of XGrabKeyboard() wasn't actually being assigned
to the 'result' variable so we didn't notice when grabbing the
keyboard failed.

https://bugzilla.gnome.org/show_bug.cgi?id=596343
2009-09-25 12:59:13 -04:00
Colin Walters
d399141d13 Add meta_window_get_stable_sequence
Useful for plugins which want to order windows in a stable
fashion.

https://bugzilla.gnome.org/show_bug.cgi?id=595882
2009-09-22 12:43:35 -04:00
Frédéric Péters
f6f899f103 [release] 2.28.0 2009-09-22 15:41:33 +02:00
Shankar Prasad
5b8919a246 Updated Kannada(kn) translation 2009-09-21 10:57:57 +05:30
Petr Kovar
fe1989979c Updated Czech translation 2009-09-21 03:15:22 +02:00
Amitakhya Phukan
0895fa9331 Updating Assamese translations 2009-09-20 15:53:01 +05:30
Changwoo Ryu
b90fe0c52a Korean translation update 2009-09-20 09:34:59 +09:00
David Planella
ab0e22159c Updated Catalan translation 2009-09-19 18:29:25 +02:00
Takayuki KUSANO
6ac0afbce0 Updated Japanese translation 2009-09-20 00:56:16 +09:00
Rajesh Ranjan
9532527e52 maithili update, translated by Sangeeta Kumari 2009-09-18 18:28:40 +05:30
Ani
defdf9f34c Updated Malayalam Translations 2009-09-17 23:44:05 +05:30
Yaron Shahrabani
a7dce2dc4e Updated Hebrew translation 2009-09-17 20:01:46 +03:00
Maxim V. Dziumanenko
ea8c51f8f3 Added Ukrainian translation 2009-09-17 19:02:45 +03:00
Manoj Kumar Giri
1e66878447 Upadated Oriya Translation 2009-09-17 18:15:08 +05:30
Manoj Kumar Giri
6cfbdebf6a Upadted Oriya Translation 2009-09-16 19:17:46 +05:30
Antón Méixome
a4469dcc14 Updated Galician Translation 2009-09-16 14:56:21 +02:00
Owen W. Taylor
ac3eac7154 Bump version to 2.27.5 2009-09-15 17:30:07 -04:00
Ani
65ac9065fa Updated Malayalam Translations 2009-09-15 21:26:14 +05:30
Rajesh Ranjan
5143e6763b hindi update by Rajesh Ranjan 2009-09-15 15:12:20 +05:30
Theppitak Karoonboonyanan
5660a8e9f5 Updated Thai translation. 2009-09-15 14:38:08 +07:00
A S Alam
bc2b17df0b Updating Translation for Punjabi 2009-09-15 07:25:17 +05:30
Ani
f9e7c95348 Updaeted Malayalam Translations 2009-09-15 02:54:41 +05:30
Denis ARNAUD
c6afec4759 Updated breton translation 2009-09-14 06:32:03 +02:00
Denis ARNAUD
eb13498fff added br in LINGUAS file 2009-09-14 06:30:37 +02:00
Lucian Adrian Grijincu
163057f521 Updated Romanian translation 2009-09-14 00:10:52 +03:00
Ask H. Larsen
d8ff1f9873 Updated Danish translation 2009-09-13 03:45:00 +02:00
Bruce Cowan
97b7760de8 Updated British English translation 2009-09-12 21:23:02 +01:00
Tommi Vainikainen
acca0f6946 Updated Finnish translation 2009-09-12 22:27:52 +03:00
Matej Urbančič
f3f6d67d46 Updated Slovenian translation 2009-09-12 09:52:02 +02:00
krishnababu k
63773d5226 Updated Telugu Translations 2009-09-11 20:49:57 +05:30
Mario Blättermann
4e4559fc8c Updated German translation 2009-09-10 21:14:43 +02:00
Gintautas Miliauskas
44d540d36c Updated Lithuanian translation. 2009-09-10 14:44:47 +03:00
Fábio Nogueira
c6253a6515 Corrected a bad spacing after a quotation mark in Brazilian Portuguese
translation
2009-09-09 10:06:28 -03:00
Sweta Kothari
65a5ec2ef3 Updated Gujarati Translations 2009-09-09 15:50:22 +05:30
Sandeep Shedmake
70e8b35944 Updated Marathi Translations 2009-09-09 12:54:03 +05:30
Frédéric Péters
ddba25a674 Post-release bump to 2.27.2. 2009-09-08 23:12:45 +02:00
Frédéric Péters
14e6cb6a8f 2.27.1 release 2009-09-08 23:06:42 +02:00
Miloš Popović
d4619150f3 Updated Serbian translation 2009-09-08 13:36:43 +00:00
Colin Walters
5c1a1a2dd5 Fix Super_L specification for overlay_key
A recent commit fixed the schema association, which revealed that our
<Super_L> was wrong, should just be Super_L.
2009-09-07 14:27:09 -04:00
Chao-Hsiung Liao
7cfa690aaf Updated Traditional Chinese translation(Hong Kong and Taiwan) 2009-09-06 15:01:55 +08:00
Claude Paroz
e127898312 Updated French translation 2009-09-04 21:32:33 +02:00
Duarte Loreto
f63b81c52a Updated Portuguese translation 2009-09-03 01:08:03 +01:00
Shankar Prasad
1fe673703f Updated Kannada(kn) translation 2009-09-01 11:33:20 +05:30
Og B. Maciel
979298ce57 Updated mailing list address. 2009-08-30 12:15:18 -04:00
Baris Cicek
66e727e1b2 Updated Turkish translation. 2009-08-30 18:10:53 +03:00
Ivar Smolin
6925779f59 Updating Estonian translation 2009-08-30 13:39:01 +03:00
Gabor Kelemen
125d7daf4a Hungarian translation updated 2009-08-29 14:27:23 +02:00
Gabor Kelemen
cb1020b26d Another update 2009-08-29 14:06:44 +02:00
Gabor Kelemen
e1945506f3 Hungarian translation updated 2009-08-29 13:59:56 +02:00
Luca Ferretti
3a798112f2 Updated Italian translation 2009-08-28 09:55:24 +02:00
Inaki Larranaga Murgoitio
c5dd3e5542 Updated Basque language 2009-08-27 17:36:11 +02:00
Ivar Smolin
2fa9cbfd9e Updating Estonian translation 2009-08-27 10:06:35 +03:00
Runa Bhattacharjee
23af4ee93e Updated Bengali India Translations 2009-08-26 15:42:33 +05:30
Jorge González
0317562605 Updated Spanish translation 2009-08-26 07:57:36 +02:00
Daniel Nylander
1861e0b2cc Updated Swedish translation 2009-08-26 06:04:00 +02:00
Djavan Fagundes
e5974809e8 Updated Brazilian Portuguese translation 2009-08-25 15:21:02 -03:00
Tomasz Dominikowski
abfae17b9a Updated Polish translation 2009-08-25 17:47:45 +02:00
ifelix
84b1a62ad2 Updated Tamil Translations 2009-08-25 17:27:29 +05:30
Denis Arnaud
b6bcaec9bc Updated breton translation 2009-08-25 12:43:20 +02:00
Denis Arnaud
f19ed84cc4 Added br in LINGUAS 2009-08-25 12:43:20 +02:00
Alexander Shopov
6c5a946fda Updated Bulgarian translation 2009-08-24 22:52:12 +03:00
Claude Paroz
c6ffc9427e Add missing quotes in strings (Fixes #572046) 2009-08-24 19:49:29 +02:00
krishnababu k
0f1e64f3b2 Updated Telugu Translations 2009-08-24 17:53:05 +05:30
krishnababu k
1ce5ad3003 Added new entry for Telugu [te] in LINGUAS 2009-08-24 17:52:48 +05:30
Khaled Hosny
64694955c0 Updated Arabic translation 2009-08-23 21:40:47 +03:00
Theppitak Karoonboonyanan
97a90d8122 Updated Thai translation. 2009-08-23 15:50:57 +07:00
Changwoo Ryu
3cd2c08277 Update Korean translation 2009-08-23 04:14:10 +09:00
Henrique P. Machado
c37a2ca1c8 Updated Brazilian Portuguese translation. 2009-08-18 22:34:18 -04:00
Seán de Búrca
80b38210b2 Updated Irish translation 2009-08-17 06:06:18 -06:00
Tommi Vainikainen
e5dffb0097 Updated Finnish translation 2009-08-15 13:59:30 +03:00
Alexander Shopov
deaa897928 Updated Bulgarian translation 2009-08-14 08:00:48 +03:00
Manoj Kumar Giri
3f9758e706 Updated Oriya Translation 2009-08-13 20:29:45 +05:30
Sweta Kothari
3c25c265df Updated Gujarati Translations 2009-08-12 19:08:55 +05:30
Antón Méixome
a8529bd8d1 Updated Galician translation 2009-08-12 13:21:18 +02:00
Luca Ferretti
ba03ca76c4 Updated Italian translation 2009-08-11 01:19:48 +02:00
Jorge González
71fd54ec9e Updated Spanish translation 2009-08-09 20:27:02 +02:00
Christian Kirbach
a03343827e Updated German translation. 2009-08-08 01:47:24 +02:00
Gil Forcada
4fb7c642d5 Minor fix to Catalan translation 2009-08-07 18:57:23 +02:00
drtvasudevan
8a892d47e5 Updated Tamil translation 2009-07-29 13:48:28 +05:30
Ivar Smolin
73abacc20b Updating Estonian translation 2009-07-23 19:00:46 +03:00
Daniel Nylander
aea24279ba Updated Swedish translation 2009-07-22 15:12:43 +02:00
Chao-Hsiung Liao
5c5968e742 Updated Traditional Chinese translation(Hong Kong and Taiwan) 2009-07-22 16:44:17 +08:00
Yaron Sharabani
3813ed9c2e Updated Hebrew translation 2009-07-22 00:57:22 +03:00
Maxim V. Dziumanenko
594897e9a5 Updated Ukrainian translation 2009-07-09 23:28:00 +03:00
Thomas Thurman
40e9f6fa2c unset _NET_SUPPORTING_WM_CHECK when shutting down 2009-07-09 10:26:20 -04:00
Thomas Thurman
35afd2a8fb update changelog 2009-07-09 10:23:03 -04:00
Jorge González
d9be1d7e32 Updated Spanish translation 2009-07-07 20:47:54 +02:00
Tomeu Vizoso
b625ec30d9 Add a switch to disable autofullscreen'ing maximized windows without decorations 2009-07-06 07:51:45 -04:00
Mark Krapivner
f5313268d7 Updated Hebrew translation 2009-07-04 15:47:15 +03:00
Mattias Põldaru
07dedee37b Updating Estonian translation 2009-06-25 14:31:10 +03:00
Runa Bhattacharjee
75f3127ba5 Updated Bengali India Translations 2009-06-24 15:56:42 +05:30
Ivar Smolin
b13fae2556 Updating Estonian translation 2009-06-19 19:58:46 +03:00
Ray Wang
2e9838699b Updated Simplified Chinese translation. 2009-06-06 17:27:37 +08:00
drtvasudevan
ba9c3f41c9 Updated Tamil translation 2009-05-25 17:50:14 +05:30
Jorge Gonzalez
e35fae8f32 Updated Spanish translation 2009-05-23 19:58:37 +02:00
drtvasudevan
b0d5f3bd64 Updated Tamil translation 2009-05-23 17:53:59 +05:30
drtvasudevan
ed640bb181 Updated Tamil translation 2009-05-21 17:48:02 +05:30
Maxim V. Dziumanenko
a3511ba9e2 Updated Ukrainian translation 2009-04-28 14:06:23 +03:00
Ivar Smolin
4c9c903648 Updating Estonian translation 2009-04-25 18:12:34 +03:00
Luca Ferretti
d12aaddc34 Updated Italian transaltion 2009-04-24 22:17:24 +02:00
Olav Vitters
28955bb449 doap: Add desktop category 2009-04-23 19:35:51 +02:00
Matej Urban
dcd7cae7cf Updated Slovenian translation 2009-04-22 12:18:20 +02:00
Jordi Mas i Hernandez
c954bb9456 Minor fixes to Catalan translation 2009-04-22 09:46:20 +02:00
Shankar Prasad
be0b298d81 Updated Kannada Translation 2009-04-21 12:34:27 +05:30
Jorge Gonzalez
409026044b Updated Spanish translation 2009-04-18 20:55:56 +02:00
Funda Wang
0c311bdcf9 Updated zh_CN translation.
svn path=/trunk/; revision=4238
2009-04-10 03:22:43 +00:00
Marcel Telka
e81775e63d Updated Slovak translation by Pavol Šimo.
2009-04-04  Marcel Telka  <marcel@telka.sk>

	* sk.po: Updated Slovak translation by Pavol Šimo.

svn path=/trunk/; revision=4235
2009-04-04 12:45:30 +00:00
Simos Xenitellis
209d7ef613 Updated Greek translation
svn path=/trunk/; revision=4232
2009-03-27 12:07:25 +00:00
Goran Rakic
a6c76a85ce Updated Serbian translation by Miloš Popović.
svn path=/trunk/; revision=4229
2009-03-21 19:49:40 +00:00
Tomasz Dominikowski
265f9e5433 Updated Polish translation
2009-03-19  Tomasz Dominikowski  <tdominikowski@aviary.pl>

	* pl.po: Updated Polish translation

svn path=/trunk/; revision=4228
2009-03-19 11:30:21 +00:00
Ignacio Casal Quinteiro
b86d988b3c Updated Galician translation by Suso Baleato.
svn path=/trunk/; revision=4224
2009-03-18 19:58:04 +00:00
Alexander Shopov
c4148cec33 Updated Bulgarian translation by Alexander Shopov <ash@contact.bg>
2009-03-17  Alexander Shopov  <ash@contact.bg>

	* bg.po: Updated Bulgarian translation by
	Alexander Shopov <ash@contact.bg>

svn path=/trunk/; revision=4220
2009-03-17 07:19:13 +00:00
Gintautas Miliauskas
aa57becc41 Updated Lithuanian translation.
2009-03-14  Gintautas Miliauskas  <gintautas@miliauskas.lt>

	* lt.po: Updated Lithuanian translation.



svn path=/trunk/; revision=4209
2009-03-14 21:06:17 +00:00
Nickolay V. Shmyrev
7269c37c8f Updated Russian translation by Yuriy Penkin.
2009-03-14  Nickolay V. Shmyrev  <nshmyrev@yandex.ru>

	* ru.po: Updated Russian translation by Yuriy Penkin.


svn path=/trunk/; revision=4206
2009-03-14 19:09:33 +00:00
Thomas James Alexander Thurman
3093d7e95a that should not have been checked in
svn path=/trunk/; revision=4199
2009-03-12 02:06:30 +00:00
Thomas James Alexander Thurman
4e0d8a0cbb Post-release bump to 2.27.1.
svn path=/trunk/; revision=4198
2009-03-12 02:05:26 +00:00
Thomas James Alexander Thurman
523151ddf0 svn path=/trunk/; revision=4196
svn path=/trunk/; revision=4196
2009-03-12 01:50:00 +00:00
Thomas James Alexander Thurman
0a7cb94ea8 2.27.0 release.
* NEWS: 2.27.0 release.


svn path=/trunk/; revision=4195
2009-03-12 01:49:30 +00:00
Thomas James Alexander Thurman
d4b7c0e633 2.27.0 release.
svn path=/trunk/; revision=4194
2009-03-12 01:36:30 +00:00
Thomas James Alexander Thurman
3f76affbd2 Remove deprecated GTK symbols. Refs #572332.
* src/include/util.h:
	* src/tools/metacity-window-demo.c:
	* src/ui/fixedtip.c:
	* src/ui/frames.c:
	* src/ui/frames.h:
	* src/ui/menu.c:
	* src/ui/metaaccellabel.c:
	* src/ui/metaaccellabel.h:
	* src/ui/preview-widget.c:
	* src/ui/preview-widget.h:
	* src/ui/tabpopup.c:
	* src/ui/theme-viewer.c:
	* src/ui/themewidget.c:
	* src/ui/themewidget.h:
	* test/tokentest/tokentest.c:


svn path=/trunk/; revision=4193
2009-03-12 01:26:24 +00:00
Thomas James Alexander Thurman
a8f8970601 use g_signal_handlers_disconnect_by_func instead of an old deprecated
* src/tools/metacity-mag.c: use g_signal_handlers_disconnect_by_func
	instead of an old deprecated function.


svn path=/trunk/; revision=4192
2009-03-12 01:16:52 +00:00
Thomas James Alexander Thurman
178b5ff626 fix problem where the previous code ignored callbacks for properties whose
* src/core/window-props.c: fix problem where the previous
        code ignored callbacks for properties whose values weren't
        looked up.  Closes #572573.


svn path=/trunk/; revision=4191
2009-03-12 01:09:41 +00:00
Petr Kovar
c47f7c2806 Updated Czech translation. Removed "src/ui/metacity-dialog.c".
2009-03-08  Petr Kovar  <pknbe@volny.cz>

	* cs.po: Updated Czech translation.
	* POTFILES.in: Removed "src/ui/metacity-dialog.c".

svn path=/trunk/; revision=4185
2009-03-08 19:34:41 +00:00
Thomas James Alexander Thurman
ab6aa5463f add optional dependency on gtop. Include "(as username)" in the titlebar
* configure.in: add optional dependency on gtop.
	* src/core/window-props.c: Include "(as username)"
          in the titlebar if a window is running as another user.
	* src/core/window.c: check for PID before name, since
          the rendering of the name can now depend on the PID.
        Closes #549389.


svn path=/trunk/; revision=4181
2009-03-06 22:51:02 +00:00
Claude Paroz
42387bff6f Updated French translation (synced with gnome-2-26).
2009-03-02  Claude Paroz  <claude@2xlibre.net>

	* fr.po: Updated French translation (synced with gnome-2-26).

svn path=/trunk/; revision=4177
2009-03-02 21:33:24 +00:00
Jorge Gonzalez Gonzalez
3afd25691a Updated Spanish translation
svn path=/trunk/; revision=4171
2009-02-28 12:29:19 +00:00
Matej Urbančič
a6a963bec1 Updated Slovenian translation
svn path=/trunk/; revision=4170
2009-02-24 14:58:19 +00:00
Matthias Clasen
d6ac4dc22a Don't force CA_PROP_CANBERRA_ENABLE to 1. That was a misunderstanding on
* src/core/bell.c: Don't force CA_PROP_CANBERRA_ENABLE to 1.
        That was a misunderstanding on my part, and makes it impossible
        to get rid of the bell.


svn path=/trunk/; revision=4165
2009-02-21 17:00:26 +00:00
Thomas James Alexander Thurman
0b3f45bb1b Use zenity for the session management dialogue that warns about
clueless clients, not metacity-dialog.  This is the last change
	away from metacity-dialog and therefore closes #521914.
	* src/Makefile.am:
	* src/core/session.c:
	* src/core/util.c:
	* src/include/util.h:
	* src/ui/metacity-dialog.c (deleted):


svn path=/trunk/; revision=4163
2009-02-20 19:48:04 +00:00
Og B. Maciel
24f2df926a Updated Brazilian Portuguese translation.
svn path=/trunk/; revision=4162
2009-02-20 13:56:39 +00:00
Daniel Nylander
f00e8655ac sv.po: Updated Swedish translation
svn path=/trunk/; revision=4159
2009-02-19 19:40:33 +00:00
Ilkka Tuohela
41395d9e00 Updated Finnish translation
svn path=/trunk/; revision=4157
2009-02-19 08:01:05 +00:00
Ilkka Tuohela
3e00bcbf9f Updated Finnish translation
svn path=/trunk/; revision=4156
2009-02-19 08:00:17 +00:00
Gabor Kelemen
0b402b23f7 Translation updated.
2009-02-17  Gabor Kelemen  <kelemeng@gnome.hu>

	* hu.po: Translation updated.

svn path=/trunk/; revision=4153
2009-02-17 01:49:56 +00:00
Wouter Bolsterlee
691fcaeee7 Updated Dutch translation by Wouter Bolsterlee.
2009-02-16  Wouter Bolsterlee  <wbolster@svn.gnome.org>

	* nl.po: Updated Dutch translation by Wouter Bolsterlee.


svn path=/trunk/; revision=4151
2009-02-16 18:38:00 +00:00
Kenneth Nielsen
9f30910653 Updated Danish translation
svn path=/trunk/; revision=4148
2009-02-15 13:05:00 +00:00
Ihar Hrachyshka
41a6c2e501 Updated be@latin.po
svn path=/trunk/; revision=4144
2009-02-14 11:17:08 +00:00
Theppitak Karoonboonyanan
fbc7fc6645 Updated Thai translation (merged from gnome-2-26 branch).
2009-02-13  Theppitak Karoonboonyanan  <thep@linux.thai.net>

	* th.po: Updated Thai translation (merged from gnome-2-26 branch).


svn path=/trunk/; revision=4143
2009-02-13 13:45:17 +00:00
Matthias Clasen
573dbb431e Now that we are using libcanberra, don't tell the X server to play the
* src/core/bell.c (meta_bell_set_audible): Now that we are
        using libcanberra, don't tell the X server to play the system
        bell internally.


svn path=/trunk/; revision=4141
2009-02-13 00:09:44 +00:00
Inaki Larranaga Murgoitio
7b2cba7a6c Updated Basque translation.
2009-02-12  Inaki Larranaga Murgoitio  <dooteo@euskalgnu.org>

	* eu.po: Updated Basque translation.


svn path=/trunk/; revision=4139
2009-02-12 19:22:30 +00:00
Matthias Clasen
91ff5617ef Forgotten file
svn path=/trunk/; revision=4138
2009-02-12 14:43:09 +00:00
Matthias Clasen
f1782868f9 Use libcanberra to play system bell and workspace switch sounds
svn path=/trunk/; revision=4137
2009-02-12 00:53:23 +00:00
Daniel Nylander
66ee22c3e6 sv.po: Updated Swedish translation
svn path=/trunk/; revision=4135
2009-02-11 11:52:27 +00:00
Priit Laes
2db1222e45 Translation updated by Mattias Põldaru
2009-02-11  Priit Laes  <plaes at svn dot gnome dot org>

	* et.po: Translation updated by Mattias Põldaru

svn path=/trunk/; revision=4134
2009-02-11 11:32:47 +00:00
Thomas James Alexander Thurman
abbd057eb9 Session must be saved before display close, and display
shouldn't close during shutdown if it's already closed.
        Can't believe we don't have a bug about this already...
	* src/core/display-private.h:
	* src/core/display.c:
	* src/core/main.c:
	* src/core/session.c:


svn path=/trunk/; revision=4133
2009-02-11 05:26:58 +00:00
Thomas James Alexander Thurman
6da5b8ccc5 Don't define meta_spew_event unless verbose mode is on.
Closes #571126.
	* src/core/display.c:
	* src/core/window.c:


svn path=/trunk/; revision=4132
2009-02-11 04:34:17 +00:00
Thomas James Alexander Thurman
128e2b917d switch is "--disable-verbose-mode", not "--disable-verbose". Closes
* README: switch is "--disable-verbose-mode", not "--disable-verbose".
          Closes #571210.


svn path=/trunk/; revision=4130
2009-02-11 03:13:33 +00:00
Thomas James Alexander Thurman
2f4173b267 rm incorrect comment
* src/include/util.h:


svn path=/trunk/; revision=4129
2009-02-10 12:51:29 +00:00
Gil Forcada Codinachs
3fea1e4df5 Added Asturian translation on behalf of Mikel González
svn path=/trunk/; revision=4127
2009-02-10 08:33:24 +00:00
Kjartan Maraas
13d2552274 Updated Norwegian bokmål translation.
2009-02-10  Kjartan Maraas  <kmaraas@gnome.org>

	* nb.po: Updated Norwegian bokmål translation.

svn path=/trunk/; revision=4126
2009-02-10 07:06:34 +00:00
Thomas James Alexander Thurman
3d0bfbb4f4 Further movement of code out of metacity-dialog into Zenity;
this time it's the "kill or wait?" dialogue.  Much code saved.
	* src/core/delete.c:
	* src/core/keybindings.c:
	* src/core/main.c:
	* src/core/util.c:
	* src/core/window-private.h:
	* src/core/window.c:
	* src/include/util.h:


svn path=/trunk/; revision=4125
2009-02-10 05:12:53 +00:00
Chao-Hsiung Liao
b893e88e8b 2.27.0
svn path=/trunk/; revision=4124
2009-02-09 00:10:40 +00:00
Thomas James Alexander Thurman
f2be9e4381 Windows demanding attention should never appear in the
alt-tab list unless they're of a type which might have appeared
        there anyway.  This solves a problem under AWN where docks which were
        marked as demanding attention appeared in all alt-tab lists;
        they were irrelevant and it was impossible to remove them from the
        lists.
	* src/core/display.c:


svn path=/trunk/; revision=4123
2009-02-08 00:22:12 +00:00
Thomas James Alexander Thurman
53b5d6d167 some commenting
* src/ui/theme.c: some commenting


svn path=/trunk/; revision=4122
2009-02-07 23:55:39 +00:00
Thomas James Alexander Thurman
92bfe34716 Only skip the first window in the alt-tab chain if it's actually the
* src/core/display.c: Only skip the first window in
        the alt-tab chain if it's actually the current window
        (urgent windows on other workspaces may precede it).
        Fixes #535887.


svn path=/trunk/; revision=4121
2009-02-07 23:05:42 +00:00
Thomas James Alexander Thurman
5df096baf3 Lines where x1==x2 or y1==y2 may have the second element
null.  Lines where both are null, and the width is zero,
        are points.  This speeds things up surprisingly much.
	* src/ui/theme-parser.c:
	* src/ui/theme.c:


svn path=/trunk/; revision=4119
2009-02-06 04:50:50 +00:00
Thomas James Alexander Thurman
45cbaa2d13 incredibly baroque system to make sure the translators don't have to
* src/core/main.c: incredibly baroque system to make sure
        the translators don't have to update the year number every year.


svn path=/trunk/; revision=4118
2009-02-05 20:02:59 +00:00
Thomas James Alexander Thurman
720a17acd7 collapse several strings into one for the translators' benefit.
* src/ui/theme-parser.c: collapse several strings into one
        for the translators' benefit.


svn path=/trunk/; revision=4117
2009-02-05 19:26:06 +00:00
Thomas James Alexander Thurman
dab00ab036 post-branch bump to 2.27.0.
* configure.in: post-branch bump to 2.27.0.


svn path=/trunk/; revision=4116
2009-02-05 01:13:01 +00:00
128 changed files with 36252 additions and 37915 deletions

31
.gitignore vendored
View File

@@ -13,17 +13,22 @@ config.sub
configure
depcomp
install-sh
intltool-extract.in
intltool-merge.in
libtool
ltmain.sh
missing
.deps
src/metacity-wm.desktop
src/mutter-wm.desktop
src/mutter.desktop
*.o
*.a
*.lo
*.la
.libs
*.swp
*.gir
*.typelib
tidy-enum-types.[ch]
tidy-marshal.[ch]
stamp-tidy-enum-types.h
@@ -38,19 +43,18 @@ POTFILES
50-metacity-desktop-key.xml
50-metacity-key.xml
inlinepixbufs.h
libmetacity-private.pc
metacity
metacity-dialog
metacity-theme-viewer
metacity.desktop
metacity.schemas
libmutter-private.pc
mutter
mutter-theme-viewer
mutter.desktop
mutter.schemas
testasyncgetprop
testboxes
testgradient
metacity-grayscale
metacity-mag
metacity-message
metacity-window-demo
mutter-grayscale
mutter-mag
mutter-message
mutter-window-demo
focus-window
test-gravity
test-resizing
@@ -58,3 +62,8 @@ test-size-hints
wm-tester
INSTALL
mkinstalldirs
src/mutter-enum-types.[ch]
src/stamp-mutter-enum-types.h
src/mutter-marshal.[ch]
src/stamp-mutter-marshal.h
src/mutter-plugins.pc

View File

@@ -1,13 +1,13 @@
AC_PREREQ(2.50)
m4_define([mutter_major_version], [2])
m4_define([mutter_minor_version], [27])
m4_define([mutter_micro_version], [4])
m4_define([mutter_minor_version], [91])
m4_define([mutter_micro_version], [0])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
m4_define([mutter_plugin_api_version], [2])
m4_define([mutter_plugin_api_version], [3])
AC_INIT([mutter], [mutter_version],
[http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
@@ -63,68 +63,97 @@ AC_C_BIGENDIAN
#### Warnings
# Stay command-line compatible with the gnome-common configure option. Here
# minimum/yes/maximum are the same, however.
AC_ARG_ENABLE(compile_warnings,
AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],[Turn on compiler warnings]),,
enable_compile_warnings=error)
changequote(,)dnl
if test "x$GCC" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-Wall[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wall" ;;
esac
# case " $CFLAGS " in
# *[\ \ ]-Wshadow[\ \ ]*) ;;
# *) CFLAGS="$CFLAGS -Wshadow" ;;
# esac
case " $CFLAGS " in
*[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wmissing-declarations[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wmissing-prototypes[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wmissing-prototypes" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wnested-externs[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wnested-externs" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wpointer-arith[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wpointer-arith" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wcast-align[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wcast-align" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wsign-compare[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wsign-compare" ;;
esac
if test "x$enable_ansi" = "xyes"; then
if test "$enable_compile_warnings" != no ; then
if test "x$GCC" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-ansi[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -ansi" ;;
*[\ \ ]-Wall[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wall" ;;
esac
# case " $CFLAGS " in
# *[\ \ ]-Wshadow[\ \ ]*) ;;
# *) CFLAGS="$CFLAGS -Wshadow" ;;
# esac
case " $CFLAGS " in
*[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
esac
case " $CFLAGS " in
*[\ \ ]-pedantic[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -pedantic" ;;
*[\ \ ]-Wmissing-declarations[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wmissing-prototypes[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wmissing-prototypes" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wnested-externs[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wnested-externs" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wpointer-arith[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wpointer-arith" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wcast-align[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wcast-align" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wsign-compare[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wsign-compare" ;;
esac
if test "$enable_compile_warnings" = error; then
case " $CFLAGS " in
*[\ \ ]-Werror[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Werror" ;;
esac
fi
fi
fi
changequote([,])dnl
MUTTER_PC_MODULES='gtk+-2.0 >= 2.10.0 pango >= 1.2.0'
AC_MSG_CHECKING([which gtk+ version to compile against])
AC_ARG_WITH([gtk],
AC_HELP_STRING([--with-gtk=2.0|3.0],
[which gtk+ version to compile against (default: 2)]),
[case "$with_gtk" in
2.0|3.0) ;;
*) AC_MSG_ERROR([invalid gtk+ version specified]);;
esac],
[with_gtk=2.0])
AC_MSG_RESULT([$with_gtk])
case "$with_gtk" in
2.0) GTK_API_VERSION=2.0
GTK_MIN_VERSION=2.18
CANBERRA_GTK=libcanberra-gtk
;;
3.0) GTK_API_VERSION=3.0
GTK_MIN_VERSION=2.90
CANBERRA_GTK=libcanberra-gtk3
AC_DEFINE(USE_CAIRO_REGION, 1, [Use cairo_region_t instead of GdkRegion])
;;
esac
AM_CONDITIONAL(INSTALL_LIBMUTTER_PRIVATE, test "$with_gtk" = "3.0")
MUTTER_PC_MODULES="gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION pango >= 1.2.0"
AC_SUBST(GTK_API_VERSION)
AC_ARG_ENABLE(gconf,
AC_HELP_STRING([--disable-gconf],
@@ -160,6 +189,11 @@ AC_ARG_WITH(introspection,
[disable the use of GObject introspection]),,
with_introspection=auto)
AC_ARG_WITH(libcanberra,
AC_HELP_STRING([--without-libcanberra],
[disable the use of libcanberra for playing sounds]),,
with_libcanberra=auto)
AC_ARG_ENABLE(xsync,
AC_HELP_STRING([--disable-xsync],
[disable mutter's use of the XSync extension]),,
@@ -176,11 +210,11 @@ AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
AM_GLIB_GNU_GETTEXT
## here we get the flags we'll actually use
# GOptionEntry requires glib-2.6.0
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.6.0)
# GRegex requires Glib-2.14.0
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
# gtk_window_set_icon_name requires gtk2+-2.6.0
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-2.0 >= 2.6.0)
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-2.0 >= 2.6.0)
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION)
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-$GTK_API_VERSION >= $GTK_MIN_VERSION)
# Unconditionally use this dir to avoid a circular dep with gnomecc
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
@@ -212,6 +246,24 @@ else
echo "Building without libstartup-notification"
fi
have_libcanberra=no
AC_MSG_CHECKING([libcanberra-gtk])
if test x$with_libcanberra = xno ; then
AC_MSG_RESULT([disabled])
else
if $PKG_CONFIG --exists $CANBERRA_GTK; then
have_libcanberra=yes
AC_MSG_RESULT(yes)
MUTTER_PC_MODULES="$MUTTER_PC_MODULES $CANBERRA_GTK"
AC_DEFINE([HAVE_LIBCANBERRA], 1, [Building with libcanberra for playing sounds])
else
AC_MSG_RESULT(no)
if test x$with_libcanberra = xyes ; then
AC_MSG_ERROR([libcanberra forced and libcanberra-gtk was not found])
fi
fi
fi
XCOMPOSITE_VERSION=0.2
AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION])
@@ -226,7 +278,7 @@ else
AC_MSG_ERROR([no. Mutter requires the Xcomposite extension to build.])
fi
CLUTTER_VERSION=1.0.0
CLUTTER_VERSION=1.2.0
CLUTTER_PACKAGE=clutter-1.0
AC_SUBST(CLUTTER_PACKAGE)
if $PKG_CONFIG --atleast-version $CLUTTER_VERSION $CLUTTER_PACKAGE ; then
@@ -251,7 +303,7 @@ else
fi
if test x$with_introspection != xno; then
PKG_CHECK_MODULES(INTROSPECTION, gobject-introspection-1.0, have_introspection=yes, have_introspection=no)
PKG_CHECK_MODULES(INTROSPECTION, gobject-introspection-1.0 >= 0.9.5, have_introspection=yes, have_introspection=no)
if test x$have_introspection=xyes; then
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gobject-introspection-1.0"
AC_DEFINE(HAVE_INTROSPECTION, 1, [Define if GObject introspection is available])
@@ -414,7 +466,7 @@ fi
MUTTER_LIBS="$MUTTER_LIBS $XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
MUTTER_MESSAGE_LIBS="$MUTTER_MESSAGE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
MUTTER_WINDOW_DEMO_LIBS="$MUTTER_WINDOW_DEMO_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
MUTTER_WINDOW_DEMO_LIBS="$MUTTER_WINDOW_DEMO_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
MUTTER_PROPS_LIBS="$MUTTER_PROPS_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
found_sm=no
@@ -482,10 +534,8 @@ if test "x$enable_debug" = "xyes"; then
CFLAGS="$CFLAGS -g -O"
fi
# Warnings are there for a reason
if test "x$GCC" = "xyes"; then
CFLAGS="$CFLAGS -Wall -Werror -ansi"
fi
# For fix-meta-rectangle.py
AM_PATH_PYTHON([2.5])
# Use gnome-doc-utils:
GNOME_DOC_INIT([0.8.0])
@@ -522,7 +572,7 @@ fi
dnl ==========================================================================
echo "
mutter-$VERSION:
mutter-$VERSION (using gtk+-${GTK_API_VERSION}):
prefix: ${prefix}
source code location: ${srcdir}
@@ -532,6 +582,7 @@ mutter-$VERSION:
XFree86 Xinerama: ${use_xfree_xinerama}
Solaris Xinerama: ${use_solaris_xinerama}
Startup notification: ${have_startup_notification}
libcanberra: ${have_libcanberra}
Introspection: ${have_introspection}
Session management: ${found_sm}
Shape extension: ${found_shape}

View File

@@ -4,6 +4,7 @@ of the theme format, and a given theme can support more than one format.
Version 1: THEMEDIR/metacity-1/metacity-theme-1.xml
(original metacity format)
Version 2: THEMEDIR/metacity-1/metacity-theme-2.xml
Version 3: THEMEDIR/metacity-1/metacity-theme-3.xml
The subdirectory name is "metacity-1" in all versions.
@@ -21,6 +22,41 @@ This document has separate sections for each format version. You may
want to read the document in reverse order, since the base features
are discussed under version 1.
New Features in Theme Format Version 3.1
========================================
Additional predefined variables are added for positioning expressions:
frame_x_center: the X center of the entire frame, with respect to the
piece currently being drawn.
frame_y_center: the Y center of the entire frame, with respect to the
piece currently being drawn.
The <title/> element now supports an "ellipsize_width" attribute. When
specified, this gives a width at which to ellipsize the title. If not
specified, the title will simply be clipped to the title area.
New Features in Theme Format Version 3
======================================
Format version 3 has exactly one new feature; any element in the file
can now have a version attribute:
version="[<|<=|=>|>] MAJOR.MINOR"
(< and > should be to be entity escaped as &lt; and &gt;). If this
version check is not met, then the element and its children will be
ignored. This allows having alternate sections of the theme file for
older and newer version of the Metacity theme format.
When placed on the toplevel <metacity_theme> element, an unsatisfied
version check will not just cause the contents of the file to be
ignored, it will also cause the lookup of a theme file to proceed on
and look for an older format 2 or format 1 file. This allows making a
metacity-theme-3.xml file that is only used the format version 3.2 or
newer is supported, and using metacity-theme-1.xml for older window
managers.
New Features in Theme Format Version 2
======================================

View File

@@ -10,6 +10,7 @@ be@latin
bg
bn
bn_IN
br
bs
ca
ca@valencia
@@ -56,6 +57,7 @@ mn
mr
ms
nb
nds
ne
nl
nn

View File

@@ -1,5 +1,6 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
src/core/bell.c
src/core/core.c
src/core/delete.c
src/core/display.c

4989
po/ar.po

File diff suppressed because it is too large Load Diff

1815
po/ast.po

File diff suppressed because it is too large Load Diff

1483
po/bg.po

File diff suppressed because it is too large Load Diff

1835
po/br.po Normal file

File diff suppressed because it is too large Load Diff

1440
po/cs.po

File diff suppressed because it is too large Load Diff

1859
po/da.po

File diff suppressed because it is too large Load Diff

3278
po/de.po

File diff suppressed because it is too large Load Diff

1485
po/el.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

749
po/es.po

File diff suppressed because it is too large Load Diff

336
po/eu.po
View File

@@ -3,14 +3,14 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER.
#
# Hizkuntza Politikarako Sailburuordetza <hizpol@ej-gv.es>, 2004.
# Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>, 2004, 2005, 2006, 2008, 2009.
# Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>, 2004, 2005, 2006, 2008, 2009, 2010.
# Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: eu\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-09-04 11:40+0200\n"
"PO-Revision-Date: 2009-09-04 11:56+0200\n"
"POT-Creation-Date: 2010-03-19 17:23+0100\n"
"PO-Revision-Date: 2010-03-19 17:27+0100\n"
"Last-Translator: Iñaki Larrañaga Murgoitio <dooteo@euskalgnu.org>\n"
"Language-Team: Basque <itzulpena@euskalgnu.org>\n"
"MIME-Version: 1.0\n"
@@ -20,48 +20,53 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"\n"
#: ../src/core/bell.c:302
msgid "Bell event"
msgstr "Soinuaren gertaera"
#: ../src/core/core.c:213
#, c-format
msgid "Unknown window information request: %d"
msgstr "Leihoaren informazio eskaera ezezaguna: %d"
#: ../src/core/delete.c:105
#. Translators: %s is a window title
#: ../src/core/delete.c:95
#, c-format
msgid ""
"<big><b><tt>%s</tt> is not responding.</b></big>\n"
"\n"
"<i>You may choose to wait a short while for it to continue or force the "
"application to quit entirely.</i>"
msgstr ""
"<big><b><tt>%s</tt>(e)k ez du erantzuten.</b></big>\n"
"\n"
"<i>Aukeratu piskatean zai egotea aplikazioak jarraitzeko edo derrigortu "
"aplikazioa erabat ixtea.</i>"
msgid "<tt>%s</tt> is not responding."
msgstr "<tt>%s</tt>(e)k ez du erantzuten."
#: ../src/core/delete.c:116
#: ../src/core/delete.c:100
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
"Aukeratu piskatean zai egotea aplikazioak jarraitzeko edo derrigortu "
"aplikazioa erabat ixtea."
#: ../src/core/delete.c:109
msgid "_Wait"
msgstr "_Itxaron"
#: ../src/core/delete.c:116
#: ../src/core/delete.c:109
msgid "_Force Quit"
msgstr "_Behartu ixtera"
#: ../src/core/delete.c:217
#: ../src/core/delete.c:207
#, c-format
msgid "Failed to get hostname: %s\n"
msgstr "Huts egin du ostalari-izena hartzean: %s\n"
#: ../src/core/display.c:329
#: ../src/core/display.c:362
#, c-format
msgid "Missing %s extension required for compositing"
msgstr "Konposaketa lantzeko beharrezkoa den %s hedapena falta da"
#: ../src/core/display.c:414
#: ../src/core/display.c:447
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Huts egin du X Window sistemaren '%s' pantaila irekitzean\n"
#: ../src/core/errors.c:236
#: ../src/core/errors.c:233
#, c-format
msgid ""
"Lost connection to the display '%s';\n"
@@ -72,12 +77,12 @@ msgstr ""
"seguru asko X zerbitzaria itzalita egongo da edo leiho-kudeatzailea \n"
"hilko/hondatuko zenuen.\n"
#: ../src/core/errors.c:243
#: ../src/core/errors.c:240
#, c-format
msgid "Fatal IO error %d (%s) on display '%s'.\n"
msgstr "S/Iko %d (%s) errore konponezina '%s' pantailan.\n"
#: ../src/core/keybindings.c:697
#: ../src/core/keybindings.c:708
#, c-format
msgid ""
"Some other program is already using the key %s with modifiers %x as a "
@@ -89,7 +94,7 @@ msgstr ""
#. Displayed when a keybinding which is
#. * supposed to launch a program fails.
#.
#: ../src/core/keybindings.c:2392
#: ../src/core/keybindings.c:2399
#, c-format
msgid ""
"There was an error running <tt>%s</tt>:\n"
@@ -100,92 +105,96 @@ msgstr ""
"\n"
"%s"
#: ../src/core/keybindings.c:2482
#: ../src/core/keybindings.c:2489
#, c-format
msgid "No command %d has been defined.\n"
msgstr "%d komandoa ez dago definituta.\n"
#: ../src/core/keybindings.c:3495
#: ../src/core/keybindings.c:3502
#, c-format
msgid "No terminal command has been defined.\n"
msgstr "Ez da terminalaren komandoa definitu.\n"
#: ../src/core/main.c:127
#: ../src/core/main.c:130
#, c-format
msgid ""
"mutter %s\n"
"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"This is free software; see the source for copying conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
"PARTICULAR PURPOSE.\n"
msgstr ""
"mutter %s\n"
"Copyright-a (C) 2001-2008 Havoc Pennington, Red Hat, Inc., eta beste batzuk\n"
"Copyright-a (C) 2001-%d Havoc Pennington, Red Hat, Inc., eta beste batzuk\n"
"Hau software librea da; ikus kopiatzeko baldintzak iturburu-kodean.\n"
"EZ du bermerik; ezta MERKATURATZEKO edo XEDE JAKIN BATERAKO EGOKITASUNAREN "
"BERMERIK ERE.\n"
#: ../src/core/main.c:257
#: ../src/core/main.c:261
msgid "Disable connection to session manager"
msgstr "Desgaitu saio-kudeatzailearen konexioa"
#: ../src/core/main.c:263
#: ../src/core/main.c:267
msgid "Replace the running window manager with Mutter"
msgstr "Ordeztu exekutatzen dagoen leiho-kudeatzailea Mutter-rekin"
#: ../src/core/main.c:269
#: ../src/core/main.c:273
msgid "Specify session management ID"
msgstr "Zehaztu saio-kudeatzailearen IDa"
#: ../src/core/main.c:274
#: ../src/core/main.c:278
msgid "X Display to use"
msgstr "X pantaila erabiltzeko"
#: ../src/core/main.c:280
#: ../src/core/main.c:284
msgid "Initialize session from savefile"
msgstr "Hasieratu saioa babes-fitxategitik"
#: ../src/core/main.c:286
#: ../src/core/main.c:290
msgid "Print version"
msgstr "Erakutsi bertsioa"
#: ../src/core/main.c:292
#: ../src/core/main.c:296
msgid "Make X calls synchronous"
msgstr "Egin X deiak sinkronoak izatea"
#: ../src/core/main.c:298
#: ../src/core/main.c:302
msgid "Turn compositing on"
msgstr "Aktibatu konposaketa"
#: ../src/core/main.c:304
#: ../src/core/main.c:308
msgid "Turn compositing off"
msgstr "Desaktibatu konposaketa"
#: ../src/core/main.c:310
#: ../src/core/main.c:314
msgid "Don't make fullscreen windows that are maximized and have no decorations"
msgstr "Ez jarri pantaila osoan maximizatuta dauden eta dekoraziorik ez duten leihoak"
#: ../src/core/main.c:320
msgid "Comma-separated list of compositor plugins"
msgstr "Konpositoreen pluginen komaz bereiztutako zerrenda"
#: ../src/core/main.c:316
#: ../src/core/main.c:326
msgid "Whether window popup/frame should be shown when cycling windows."
msgstr "Leihoak begiztan sartzean laster-leihoak/-markoak erakutsiko diren edo ez."
#: ../src/core/main.c:323
#: ../src/core/main.c:333
msgid "Internal argument for GObject introspection"
msgstr "Barneko argumentua GObject objektua aztertzeko"
#: ../src/core/main.c:668
#: ../src/core/main.c:663
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Huts egin du gaien direktorioa aztertzean: %s\n"
#: ../src/core/main.c:684
#: ../src/core/main.c:679
#, c-format
msgid "Could not find a theme! Be sure %s exists and contains the usual themes.\n"
msgstr ""
"Gai bat ezin izan da aurkitu. Ziurtatu %s badagoela eta ohiko gaiak "
"dituela.\n"
#: ../src/core/main.c:745
#: ../src/core/main.c:743
#, c-format
msgid "Failed to restart: %s\n"
msgstr "Ezin izan da berrabiarazi: %s\n"
@@ -201,24 +210,24 @@ msgstr "Ezin izan da berrabiarazi: %s\n"
#. * (Empty comment follows so the translators don't see this.)
#.
#.
#: ../src/core/prefs.c:522 ../src/core/prefs.c:683
#: ../src/core/prefs.c:529 ../src/core/prefs.c:690
#, c-format
msgid "GConf key '%s' is set to an invalid value\n"
msgstr "\"%s\" GConf gakoa balio baliogabean ezarrita dago\n"
#: ../src/core/prefs.c:609 ../src/core/prefs.c:852
#: ../src/core/prefs.c:616 ../src/core/prefs.c:859
#, c-format
msgid "%d stored in GConf key %s is out of range %d to %d\n"
msgstr "%2$s GConf gakoko %1$d balioa %3$d - %4$d barrutitik kanpo dago\n"
#: ../src/core/prefs.c:653 ../src/core/prefs.c:730 ../src/core/prefs.c:778
#: ../src/core/prefs.c:842 ../src/core/prefs.c:1142 ../src/core/prefs.c:1158
#: ../src/core/prefs.c:1175 ../src/core/prefs.c:1191
#: ../src/core/prefs.c:660 ../src/core/prefs.c:737 ../src/core/prefs.c:785
#: ../src/core/prefs.c:849 ../src/core/prefs.c:1149 ../src/core/prefs.c:1165
#: ../src/core/prefs.c:1182 ../src/core/prefs.c:1198
#, c-format
msgid "GConf key \"%s\" is set to an invalid type\n"
msgstr "\"%s\" GConf gakoa mota baliogabean ezarrita dago\n"
#: ../src/core/prefs.c:1282
#: ../src/core/prefs.c:1289
msgid ""
"Workarounds for broken applications disabled. Some applications may not "
"behave properly.\n"
@@ -226,12 +235,12 @@ msgstr ""
"Aplikazio hautsien konponbidea desgaituta. Aplikazio batzuk ez dira behar "
"den bezala ibiliko.\n"
#: ../src/core/prefs.c:1353
#: ../src/core/prefs.c:1360
#, c-format
msgid "Could not parse font description \"%s\" from GConf key %s\n"
msgstr "Ezin izan da analizatu \"%s\" letra-tipoaren deskribapena %s GConf gakoan\n"
#: ../src/core/prefs.c:1415
#: ../src/core/prefs.c:1422
#, c-format
msgid ""
"\"%s\" found in configuration database is not a valid value for mouse button "
@@ -240,17 +249,17 @@ msgstr ""
"Konfigurazioaren datu-basean aurkitutako \"%s\" balioa ez da baliozkoa sagu-"
"botoiaren aldatzailearentzat\n"
#: ../src/core/prefs.c:1839
#: ../src/core/prefs.c:1849
#, c-format
msgid "Error setting number of workspaces to %d: %s\n"
msgstr "Errorea laneko %d area ezartzean: %s\n"
#: ../src/core/prefs.c:2023 ../src/core/prefs.c:2529
#: ../src/core/prefs.c:2028 ../src/core/prefs.c:2531
#, c-format
msgid "Workspace %d"
msgstr "%d. laneko area"
#: ../src/core/prefs.c:2056 ../src/core/prefs.c:2234
#: ../src/core/prefs.c:2061 ../src/core/prefs.c:2239
#, c-format
msgid ""
"\"%s\" found in configuration database is not a valid value for keybinding "
@@ -259,37 +268,37 @@ msgstr ""
"Konfigurazioaren datu-basean aurkitutako \"%s\" balioa ez da baliozkoa \"%s"
"\" laster-teklarentzat.\n"
#: ../src/core/prefs.c:2610
#: ../src/core/prefs.c:2612
#, c-format
msgid "Error setting name for workspace %d to \"%s\": %s\n"
msgstr "Errorea %d. laneko areari \"%s\" izena ezartzean: %s\n"
#: ../src/core/prefs.c:2808
#: ../src/core/prefs.c:2816
#, c-format
msgid "Error setting compositor status: %s\n"
msgstr "Errorea konposaketaren egoera ezartzean: %s\n"
#: ../src/core/prefs.c:2836
#: ../src/core/prefs.c:2845
#, c-format
msgid "Error setting clutter plugin list: %s\n"
msgstr "Errorea 'clutter' pluginen zerrenda ezartzean: %s\n"
#: ../src/core/prefs.c:2879
#: ../src/core/prefs.c:2889
#, c-format
msgid "Error setting live hidden windows status status: %s\n"
msgstr "Errorea ezkutuko leihoen bizitzen egoera ezartzean: %s\n"
#: ../src/core/prefs.c:2907
#: ../src/core/prefs.c:2917
#, c-format
msgid "Error setting no tab popup status: %s\n"
msgstr "Errorea fitxarik gabeko laster-leihoen egoera ezartzean: %s\n"
#: ../src/core/screen.c:561
#: ../src/core/screen.c:577
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "'%2$s' bistaratzeko %1$d pantaila ez da baliozkoa\n"
#: ../src/core/screen.c:577
#: ../src/core/screen.c:593
#, c-format
msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
@@ -298,77 +307,71 @@ msgstr ""
"\"%2$s\" bistaratzeko %1$d pantailak badu leiho-kudeatzailea; leiho-"
"kudeatzaile hori ordeztu nahi baduzu, saiatu --replace aukerarekin.\n"
#: ../src/core/screen.c:604
#: ../src/core/screen.c:620
#, c-format
msgid "Could not acquire window manager selection on screen %d display \"%s\"\n"
msgstr ""
"Ezin izan da eskuratu leiho-kudeatzailearen hautapena \"%2$s\" bistaratzeko %"
"1$d pantailan\n"
#: ../src/core/screen.c:659
#: ../src/core/screen.c:675
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "\"%2$s\" bistaratzeko %1$d pantailak badu leiho-kudeatzailea\n"
#: ../src/core/screen.c:871
#: ../src/core/screen.c:857
#, c-format
msgid "Could not release screen %d on display \"%s\"\n"
msgstr "Ezin izan da askatu \"%2$s\" bistaratzeko %1$d pantaila\n"
#: ../src/core/session.c:851 ../src/core/session.c:858
#: ../src/core/session.c:856 ../src/core/session.c:863
#, c-format
msgid "Could not create directory '%s': %s\n"
msgstr "Ezin izan da '%s' direktorioa sortu: %s\n"
#: ../src/core/session.c:868
#: ../src/core/session.c:873
#, c-format
msgid "Could not open session file '%s' for writing: %s\n"
msgstr "Ezin izan da '%s' saio-fitxategia idazteko ireki: %s\n"
#: ../src/core/session.c:1009
#: ../src/core/session.c:1014
#, c-format
msgid "Error writing session file '%s': %s\n"
msgstr "Errorea '%s' saio-fitxategia idaztean: %s\n"
#: ../src/core/session.c:1014
#: ../src/core/session.c:1019
#, c-format
msgid "Error closing session file '%s': %s\n"
msgstr "Errorea '%s' saio-fitxategia ixtean: %s\n"
#. oh, just give up
#: ../src/core/session.c:1107
#, c-format
msgid "Failed to read saved session file %s: %s\n"
msgstr "Huts egin du gordetako %s saio-fitxategia irakurtzean: %s\n"
#: ../src/core/session.c:1146
#: ../src/core/session.c:1149
#, c-format
msgid "Failed to parse saved session file: %s\n"
msgstr "Huts egin du gordetako saio-fitxategia analizatzean: %s\n"
#: ../src/core/session.c:1195
#: ../src/core/session.c:1198
#, c-format
msgid "<mutter_session> attribute seen but we already have the session ID"
msgstr "<mutter_session> atributua ikusi da baina dagoeneko badugu saio-IDa"
#: ../src/core/session.c:1208 ../src/core/session.c:1283
#: ../src/core/session.c:1315 ../src/core/session.c:1387
#: ../src/core/session.c:1447
#: ../src/core/session.c:1211 ../src/core/session.c:1286
#: ../src/core/session.c:1318 ../src/core/session.c:1390
#: ../src/core/session.c:1450
#, c-format
msgid "Unknown attribute %s on <%s> element"
msgstr "%s atributu ezezaguna <%s> elementuan"
#: ../src/core/session.c:1225
#: ../src/core/session.c:1228
#, c-format
msgid "nested <window> tag"
msgstr "<window> etiketa habiaratua"
#: ../src/core/session.c:1467
#: ../src/core/session.c:1470
#, c-format
msgid "Unknown element %s"
msgstr "%s elementu ezezaguna"
#: ../src/core/session.c:1818
#: ../src/core/session.c:1822
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
@@ -376,51 +379,51 @@ msgstr ""
"Leiho hauek ez dute onartzen &quot;gorde uneko konfigurazioa&quot; eta eskuz "
"berrabiarazi beharko dituzu hurrengo saioa hasten duzunean."
#: ../src/core/util.c:103
#: ../src/core/util.c:104
#, c-format
msgid "Failed to open debug log: %s\n"
msgstr "Huts egin du arazketako egunkaria irekitzean: %s\n"
#: ../src/core/util.c:113
#: ../src/core/util.c:114
#, c-format
msgid "Failed to fdopen() log file %s: %s\n"
msgstr "Huts egin du %s egunkari-fitxategian fdopen() egitean: %s\n"
#: ../src/core/util.c:119
#: ../src/core/util.c:120
#, c-format
msgid "Opened log file %s\n"
msgstr "%s egunkari-fitxategia irekita\n"
#: ../src/core/util.c:138 ../src/tools/mutter-message.c:176
#: ../src/core/util.c:139 ../src/tools/mutter-message.c:176
#, c-format
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter modu xehatuaren euskarririk gabe konpilatu da\n"
#: ../src/core/util.c:238
#: ../src/core/util.c:239
msgid "Window manager: "
msgstr "Leiho-kudeatzailea: "
#: ../src/core/util.c:390
#: ../src/core/util.c:391
msgid "Bug in window manager: "
msgstr "Akatsa leiho-kudeatzailean: "
#: ../src/core/util.c:423
#: ../src/core/util.c:424
msgid "Window manager warning: "
msgstr "Leiho-kudeatzailearen abisua: "
#: ../src/core/util.c:451
#: ../src/core/util.c:452
msgid "Window manager error: "
msgstr "Leiho-kudeatzailearen errorea: "
#. Translators: This is the title used on dialog boxes
#. eof all-keybindings.h
#: ../src/core/util.c:570 ../src/mutter.desktop.in.h:1
#: ../src/core/util.c:573 ../src/mutter.desktop.in.h:1
#: ../src/mutter-wm.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#. first time through
#: ../src/core/window.c:6086
#: ../src/core/window.c:6217
#, c-format
msgid ""
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
@@ -436,7 +439,7 @@ msgstr ""
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
#. * about these apps but make them work.
#.
#: ../src/core/window.c:6749
#: ../src/core/window.c:6880
#, c-format
msgid ""
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size %"
@@ -456,7 +459,7 @@ msgstr "Aplikazioak _NET_WM_PID %lu faltsua ezarri du\n"
msgid "%s (on %s)"
msgstr "%s (%s)"
#: ../src/core/window-props.c:1419
#: ../src/core/window-props.c:1435
#, c-format
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
msgstr "%2$s(e)n baliogabeko WM_TRANSIENT_FOR 0x%1$lx leihoa zehaztu da.\n"
@@ -476,12 +479,12 @@ msgstr ""
"Gehiago ematen du aplikazioaren akatsa leiho-kudeatzailearena baino.\n"
"Leihoak title=\"%s\" class=\"%s\" name=\"%s\" du\n"
#: ../src/core/xprops.c:401
#: ../src/core/xprops.c:411
#, c-format
msgid "Property %s on window 0x%lx contained invalid UTF-8\n"
msgstr "0x%2$lx leihoko %1$s propietateak UTF-8 baliogabea du\n"
#: ../src/core/xprops.c:484
#: ../src/core/xprops.c:494
#, c-format
msgid "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"
msgstr ""
@@ -804,7 +807,9 @@ msgstr "Clutter pluginak"
msgid ""
"Determines whether hidden windows (i.e., minimized windows and windows on "
"other workspaces than the current one) should be kept alive."
msgstr "Ezkutuko leihoak (adib. ikonotutakoak, beste laneko arekoak) bizirik iraungo diren edo ez zehazten du."
msgstr ""
"Ezkutuko leihoak (adib. ikonotutakoak, beste laneko arekoak) bizirik iraungo "
"diren edo ez zehazten du."
#: ../src/mutter.schemas.in.h:3
msgid "Live Hidden Windows"
@@ -816,7 +821,9 @@ msgstr "Aldatzailea leihoak kudeatzeko eragiketa hedatuetan erabiltzeko"
#: ../src/mutter.schemas.in.h:5
msgid "Plugins to load for the Clutter-based compositing manager."
msgstr "Kargatuko diren puginak Clutter-en oinarritutako konposaketa-kudeatzailearentzako"
msgstr ""
"Kargatuko diren puginak Clutter-en oinarritutako konposaketa-"
"kudeatzailearentzako"
#: ../src/mutter.schemas.in.h:6
msgid ""
@@ -825,8 +832,8 @@ msgid ""
"\"Windows key\" on PC hardware. It's expected that this binding either the "
"default or set to the empty string."
msgstr ""
"Gako honek \"overlay\" (gainjarria) hasieratuko du: hau leihoaren "
"ikuspegi orokorraren eta aplikazioa abiarazteko sistemaren arteko konbinazioa da. "
"Gako honek \"overlay\" (gainjarria) hasieratuko du: hau leihoaren ikuspegi "
"orokorraren eta aplikazioa abiarazteko sistemaren arteko konbinazioa da. "
"Lehenetsi gisa, PC ordenagailuko \"Windows tekla\" da. Tekla konbinazio hau "
"lehenetsia izatea edo kate hutz gisa ezartzea da."
@@ -1289,7 +1296,7 @@ msgstr "Koordenatuen adierazpenak ez dirudi eragilerik edo eragigairik duenik"
msgid "Theme contained an expression that resulted in an error: %s\n"
msgstr "Gaiak errorea ematen duen adierazpen bat dauka: %s\n"
#: ../src/ui/theme.c:4187
#: ../src/ui/theme.c:4203
#, c-format
msgid ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
@@ -1298,23 +1305,23 @@ msgstr ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> zehaztu behar "
"da marko-estilo honetan"
#: ../src/ui/theme.c:4695 ../src/ui/theme.c:4720
#: ../src/ui/theme.c:4711 ../src/ui/theme.c:4736
#, c-format
msgid "Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr "<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> falta da"
#: ../src/ui/theme.c:4764
#: ../src/ui/theme.c:4780
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Huts egin du \"%s\" gaia kargatzean: %s\n"
#: ../src/ui/theme.c:4894 ../src/ui/theme.c:4901 ../src/ui/theme.c:4908
#: ../src/ui/theme.c:4915 ../src/ui/theme.c:4922
#: ../src/ui/theme.c:4910 ../src/ui/theme.c:4917 ../src/ui/theme.c:4924
#: ../src/ui/theme.c:4931 ../src/ui/theme.c:4938
#, c-format
msgid "No <%s> set for theme \"%s\""
msgstr "<%s> ez da ezarri \"%s\" gaian"
#: ../src/ui/theme.c:4930
#: ../src/ui/theme.c:4946
#, c-format
msgid ""
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
@@ -1323,14 +1330,14 @@ msgstr ""
"Ez da marko-estilorik ezarri set \"%s\" leiho-motarentzat \"%s\" gaian, "
"gehitu <window type=\"%s\" style_set=\"whatever\"/> elementu bat"
#: ../src/ui/theme.c:5383 ../src/ui/theme.c:5445 ../src/ui/theme.c:5508
#: ../src/ui/theme.c:5389 ../src/ui/theme.c:5451 ../src/ui/theme.c:5514
#, c-format
msgid "User-defined constants must begin with a capital letter; \"%s\" does not"
msgstr ""
"Erabiltzaileak definitutako konstanteak maiuskulaz hasi behar du; \"%s\" ez "
"da maiuskulaz hasten"
#: ../src/ui/theme.c:5391 ../src/ui/theme.c:5453 ../src/ui/theme.c:5516
#: ../src/ui/theme.c:5397 ../src/ui/theme.c:5459 ../src/ui/theme.c:5522
#, c-format
msgid "Constant \"%s\" has already been defined"
msgstr "\"%s\" konstantea lehendik definituta dago"
@@ -1449,10 +1456,10 @@ msgid "Window type \"%s\" has already been assigned a style set"
msgstr "\"%s\" leiho-motak dagoeneko esleituta du estilo-multzoa"
#: ../src/ui/theme-parser.c:1229 ../src/ui/theme-parser.c:1293
#: ../src/ui/theme-parser.c:1519 ../src/ui/theme-parser.c:2732
#: ../src/ui/theme-parser.c:2778 ../src/ui/theme-parser.c:2926
#: ../src/ui/theme-parser.c:3118 ../src/ui/theme-parser.c:3156
#: ../src/ui/theme-parser.c:3194 ../src/ui/theme-parser.c:3232
#: ../src/ui/theme-parser.c:1519 ../src/ui/theme-parser.c:2740
#: ../src/ui/theme-parser.c:2786 ../src/ui/theme-parser.c:2934
#: ../src/ui/theme-parser.c:3126 ../src/ui/theme-parser.c:3164
#: ../src/ui/theme-parser.c:3202 ../src/ui/theme-parser.c:3240
#, c-format
msgid "Element <%s> is not allowed below <%s>"
msgstr "Ez da onartzen <%s> elementua <%s>(r)en azpian jartzea"
@@ -1481,108 +1488,108 @@ msgstr "\"%s\" aspektu-erlazioa ezezaguna da"
msgid "Border \"%s\" is unknown"
msgstr "\"%s\" ertza ezezaguna da"
#: ../src/ui/theme-parser.c:1776
#: ../src/ui/theme-parser.c:1784
#, c-format
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
msgstr "Ez dago \"start_angle\" edo \"from\" atributurik <%s> elementuan"
#: ../src/ui/theme-parser.c:1783
#: ../src/ui/theme-parser.c:1791
#, c-format
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
msgstr "Ez dago \"extent_angle\" edo \"to\" atributurik <%s> elementuan"
#: ../src/ui/theme-parser.c:2023
#: ../src/ui/theme-parser.c:2031
#, c-format
msgid "Did not understand value \"%s\" for type of gradient"
msgstr "Gradiente-motan ez da ulertu \"%s\" balioa"
#: ../src/ui/theme-parser.c:2101 ../src/ui/theme-parser.c:2476
#: ../src/ui/theme-parser.c:2109 ../src/ui/theme-parser.c:2484
#, c-format
msgid "Did not understand fill type \"%s\" for <%s> element"
msgstr "Ez da ulertu \"%s\" betetze-mota <%s> elementuan"
#: ../src/ui/theme-parser.c:2268 ../src/ui/theme-parser.c:2351
#: ../src/ui/theme-parser.c:2414
#: ../src/ui/theme-parser.c:2276 ../src/ui/theme-parser.c:2359
#: ../src/ui/theme-parser.c:2422
#, c-format
msgid "Did not understand state \"%s\" for <%s> element"
msgstr "Ez da ulertu \"%s\" egoera <%s> elementuan"
#: ../src/ui/theme-parser.c:2278 ../src/ui/theme-parser.c:2361
#: ../src/ui/theme-parser.c:2286 ../src/ui/theme-parser.c:2369
#, c-format
msgid "Did not understand shadow \"%s\" for <%s> element"
msgstr "Ez da ulertu \"%s\" itzala <%s> elementuan"
#: ../src/ui/theme-parser.c:2288
#: ../src/ui/theme-parser.c:2296
#, c-format
msgid "Did not understand arrow \"%s\" for <%s> element"
msgstr "Ez da ulertu \"%s\" gezia <%s> elementuan"
#: ../src/ui/theme-parser.c:2588 ../src/ui/theme-parser.c:2684
#: ../src/ui/theme-parser.c:2596 ../src/ui/theme-parser.c:2692
#, c-format
msgid "No <draw_ops> called \"%s\" has been defined"
msgstr "Ez da \"%s\" izeneko <draw_ops> bat ere definitu"
#: ../src/ui/theme-parser.c:2600 ../src/ui/theme-parser.c:2696
#: ../src/ui/theme-parser.c:2608 ../src/ui/theme-parser.c:2704
#, c-format
msgid "Including draw_ops \"%s\" here would create a circular reference"
msgstr "Hemen \"%s\" draw_ops sartzen bada, erreferentzia zirkularra sortuko da"
#: ../src/ui/theme-parser.c:2811
#: ../src/ui/theme-parser.c:2819
#, c-format
msgid "Unknown position \"%s\" for frame piece"
msgstr "\"%s\" kokaleku ezezaguna markoarentzat"
#: ../src/ui/theme-parser.c:2819
#: ../src/ui/theme-parser.c:2827
#, c-format
msgid "Frame style already has a piece at position %s"
msgstr "Marko-estiloak badu zati bat %s posizioan"
#: ../src/ui/theme-parser.c:2836 ../src/ui/theme-parser.c:2911
#: ../src/ui/theme-parser.c:2844 ../src/ui/theme-parser.c:2919
#, c-format
msgid "No <draw_ops> with the name \"%s\" has been defined"
msgstr "Ez da \"%s\" izeneko <draw_ops> bat ere definitu"
#: ../src/ui/theme-parser.c:2865
#: ../src/ui/theme-parser.c:2873
#, c-format
msgid "Unknown function \"%s\" for button"
msgstr "\"%s\" funtzioa ezezaguna botoiarentzat"
#: ../src/ui/theme-parser.c:2874
#: ../src/ui/theme-parser.c:2882
#, c-format
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
msgstr "\"%s\" botoi-funtzioa ez da existitzen bertsio honetan (%d, %d behar du)"
#: ../src/ui/theme-parser.c:2886
#: ../src/ui/theme-parser.c:2894
#, c-format
msgid "Unknown state \"%s\" for button"
msgstr "\"%s\" egoera ezezaguna botoiarentzat"
#: ../src/ui/theme-parser.c:2894
#: ../src/ui/theme-parser.c:2902
#, c-format
msgid "Frame style already has a button for function %s state %s"
msgstr "Marko-estiloak badu botoi bat %s funtzioan %s egoeran"
#: ../src/ui/theme-parser.c:2965
#: ../src/ui/theme-parser.c:2973
#, c-format
msgid "\"%s\" is not a valid value for focus attribute"
msgstr "\"%s\" ez da baliozko balioa foku-atributuarentzat"
#: ../src/ui/theme-parser.c:2974
#: ../src/ui/theme-parser.c:2982
#, c-format
msgid "\"%s\" is not a valid value for state attribute"
msgstr "\"%s\" ez da baliozko balioa egoera-atributuarentzat"
#: ../src/ui/theme-parser.c:2984
#: ../src/ui/theme-parser.c:2992
#, c-format
msgid "A style called \"%s\" has not been defined"
msgstr "\"%s\" izeneko estiloa ez da definitu"
#: ../src/ui/theme-parser.c:3005 ../src/ui/theme-parser.c:3028
#: ../src/ui/theme-parser.c:3013 ../src/ui/theme-parser.c:3036
#, c-format
msgid "\"%s\" is not a valid value for resize attribute"
msgstr "\"%s\" ez da baliozko balioa tamainaz aldatzeko atributuarentzat"
#: ../src/ui/theme-parser.c:3039
#: ../src/ui/theme-parser.c:3047
#, c-format
msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
@@ -1591,24 +1598,24 @@ msgstr ""
"Ez luke izan behar \"resize\" atributurik <%s> elementuan maximizatutako/"
"bildutako egoerentzat"
#: ../src/ui/theme-parser.c:3053
#: ../src/ui/theme-parser.c:3061
#, c-format
msgid "Should not have \"resize\" attribute on <%s> element for maximized states"
msgstr ""
"Ez luke izan behar \"resize\" atributurik <%s> elementuan maximizatutako "
"egoerentzat"
#: ../src/ui/theme-parser.c:3067 ../src/ui/theme-parser.c:3089
#: ../src/ui/theme-parser.c:3075 ../src/ui/theme-parser.c:3097
#, c-format
msgid "Style has already been specified for state %s resize %s focus %s"
msgstr "Estiloa dagoeneko zehaztu da %s egoeran %s tamaina-aldatzean %s fokuan"
#: ../src/ui/theme-parser.c:3078 ../src/ui/theme-parser.c:3100
#: ../src/ui/theme-parser.c:3086 ../src/ui/theme-parser.c:3108
#, c-format
msgid "Style has already been specified for state %s focus %s"
msgstr "Estiloa dagoeneko zehaztu da %s egoeran %s fokuan"
#: ../src/ui/theme-parser.c:3139
#: ../src/ui/theme-parser.c:3147
msgid ""
"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops "
"attribute and also a <draw_ops> element, or specified two elements)"
@@ -1616,7 +1623,7 @@ msgstr ""
"Ezin dira bi draw_ops izan <piece> elementu batean (gaiak draw_ops atributu "
"bat eta <draw_ops> elementu bat zehaztu ditu, edo bi elementu zehaztu ditu)"
#: ../src/ui/theme-parser.c:3177
#: ../src/ui/theme-parser.c:3185
msgid ""
"Can't have a two draw_ops for a <button> element (theme specified a draw_ops "
"attribute and also a <draw_ops> element, or specified two elements)"
@@ -1624,7 +1631,7 @@ msgstr ""
"Ezin dira bi draw_ops izan <button> elementu batean (gaiak draw_ops atributu "
"bat eta <draw_ops> elementu bat zehaztu ditu, edo bi elementu zehaztu ditu)"
#: ../src/ui/theme-parser.c:3215
#: ../src/ui/theme-parser.c:3223
msgid ""
"Can't have a two draw_ops for a <menu_icon> element (theme specified a "
"draw_ops attribute and also a <draw_ops> element, or specified two elements)"
@@ -1633,76 +1640,63 @@ msgstr ""
"atributu bat eta <draw_ops> elementu bat zehaztu ditu, edo bi elementu "
"zehaztu ditu)"
#: ../src/ui/theme-parser.c:3263
#: ../src/ui/theme-parser.c:3271
#, c-format
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
msgstr "Gaian kanporen dagoen elementuak <metacity_theme> izan behar du, ez <%s>"
#: ../src/ui/theme-parser.c:3283
#: ../src/ui/theme-parser.c:3291
#, c-format
msgid "Element <%s> is not allowed inside a name/author/date/description element"
msgstr "<%s> elementua ez da onartzen name/author/date/description elementuan"
#: ../src/ui/theme-parser.c:3288
#: ../src/ui/theme-parser.c:3296
#, c-format
msgid "Element <%s> is not allowed inside a <constant> element"
msgstr "<%s> elementua ez da onartzen <constant> elementuaren barnean"
#: ../src/ui/theme-parser.c:3300
#: ../src/ui/theme-parser.c:3308
#, c-format
msgid "Element <%s> is not allowed inside a distance/border/aspect_ratio element"
msgstr "<%s> elementua ez da onartzen distance/border/aspect_ratio elementuan"
#: ../src/ui/theme-parser.c:3322
#: ../src/ui/theme-parser.c:3330
#, c-format
msgid "Element <%s> is not allowed inside a draw operation element"
msgstr "<%s> elementua ez da onartzen marrazteko eragiketaren elementuaren barnean"
#: ../src/ui/theme-parser.c:3332 ../src/ui/theme-parser.c:3362
#: ../src/ui/theme-parser.c:3367 ../src/ui/theme-parser.c:3372
#: ../src/ui/theme-parser.c:3340 ../src/ui/theme-parser.c:3370
#: ../src/ui/theme-parser.c:3375 ../src/ui/theme-parser.c:3380
#, c-format
msgid "Element <%s> is not allowed inside a <%s> element"
msgstr "<%s> elementua ez da onartzen <%s> elementuaren barnean"
#: ../src/ui/theme-parser.c:3594
#: ../src/ui/theme-parser.c:3602
msgid "No draw_ops provided for frame piece"
msgstr "Ez da draw_ops-ik eman marko-zatiarentzat"
#: ../src/ui/theme-parser.c:3609
#: ../src/ui/theme-parser.c:3617
msgid "No draw_ops provided for button"
msgstr "Ez da draw_ops-ik eman botoiarentzat"
#: ../src/ui/theme-parser.c:3661
#: ../src/ui/theme-parser.c:3669
#, c-format
msgid "No text is allowed inside element <%s>"
msgstr "Ez da testurik onartzen <%s> elementuaren barnean"
#: ../src/ui/theme-parser.c:3716
msgid "<name> specified twice for this theme"
msgstr "<izena> birritan zehaztu da gai honetan"
#: ../src/ui/theme-parser.c:3724 ../src/ui/theme-parser.c:3736
#: ../src/ui/theme-parser.c:3748 ../src/ui/theme-parser.c:3760
#: ../src/ui/theme-parser.c:3772
#, c-format
msgid "<%s> specified twice for this theme"
msgstr "<%s> birritan zehaztu da gai honetan"
#: ../src/ui/theme-parser.c:3727
msgid "<author> specified twice for this theme"
msgstr "<egilea> birritan zehaztu da gai honetan"
#: ../src/ui/theme-parser.c:3738
msgid "<copyright> specified twice for this theme"
msgstr "<copyright-a> birritan zehaztu da gai honetan"
#: ../src/ui/theme-parser.c:3749
msgid "<date> specified twice for this theme"
msgstr "<data> birritan zehaztu da gai honetan"
#: ../src/ui/theme-parser.c:3760
msgid "<description> specified twice for this theme"
msgstr "<azalpena> birritan zehaztu da gai honetan"
#: ../src/ui/theme-parser.c:4027
#: ../src/ui/theme-parser.c:4040
#, c-format
msgid "Failed to find a valid file for theme %s\n"
msgstr "Huts egin du %s gaiaren fitxategi egokia bilatzean\n"
#: ../src/ui/theme-parser.c:4083
#: ../src/ui/theme-parser.c:4096
#, c-format
msgid "Theme file %s did not contain a root <metacity_theme> element"
msgstr "%s gai-fitxategiak ez du erroko <metacity_theme> elementurik"

3013
po/fr.po

File diff suppressed because it is too large Load Diff

2815
po/gl.po

File diff suppressed because it is too large Load Diff

2841
po/he.po

File diff suppressed because it is too large Load Diff

770
po/hu.po

File diff suppressed because it is too large Load Diff

2181
po/it.po

File diff suppressed because it is too large Load Diff

1667
po/lt.po

File diff suppressed because it is too large Load Diff

903
po/nb.po

File diff suppressed because it is too large Load Diff

1814
po/nds.po Normal file

File diff suppressed because it is too large Load Diff

2016
po/pa.po

File diff suppressed because it is too large Load Diff

3030
po/pl.po

File diff suppressed because it is too large Load Diff

1999
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2118
po/sk.po

File diff suppressed because it is too large Load Diff

2597
po/sl.po

File diff suppressed because it is too large Load Diff

1984
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2076
po/ta.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,11 @@
# Flag build for parallelism; see https://savannah.gnu.org/patch/?6905
.AUTOPARALLEL:
if INSTALL_LIBMUTTER_PRIVATE
lib_LTLIBRARIES = libmutter-private.la
else
noinst_LTLIBRARIES = libmutter-private.la
endif
SUBDIRS=wm-tester tools compositor/plugins
@@ -16,10 +20,6 @@ mutter_built_sources = \
mutter_SOURCES= \
core/async-getprop.c \
core/async-getprop.h \
core/alttabhandler.c \
include/alttabhandler.h \
core/alttabhandlerdefault.c \
include/alttabhandlerdefault.h \
core/bell.c \
core/bell.h \
core/boxes.c \
@@ -32,6 +32,8 @@ mutter_SOURCES= \
compositor/mutter-plugin-manager.c \
compositor/mutter-plugin-manager.h \
compositor/mutter-shaped-texture.c \
compositor/mutter-texture-tower.c \
compositor/mutter-texture-tower.h \
compositor/mutter-window.c \
compositor/mutter-window-private.h \
compositor/mutter-window-group.c \
@@ -41,9 +43,14 @@ mutter_SOURCES= \
compositor/mutter-shaped-texture.h \
compositor/tidy/tidy-texture-frame.c \
compositor/tidy/tidy-texture-frame.h \
gdk-compat.h \
gtk-compat.h \
gdk2-drawing-utils.c \
gdk2-drawing-utils.h \
include/compositor.h \
include/mutter-plugin.h \
include/mutter-window.h \
include/region.h \
include/compositor-mutter.h \
core/constraints.c \
core/constraints.h \
@@ -117,12 +124,12 @@ mutter_SOURCES= \
include/resizepopup.h \
ui/tabpopup.c \
include/tabpopup.h \
ui/tile-preview.c \
include/tile-preview.h \
ui/theme-parser.c \
ui/theme-parser.h \
ui/theme.c \
ui/theme.h \
ui/themewidget.c \
ui/themewidget.h \
ui/ui.c \
include/all-keybindings.h \
$(mutter_built_sources)
@@ -140,6 +147,9 @@ libmutter_private_la_SOURCES= \
include/common.h \
ui/preview-widget.c \
ui/preview-widget.h \
include/region.h \
gdk2-drawing-utils.c \
gdk2-drawing-utils.h \
ui/theme-parser.c \
ui/theme-parser.h \
ui/theme.c \
@@ -148,12 +158,9 @@ libmutter_private_la_SOURCES= \
libmutter_private_la_LDFLAGS = -no-undefined
libmutter_private_la_LIBADD = @MUTTER_LIBS@
libmutterincludedir = $(includedir)/mutter/mutter-private
# Headers installed for plugins; introspected information will
# be extracted into Mutter-<version>.gir
libmutterinclude_base_headers = \
include/alttabhandler.h \
include/boxes.h \
ui/gradient.h \
include/main.h \
@@ -180,11 +187,20 @@ libmutterinclude_base_headers = \
# atomnames.h: macros cause problems for scanning process
libmutterinclude_extra_headers = \
ui/preview-widget.h \
include/atomnames.h
include/atomnames.h \
include/region.h
if INSTALL_LIBMUTTER_PRIVATE
libmutterincludedir = $(includedir)/mutter/mutter-private
libmutterinclude_HEADERS = \
$(libmutterinclude_base_headers) \
$(libmutterinclude_extra_headers)
else
noinst_HEADERS = \
$(libmutterinclude_base_headers) \
$(libmutterinclude_extra_headers)
endif
mutter_theme_viewer_SOURCES= \
ui/theme-viewer.c
@@ -205,20 +221,25 @@ typelib_DATA = Meta-$(api_version).typelib
# We need to strip out the attribute that would point back to libmutter-introspect
# so that libgirepository looks for symbols in the executable instead
Meta-$(api_version).gir: $(G_IR_SCANNER) mutter $(libmutterinclude_HEADERS) $(mutter_SOURCES)
Meta-$(api_version).gir: $(G_IR_SCANNER) mutter $(libmutterinclude_HEADERS) $(mutter_SOURCES) Makefile
$(AM_V_GEN) pwd=`pwd` ; \
cd $(srcdir) && \
$(G_IR_SCANNER) \
--namespace=Meta \
--nsversion=$(api_version) \
--warn-all \
--warn-error \
--accept-unprefixed \
--include=GObject-2.0 \
--include=Gdk-2.0 \
--include=Gtk-2.0 \
--include=Gdk-@GTK_API_VERSION@ \
--include=Gtk-@GTK_API_VERSION@ \
--include=Clutter-1.0 \
--pkg=clutter-1.0 \
--pkg=gtk+-2.0 \
--pkg=gtk+-@GTK_API_VERSION@ \
--include=xlib-2.0 \
--include=xfixes-4.0 \
--program=$$pwd/mutter \
mutter-enum-types.h \
$(filter %.c,$(mutter_SOURCES)) \
$(libmutterinclude_base_headers) \
$(INCLUDES) \
@@ -289,9 +310,11 @@ CLEANFILES = \
inlinepixbufs.h: $(IMAGES)
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
if INSTALL_LIBMUTTER_PRIVATE
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libmutter-private.pc mutter-plugins.pc
endif
EXTRA_DIST=$(desktopfiles_files) \
$(wmproperties_files) \

View File

@@ -33,59 +33,6 @@ composite_at_least_version (MetaDisplay *display, int maj, int min)
return (major > maj || (major == maj && minor >= min));
}
static MutterWindow*
find_window_for_screen (MetaScreen *screen, Window xwindow)
{
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
if (info == NULL)
return NULL;
return g_hash_table_lookup (info->windows_by_xid,
(gpointer) xwindow);
}
static MutterWindow *
find_window_in_display (MetaDisplay *display, Window xwindow)
{
GSList *index;
MetaWindow *window = meta_display_lookup_x_window (display, xwindow);
if (window)
{
void *priv = meta_window_get_compositor_private (window);
if (priv)
return priv;
}
for (index = meta_display_get_screens (display);
index;
index = index->next)
{
MutterWindow *cw = find_window_for_screen (index->data, xwindow);
if (cw != NULL)
return cw;
}
return NULL;
}
static MutterWindow *
find_window_for_child_window_in_display (MetaDisplay *display, Window xwindow)
{
Window ignored1, *ignored2, parent;
guint ignored_children;
XQueryTree (meta_display_get_xdisplay (display), xwindow, &ignored1,
&parent, &ignored2, &ignored_children);
if (parent != None)
return find_window_in_display (display, parent);
return NULL;
}
static void sync_actor_stacking (GList *windows);
static void
@@ -144,9 +91,15 @@ add_win (MetaWindow *window)
static void
process_damage (MetaCompositor *compositor,
XDamageNotifyEvent *event)
XDamageNotifyEvent *event,
MetaWindow *window)
{
MutterWindow *cw = find_window_in_display (compositor->display, event->drawable);
MutterWindow *cw;
if (window == NULL)
return;
cw = MUTTER_WINDOW (meta_window_get_compositor_private (window));
if (cw == NULL)
return;
@@ -156,10 +109,15 @@ process_damage (MetaCompositor *compositor,
#ifdef HAVE_SHAPE
static void
process_shape (MetaCompositor *compositor,
XShapeEvent *event)
XShapeEvent *event,
MetaWindow *window)
{
MutterWindow *cw = find_window_in_display (compositor->display,
event->window);
MutterWindow *cw;
if (window == NULL)
return;
cw = MUTTER_WINDOW (meta_window_get_compositor_private (window));
if (cw == NULL)
return;
@@ -172,47 +130,26 @@ process_shape (MetaCompositor *compositor,
static void
process_property_notify (MetaCompositor *compositor,
XPropertyEvent *event)
XPropertyEvent *event,
MetaWindow *window)
{
MetaDisplay *display = compositor->display;
MutterWindow *cw;
if (window == NULL)
return;
cw = MUTTER_WINDOW (meta_window_get_compositor_private (window));
if (cw == NULL)
return;
/* Check for the opacity changing */
if (event->atom == compositor->atom_net_wm_window_opacity)
{
MutterWindow *cw = find_window_in_display (display, event->window);
if (!cw)
{
/* Applications can set this for their toplevel windows, so
* this must be propagated to the window managed by the compositor
*/
cw = find_window_for_child_window_in_display (display,
event->window);
}
if (!cw)
{
DEBUG_TRACE ("process_property_notify: opacity, early exit\n");
return;
}
mutter_window_update_opacity (cw);
}
else if (event->atom == meta_display_get_atom (display,
META_ATOM__NET_WM_WINDOW_TYPE))
{
MutterWindow *cw = find_window_in_display (display, event->window);
if (!cw)
{
DEBUG_TRACE ("process_property_notify: net_wm_type, early exit\n");
return;
}
mutter_window_update_window_type (cw);
DEBUG_TRACE ("process_property_notify: net_wm_type\n");
DEBUG_TRACE ("process_property_notify: net_wm_window_opacity\n");
return;
}
DEBUG_TRACE ("process_property_notify: unknown\n");
}
@@ -247,6 +184,12 @@ get_output_window (MetaScreen *screen)
return output;
}
/**
* mutter_get_stage_for_screen:
* @screen: a #MetaScreen
*
* Returns: (transfer none): The #ClutterStage for the screen
*/
ClutterActor *
mutter_get_stage_for_screen (MetaScreen *screen)
{
@@ -258,6 +201,12 @@ mutter_get_stage_for_screen (MetaScreen *screen)
return info->stage;
}
/**
* mutter_get_overlay_group_for_screen:
* @screen: a #MetaScreen
*
* Returns: (transfer none): The overlay group corresponding to @screen
*/
ClutterActor *
mutter_get_overlay_group_for_screen (MetaScreen *screen)
{
@@ -269,6 +218,12 @@ mutter_get_overlay_group_for_screen (MetaScreen *screen)
return info->overlay_group;
}
/**
* mutter_get_window_group_for_screen:
* @screen: a #MetaScreen
*
* Returns: (transfer none): The window group corresponding to @screen
*/
ClutterActor *
mutter_get_window_group_for_screen (MetaScreen *screen)
{
@@ -280,6 +235,12 @@ mutter_get_window_group_for_screen (MetaScreen *screen)
return info->window_group;
}
/**
* mutter_get_windows:
* @screen: a #MetaScreen
*
* Returns: (transfer none) (element-type Clutter.Actor): The windows on @screen
*/
GList *
mutter_get_windows (MetaScreen *screen)
{
@@ -390,10 +351,10 @@ mutter_begin_modal_for_plugin (MetaScreen *screen,
if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
{
XGrabKeyboard (xdpy, grab_window,
False, /* owner_events */
GrabModeAsync, GrabModeAsync,
timestamp);
result = XGrabKeyboard (xdpy, grab_window,
False, /* owner_events */
GrabModeAsync, GrabModeAsync,
timestamp);
if (result != Success)
goto fail;
@@ -505,7 +466,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
info->output = None;
info->windows = NULL;
info->windows_by_xid = g_hash_table_new (g_direct_hash, g_direct_equal);
meta_screen_set_cm_selection (screen);
@@ -545,9 +505,17 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
clutter_actor_hide (info->hidden_group);
info->plugin_mgr =
mutter_plugin_manager_new (screen);
if (!mutter_plugin_manager_load (info->plugin_mgr))
g_critical ("failed to load plugins");
mutter_plugin_manager_get (screen);
if (info->plugin_mgr != mutter_plugin_manager_get_default ())
{
/* The default plugin manager has been initialized during
* global preferences load.
*/
if (!mutter_plugin_manager_load (info->plugin_mgr))
g_critical ("failed to load plugins");
}
if (!mutter_plugin_manager_initialize (info->plugin_mgr))
g_critical ("failed to initialize plugins");
@@ -634,14 +602,17 @@ is_grabbed_event (XEvent *event)
case EnterNotify:
case LeaveNotify:
case MotionNotify:
case KeyPressMask:
case KeyReleaseMask:
case KeyPress:
case KeyRelease:
return TRUE;
}
return FALSE;
}
/**
* meta_compositor_process_event: (skip)
*
*/
gboolean
meta_compositor_process_event (MetaCompositor *compositor,
XEvent *event,
@@ -696,38 +667,37 @@ meta_compositor_process_event (MetaCompositor *compositor,
}
}
/*
* This trap is so that none of the compositor functions cause
* X errors. This is really a hack, but I'm afraid I don't understand
* enough about Metacity/X to know how else you are supposed to do it
*/
meta_error_trap_push (compositor->display);
switch (event->type)
{
case PropertyNotify:
process_property_notify (compositor, (XPropertyEvent *) event);
process_property_notify (compositor, (XPropertyEvent *) event, window);
break;
default:
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);
process_damage (compositor, (XDamageNotifyEvent *) event, window);
}
#ifdef HAVE_SHAPE
else if (event->type == meta_display_get_shape_event_base (compositor->display) + ShapeNotify)
{
DEBUG_TRACE ("meta_compositor_process_event (process_shape)\n");
process_shape (compositor, (XShapeEvent *) event);
process_shape (compositor, (XShapeEvent *) event, window);
}
#endif /* HAVE_SHAPE */
break;
}
meta_error_trap_pop (compositor->display, FALSE);
/* Clutter needs to know about MapNotify events otherwise it will
think the stage is invisible */
if (event->type == MapNotify)
@@ -840,7 +810,6 @@ meta_compositor_switch_workspace (MetaCompositor *compositor,
if (!info->plugin_mgr ||
!mutter_plugin_manager_switch_workspace (info->plugin_mgr,
(const GList **)&info->windows,
from_indx,
to_indx,
direction))
@@ -1048,6 +1017,10 @@ mutter_repaint_func (gpointer data)
return TRUE;
}
/**
* meta_compositor_new: (skip)
*
*/
MetaCompositor *
meta_compositor_new (MetaDisplay *display)
{
@@ -1085,6 +1058,10 @@ meta_compositor_new (MetaDisplay *display)
return compositor;
}
/**
* mutter_get_overlay_window: (skip)
*
*/
Window
mutter_get_overlay_window (MetaScreen *screen)
{

View File

@@ -39,26 +39,27 @@
*/
static GHashTable *plugin_modules = NULL;
/*
* We have one "default plugin manager" that acts for the first screen,
* but also can be used before we open any screens, and additional
* plugin managers for each screen. (This is ugly. Probably we should
* have one plugin manager and only make the plugins per-screen.)
*/
static MutterPluginManager *default_plugin_manager;
static gboolean mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr);
struct MutterPluginManager
{
MetaScreen *screen;
GList /* MutterPluginPending */ *pending_plugin_modules; /* Plugins not yet fully loaded */
GList /* MutterPlugin */ *plugins; /* TODO -- maybe use hash table */
GList *unload; /* Plugins that are disabled and pending unload */
guint idle_unload_id;
};
typedef struct MutterPluginPending
{
MutterModule *module;
char *path;
char *params;
} MutterPluginPending;
/*
* Checks that the plugin is compatible with the WM and sets up the plugin
* struct.
@@ -78,7 +79,6 @@ mutter_plugin_load (MutterPluginManager *mgr,
}
plugin = g_object_new (plugin_type,
"screen", mgr->screen,
"params", params,
NULL);
@@ -270,12 +270,14 @@ mutter_plugin_manager_load (MutterPluginManager *plugin_mgr)
if (use_succeeded)
{
MutterPluginPending *pending = g_new0 (MutterPluginPending, 1);
pending->module = module;
pending->path = g_strdup (path);
pending->params = g_strdup (params);
plugin_mgr->pending_plugin_modules =
g_list_prepend (plugin_mgr->pending_plugin_modules, pending);
MutterPlugin *plugin = mutter_plugin_load (plugin_mgr, module, params);
if (plugin)
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, plugin);
else
g_warning ("Plugin load for [%s] failed", path);
g_type_module_unuse (G_TYPE_MODULE (module));
}
}
else
@@ -293,7 +295,7 @@ mutter_plugin_manager_load (MutterPluginManager *plugin_mgr)
if (fallback)
g_slist_free (fallback);
if (plugin_mgr->pending_plugin_modules != NULL)
if (plugin_mgr->plugins != NULL)
{
meta_prefs_add_listener (prefs_changed_callback, plugin_mgr);
return TRUE;
@@ -307,27 +309,19 @@ mutter_plugin_manager_initialize (MutterPluginManager *plugin_mgr)
{
GList *iter;
for (iter = plugin_mgr->pending_plugin_modules; iter; iter = iter->next)
for (iter = plugin_mgr->plugins; iter; iter = iter->next)
{
MutterPluginPending *pending = (MutterPluginPending*) iter->data;
MutterPlugin *p;
MutterPlugin *plugin = (MutterPlugin*) iter->data;
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
if ((p = mutter_plugin_load (plugin_mgr, pending->module, pending->params)))
{
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, p);
}
else
{
g_warning ("Plugin load for [%s] failed", pending->path);
}
g_object_set (plugin,
"screen", plugin_mgr->screen,
NULL);
g_type_module_unuse (G_TYPE_MODULE (pending->module));
g_free (pending->path);
g_free (pending->params);
g_free (pending);
if (klass->start)
klass->start (plugin);
}
g_list_free (plugin_mgr->pending_plugin_modules);
plugin_mgr->pending_plugin_modules = NULL;
return TRUE;
}
@@ -349,7 +343,7 @@ mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr)
return mutter_plugin_manager_load (plugin_mgr);
}
MutterPluginManager *
static MutterPluginManager *
mutter_plugin_manager_new (MetaScreen *screen)
{
MutterPluginManager *plugin_mgr;
@@ -364,13 +358,52 @@ mutter_plugin_manager_new (MetaScreen *screen)
plugin_mgr->screen = screen;
if (screen)
g_object_set_data (G_OBJECT (screen), "mutter-plugin-manager", plugin_mgr);
return plugin_mgr;
}
MutterPluginManager *
mutter_plugin_manager_get_default (void)
{
if (!default_plugin_manager)
{
default_plugin_manager = mutter_plugin_manager_new (NULL);
}
return default_plugin_manager;
}
MutterPluginManager *
mutter_plugin_manager_get (MetaScreen *screen)
{
MutterPluginManager *plugin_mgr;
plugin_mgr = g_object_get_data (G_OBJECT (screen), "mutter-plugin-manager");
if (plugin_mgr)
return plugin_mgr;
if (!default_plugin_manager)
mutter_plugin_manager_get_default ();
if (!default_plugin_manager->screen)
{
/* The default plugin manager is so far unused, we can recycle it */
default_plugin_manager->screen = screen;
g_object_set_data (G_OBJECT (screen), "mutter-plugin-manager", default_plugin_manager);
return default_plugin_manager;
}
else
{
return mutter_plugin_manager_new (screen);
}
}
static void
mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
MutterWindow *actor,
unsigned long events)
mutter_plugin_manager_kill_window_effects (MutterPluginManager *plugin_mgr,
MutterWindow *actor)
{
GList *l = plugin_mgr->plugins;
@@ -380,17 +413,32 @@ mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
if (!mutter_plugin_disabled (plugin)
&& (mutter_plugin_features (plugin) & events)
&& klass->kill_effect)
klass->kill_effect (plugin, actor, events);
&& klass->kill_window_effects)
klass->kill_window_effects (plugin, actor);
l = l->next;
}
}
static void
mutter_plugin_manager_kill_switch_workspace (MutterPluginManager *plugin_mgr)
{
GList *l = plugin_mgr->plugins;
while (l)
{
MutterPlugin *plugin = l->data;
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
if (!mutter_plugin_disabled (plugin)
&& (mutter_plugin_features (plugin) & MUTTER_PLUGIN_SWITCH_WORKSPACE)
&& klass->kill_switch_workspace)
klass->kill_switch_workspace (plugin);
l = l->next;
}
}
#define ALL_BUT_SWITCH \
MUTTER_PLUGIN_ALL_EFFECTS & \
~MUTTER_PLUGIN_SWITCH_WORKSPACE
/*
* Public method that the compositor hooks into for events that require
* no additional parameters.
@@ -427,10 +475,9 @@ mutter_plugin_manager_event_simple (MutterPluginManager *plugin_mgr,
case MUTTER_PLUGIN_MINIMIZE:
if (klass->minimize)
{
mutter_plugin_manager_kill_effect (
mutter_plugin_manager_kill_window_effects (
plugin_mgr,
actor,
ALL_BUT_SWITCH);
actor);
_mutter_plugin_effect_started (plugin);
klass->minimize (plugin, actor);
@@ -439,10 +486,9 @@ mutter_plugin_manager_event_simple (MutterPluginManager *plugin_mgr,
case MUTTER_PLUGIN_MAP:
if (klass->map)
{
mutter_plugin_manager_kill_effect (
mutter_plugin_manager_kill_window_effects (
plugin_mgr,
actor,
ALL_BUT_SWITCH);
actor);
_mutter_plugin_effect_started (plugin);
klass->map (plugin, actor);
@@ -506,10 +552,9 @@ mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
case MUTTER_PLUGIN_MAXIMIZE:
if (klass->maximize)
{
mutter_plugin_manager_kill_effect (
mutter_plugin_manager_kill_window_effects (
plugin_mgr,
actor,
ALL_BUT_SWITCH);
actor);
_mutter_plugin_effect_started (plugin);
klass->maximize (plugin, actor,
@@ -520,10 +565,9 @@ mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
case MUTTER_PLUGIN_UNMAXIMIZE:
if (klass->unmaximize)
{
mutter_plugin_manager_kill_effect (
mutter_plugin_manager_kill_window_effects (
plugin_mgr,
actor,
ALL_BUT_SWITCH);
actor);
_mutter_plugin_effect_started (plugin);
klass->unmaximize (plugin, actor,
@@ -552,7 +596,6 @@ mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
*/
gboolean
mutter_plugin_manager_switch_workspace (MutterPluginManager *plugin_mgr,
const GList **actors,
gint from,
gint to,
MetaMotionDirection direction)
@@ -570,19 +613,15 @@ mutter_plugin_manager_switch_workspace (MutterPluginManager *plugin_mgr,
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
if (!mutter_plugin_disabled (plugin) &&
(mutter_plugin_features (plugin) & MUTTER_PLUGIN_SWITCH_WORKSPACE) &&
(actors && *actors))
(mutter_plugin_features (plugin) & MUTTER_PLUGIN_SWITCH_WORKSPACE))
{
if (klass->switch_workspace)
{
retval = TRUE;
mutter_plugin_manager_kill_effect (
plugin_mgr,
MUTTER_WINDOW ((*actors)->data),
MUTTER_PLUGIN_SWITCH_WORKSPACE);
mutter_plugin_manager_kill_switch_workspace (plugin_mgr);
_mutter_plugin_effect_started (plugin);
klass->switch_workspace (plugin, actors, from, to, direction);
klass->switch_workspace (plugin, from, to, direction);
}
}

View File

@@ -31,9 +31,24 @@
#include "mutter-plugin.h"
#undef MUTTER_PLUGIN_FROM_MANAGER_
#define MUTTER_PLUGIN_MINIMIZE (1<<0)
#define MUTTER_PLUGIN_MAXIMIZE (1<<1)
#define MUTTER_PLUGIN_UNMAXIMIZE (1<<2)
#define MUTTER_PLUGIN_MAP (1<<3)
#define MUTTER_PLUGIN_DESTROY (1<<4)
#define MUTTER_PLUGIN_SWITCH_WORKSPACE (1<<5)
#define MUTTER_PLUGIN_ALL_EFFECTS (~0)
/**
* MutterPluginManager: (skip)
*
*/
typedef struct MutterPluginManager MutterPluginManager;
MutterPluginManager * mutter_plugin_manager_new (MetaScreen *screen);
MutterPluginManager * mutter_plugin_manager_get (MetaScreen *screen);
MutterPluginManager * mutter_plugin_manager_get_default (void);
gboolean mutter_plugin_manager_load (MutterPluginManager *mgr);
gboolean mutter_plugin_manager_initialize (MutterPluginManager *plugin_mgr);
gboolean mutter_plugin_manager_event_simple (MutterPluginManager *mgr,
@@ -52,7 +67,6 @@ void mutter_plugin_manager_update_workspaces (MutterPluginManager *mgr);
void mutter_plugin_manager_update_workspace (MutterPluginManager *mgr, MetaWorkspace *w);
gboolean mutter_plugin_manager_switch_workspace (MutterPluginManager *mgr,
const GList **actors,
gint from,
gint to,
MetaMotionDirection direction);

View File

@@ -238,8 +238,7 @@ mutter_plugin_class_init (MutterPluginClass *klass)
"MetaScreen",
"MetaScreen",
META_TYPE_SCREEN,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_PARAMS,
@@ -368,9 +367,25 @@ _mutter_plugin_effect_started (MutterPlugin *plugin)
}
void
mutter_plugin_effect_completed (MutterPlugin *plugin,
MutterWindow *actor,
unsigned long event)
mutter_plugin_switch_workspace_completed (MutterPlugin *plugin)
{
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
MetaScreen *screen = mutter_plugin_get_screen (plugin);
if (priv->running-- < 0)
{
g_warning ("Error in running effect accounting, adjusting.");
priv->running = 0;
}
mutter_switch_workspace_completed (screen);
}
static void
mutter_plugin_window_effect_completed (MutterPlugin *plugin,
MutterWindow *actor,
unsigned long event)
{
MutterPluginPrivate *priv = MUTTER_PLUGIN (plugin)->priv;
@@ -392,17 +407,42 @@ mutter_plugin_effect_completed (MutterPlugin *plugin,
name ? name : "unknown");
}
if (event == MUTTER_PLUGIN_SWITCH_WORKSPACE)
{
/* The window is just used to identify the screen */
MetaWindow *window = mutter_window_get_meta_window (actor);
MetaScreen *screen = meta_window_get_screen (window);
mutter_switch_workspace_completed (screen);
}
else
{
mutter_window_effect_completed (actor, event);
}
mutter_window_effect_completed (actor, event);
}
void
mutter_plugin_minimize_completed (MutterPlugin *plugin,
MutterWindow *actor)
{
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_MINIMIZE);
}
void
mutter_plugin_maximize_completed (MutterPlugin *plugin,
MutterWindow *actor)
{
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_MAXIMIZE);
}
void
mutter_plugin_unmaximize_completed (MutterPlugin *plugin,
MutterWindow *actor)
{
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_UNMAXIMIZE);
}
void
mutter_plugin_map_completed (MutterPlugin *plugin,
MutterWindow *actor)
{
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_MAP);
}
void
mutter_plugin_destroy_completed (MutterPlugin *plugin,
MutterWindow *actor)
{
mutter_plugin_window_effect_completed (plugin, actor, MUTTER_PLUGIN_DESTROY);
}
void
@@ -459,6 +499,18 @@ mutter_plugin_set_stage_input_region (MutterPlugin *plugin,
mutter_set_stage_input_region (screen, region);
}
/**
* mutter_plugin_get_windows:
* @plugin: A #MutterPlugin
*
* This function returns all of the #MutterWindow objects referenced by Mutter, including
* override-redirect windows. The returned list is a snapshot of Mutter's current
* stacking order, with the topmost window last.
*
* The 'restacked' signal of #MetaScreen signals when this value has changed.
*
* Returns: (transfer none) (element-type MutterWindow): Windows in stacking order, topmost last
*/
GList *
mutter_plugin_get_windows (MutterPlugin *plugin)
{

277
src/compositor/mutter-shaped-texture.c Executable file → Normal file
View File

@@ -26,19 +26,27 @@
#include <config.h>
#include "mutter-shaped-texture.h"
#include "mutter-texture-tower.h"
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <string.h>
static void mutter_shaped_texture_dispose (GObject *object);
static void mutter_shaped_texture_finalize (GObject *object);
static void mutter_shaped_texture_notify (GObject *object,
GParamSpec *pspec);
static void mutter_shaped_texture_paint (ClutterActor *actor);
static void mutter_shaped_texture_pick (ClutterActor *actor,
const ClutterColor *color);
static void mutter_shaped_texture_update_area (ClutterX11TexturePixmap *texture,
int x,
int y,
int width,
int height);
static void mutter_shaped_texture_dirty_mask (MutterShapedTexture *stex);
#ifdef HAVE_GLX_TEXTURE_PIXMAP
@@ -55,18 +63,18 @@ G_DEFINE_TYPE (MutterShapedTexture, mutter_shaped_texture,
struct _MutterShapedTexturePrivate
{
MutterTextureTower *paint_tower;
CoglHandle mask_texture;
CoglHandle material;
CoglHandle material_unshaped;
#if 1 /* see workaround comment in mutter_shaped_texture_paint */
CoglHandle material_workaround;
#endif
GdkRegion *clip_region;
MetaRegion *clip_region;
guint mask_width, mask_height;
GArray *rectangles;
guint create_mipmaps : 1;
};
static void
@@ -74,13 +82,17 @@ mutter_shaped_texture_class_init (MutterShapedTextureClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
ClutterX11TexturePixmapClass *x11_texture_class = (ClutterX11TexturePixmapClass *) klass;
gobject_class->dispose = mutter_shaped_texture_dispose;
gobject_class->finalize = mutter_shaped_texture_finalize;
gobject_class->notify = mutter_shaped_texture_notify;
actor_class->paint = mutter_shaped_texture_paint;
actor_class->pick = mutter_shaped_texture_pick;
x11_texture_class->update_area = mutter_shaped_texture_update_area;
g_type_class_add_private (klass, sizeof (MutterShapedTexturePrivate));
}
@@ -93,7 +105,9 @@ mutter_shaped_texture_init (MutterShapedTexture *self)
priv->rectangles = g_array_new (FALSE, FALSE, sizeof (XRectangle));
priv->paint_tower = mutter_texture_tower_new ();
priv->mask_texture = COGL_INVALID_HANDLE;
priv->create_mipmaps = TRUE;
}
static void
@@ -102,25 +116,22 @@ mutter_shaped_texture_dispose (GObject *object)
MutterShapedTexture *self = (MutterShapedTexture *) object;
MutterShapedTexturePrivate *priv = self->priv;
if (priv->paint_tower)
mutter_texture_tower_free (priv->paint_tower);
priv->paint_tower = NULL;
mutter_shaped_texture_dirty_mask (self);
if (priv->material != COGL_INVALID_HANDLE)
{
cogl_material_unref (priv->material);
cogl_handle_unref (priv->material);
priv->material = COGL_INVALID_HANDLE;
}
if (priv->material_unshaped != COGL_INVALID_HANDLE)
{
cogl_material_unref (priv->material_unshaped);
cogl_handle_unref (priv->material_unshaped);
priv->material_unshaped = COGL_INVALID_HANDLE;
}
#if 1 /* see comment in mutter_shaped_texture_paint */
if (priv->material_workaround != COGL_INVALID_HANDLE)
{
cogl_material_unref (priv->material_workaround);
priv->material_workaround = COGL_INVALID_HANDLE;
}
#endif
mutter_shaped_texture_set_clip_region (self, NULL);
@@ -138,6 +149,31 @@ mutter_shaped_texture_finalize (GObject *object)
G_OBJECT_CLASS (mutter_shaped_texture_parent_class)->finalize (object);
}
static void
mutter_shaped_texture_notify (GObject *object,
GParamSpec *pspec)
{
if (G_OBJECT_CLASS (mutter_shaped_texture_parent_class)->notify)
G_OBJECT_CLASS (mutter_shaped_texture_parent_class)->notify (object, pspec);
/* It seems like we could just do this out of update_area(), but unfortunately,
* clutter_glx_texture_pixmap() doesn't call through the vtable on the
* initial update_area, so we need to look for changes to the texture
* explicitly.
*/
if (strcmp (pspec->name, "cogl-texture") == 0)
{
MutterShapedTexture *stex = (MutterShapedTexture *) object;
MutterShapedTexturePrivate *priv = stex->priv;
mutter_shaped_texture_clear (stex);
if (priv->create_mipmaps)
mutter_texture_tower_set_base_texture (priv->paint_tower,
clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex)));
}
}
static void
mutter_shaped_texture_dirty_mask (MutterShapedTexture *stex)
{
@@ -151,11 +187,14 @@ mutter_shaped_texture_dirty_mask (MutterShapedTexture *stex)
cogl_texture_get_gl_texture (priv->mask_texture,
&mask_gl_tex, &mask_gl_target);
if (mask_gl_target == CGL_TEXTURE_RECTANGLE_ARB)
if (mask_gl_target == GL_TEXTURE_RECTANGLE_ARB)
glDeleteTextures (1, &mask_gl_tex);
cogl_texture_unref (priv->mask_texture);
cogl_handle_unref (priv->mask_texture);
priv->mask_texture = COGL_INVALID_HANDLE;
if (priv->material != COGL_INVALID_HANDLE)
cogl_material_set_layer (priv->material, 1, COGL_INVALID_HANDLE);
}
}
@@ -214,23 +253,23 @@ mutter_shaped_texture_ensure_mask (MutterShapedTexture *stex)
cogl_texture_get_gl_texture (paint_tex, NULL, &paint_gl_target);
if (paint_gl_target == CGL_TEXTURE_RECTANGLE_ARB)
if (paint_gl_target == GL_TEXTURE_RECTANGLE_ARB)
{
GLuint tex;
glGenTextures (1, &tex);
glBindTexture (CGL_TEXTURE_RECTANGLE_ARB, tex);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
glPixelStorei (GL_UNPACK_ROW_LENGTH, tex_width);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
glTexImage2D (CGL_TEXTURE_RECTANGLE_ARB, 0,
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
GL_ALPHA, tex_width, tex_height,
0, GL_ALPHA, GL_UNSIGNED_BYTE, mask_data);
priv->mask_texture
= cogl_texture_new_from_foreign (tex,
CGL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_RECTANGLE_ARB,
tex_width, tex_height,
0, 0,
COGL_PIXEL_FORMAT_A_8);
@@ -258,18 +297,40 @@ mutter_shaped_texture_paint (ClutterActor *actor)
CoglHandle paint_tex;
guint tex_width, tex_height;
ClutterActorBox alloc;
CoglHandle material;
#if 1 /* please see comment below about workaround */
guint depth;
#endif
if (priv->clip_region && gdk_region_empty (priv->clip_region))
static CoglHandle material_template = COGL_INVALID_HANDLE;
static CoglHandle material_unshaped_template = COGL_INVALID_HANDLE;
CoglHandle material;
if (priv->clip_region && meta_region_is_empty (priv->clip_region))
return;
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
clutter_actor_realize (CLUTTER_ACTOR (stex));
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (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 = mutter_texture_tower_get_paint_texture (priv->paint_tower);
else
paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
if (paint_tex == COGL_INVALID_HANDLE)
return;
tex_width = cogl_texture_get_width (paint_tex);
tex_height = cogl_texture_get_height (paint_tex);
@@ -277,17 +338,18 @@ mutter_shaped_texture_paint (ClutterActor *actor)
if (tex_width == 0 || tex_height == 0) /* no contents yet */
return;
if (paint_tex == COGL_INVALID_HANDLE)
return;
if (priv->rectangles->len < 1)
{
/* If there are no rectangles use a single-layer texture */
if (priv->material_unshaped == COGL_INVALID_HANDLE)
priv->material_unshaped = cogl_material_new ();
if (priv->material_unshaped == COGL_INVALID_HANDLE)
{
if (G_UNLIKELY (material_unshaped_template == COGL_INVALID_HANDLE))
material_unshaped_template = cogl_material_new ();
material = priv->material_unshaped;
priv->material_unshaped = cogl_material_copy (material_unshaped_template);
}
material = priv->material_unshaped;
}
else
{
@@ -295,43 +357,17 @@ mutter_shaped_texture_paint (ClutterActor *actor)
if (priv->material == COGL_INVALID_HANDLE)
{
priv->material = cogl_material_new ();
cogl_material_set_layer_combine (priv->material, 1,
if (G_UNLIKELY (material_template == COGL_INVALID_HANDLE))
{
material_template = cogl_material_new ();
cogl_material_set_layer_combine (material_template, 1,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
}
priv->material = cogl_material_copy (material_template);
}
material = priv->material;
#if 1
/* This was added as a workaround. It seems that with the intel
* drivers when multi-texturing using an RGB TFP texture, the
* texture is actually setup internally as an RGBA texture, where
* the alpha channel is mostly 0.0 so you only see a shimmer of the
* window. This workaround forcibly defines the alpha channel as
* 1.0. Maybe there is some clutter/cogl state that is interacting
* with this that is being overlooked, but for now this seems to
* work. */
g_object_get (stex, "pixmap-depth", &depth, NULL);
if (depth == 24)
{
if (priv->material_workaround == COGL_INVALID_HANDLE)
{
material = priv->material_workaround = cogl_material_new ();
cogl_material_set_layer_combine (material, 0,
"RGB = MODULATE (TEXTURE, PREVIOUS)"
"A = REPLACE (PREVIOUS)",
NULL);
cogl_material_set_layer_combine (material, 1,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
}
material = priv->material_workaround;
}
#endif
cogl_material_set_layer (material, 1, priv->mask_texture);
}
@@ -359,7 +395,7 @@ mutter_shaped_texture_paint (ClutterActor *actor)
# define MAX_RECTS 16
/* Would be nice to be able to check the number of rects first */
gdk_region_get_rectangles (priv->clip_region, &rects, &n_rects);
meta_region_get_rectangles (priv->clip_region, &rects, &n_rects);
if (n_rects > MAX_RECTS)
{
g_free (rects);
@@ -367,24 +403,34 @@ mutter_shaped_texture_paint (ClutterActor *actor)
}
else
{
float coords[MAX_RECTS * 8];
float coords[8];
float x1, y1, x2, y2;
for (i = 0; i < n_rects; i++)
{
GdkRectangle *rect = &rects[i];
coords[i * 8 + 0] = rect->x;
coords[i * 8 + 1] = rect->y;
coords[i * 8 + 2] = rect->x + rect->width;
coords[i * 8 + 3] = rect->y + rect->height;
coords[i * 8 + 4] = rect->x / (alloc.x2 - alloc.x1);
coords[i * 8 + 5] = rect->y / (alloc.y2 - alloc.y1);
coords[i * 8 + 6] = (rect->x + rect->width) / (alloc.x2 - alloc.x1);
coords[i * 8 + 7] = (rect->y + rect->height) / (alloc.y2 - alloc.y1);
}
x1 = rect->x;
y1 = rect->y;
x2 = rect->x + rect->width;
y2 = rect->y + rect->height;
coords[0] = rect->x / (alloc.x2 - alloc.x1);
coords[1] = rect->y / (alloc.y2 - alloc.y1);
coords[2] = (rect->x + rect->width) / (alloc.x2 - alloc.x1);
coords[3] = (rect->y + rect->height) / (alloc.y2 - alloc.y1);
coords[4] = coords[0];
coords[5] = coords[1];
coords[6] = coords[2];
coords[7] = coords[3];
cogl_rectangle_with_multitexture_coords (x1, y1, x2, y2,
&coords[0], 8);
}
g_free (rects);
cogl_rectangles_with_texture_coords (coords, n_rects);
return;
}
}
@@ -438,6 +484,22 @@ mutter_shaped_texture_pick (ClutterActor *actor,
}
}
static void
mutter_shaped_texture_update_area (ClutterX11TexturePixmap *texture,
int x,
int y,
int width,
int height)
{
MutterShapedTexture *stex = (MutterShapedTexture *) texture;
MutterShapedTexturePrivate *priv = stex->priv;
CLUTTER_X11_TEXTURE_PIXMAP_CLASS (mutter_shaped_texture_parent_class)->update_area (texture,
x, y, width, height);
mutter_texture_tower_update_area (priv->paint_tower, x, y, width, height);
}
ClutterActor *
mutter_shaped_texture_new (void)
{
@@ -446,6 +508,65 @@ mutter_shaped_texture_new (void)
return self;
}
void
mutter_shaped_texture_set_create_mipmaps (MutterShapedTexture *stex,
gboolean create_mipmaps)
{
MutterShapedTexturePrivate *priv;
g_return_if_fail (MUTTER_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
create_mipmaps = create_mipmaps != FALSE;
if (create_mipmaps != priv->create_mipmaps)
{
CoglHandle base_texture;
priv->create_mipmaps = create_mipmaps;
base_texture = create_mipmaps ?
clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex)) : COGL_INVALID_HANDLE;
mutter_texture_tower_set_base_texture (priv->paint_tower, base_texture);
}
}
/* This is a workaround for deficiencies in the hack tower:
*
* When we call clutter_x11_texture_pixmap_set_pixmap(tp, None),
* ClutterX11TexturePixmap knows that it has to get rid of the old texture, but
* clutter_texture_set_cogl_texture(texture, COGL_INVALID_HANDLE) isn't allowed, so
* it grabs the material for the texture and manually sets the texture in it. This means
* that the "cogl-texture" property isn't notified, so we don't find out about it.
*
* And if we keep the CoglX11TexturePixmap around after the X pixmap is freed, then
* we'll trigger X errors when we actually try to free it.
*
* The only correct thing to do here is to change our code to derive
* from ClutterActor and get rid of the inheritance hack tower. Once
* we want to depend on Clutter-1.4 (which has CoglTexturePixmapX11),
* that will be very easy to do.
*/
void
mutter_shaped_texture_clear (MutterShapedTexture *stex)
{
MutterShapedTexturePrivate *priv;
g_return_if_fail (MUTTER_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
mutter_texture_tower_set_base_texture (priv->paint_tower, COGL_INVALID_HANDLE);
if (priv->material != COGL_INVALID_HANDLE)
cogl_material_set_layer (priv->material, 0, COGL_INVALID_HANDLE);
if (priv->material_unshaped != COGL_INVALID_HANDLE)
cogl_material_set_layer (priv->material_unshaped, 0, COGL_INVALID_HANDLE);
}
void
mutter_shaped_texture_clear_rectangles (MutterShapedTexture *stex)
{
@@ -503,7 +624,7 @@ mutter_shaped_texture_add_rectangles (MutterShapedTexture *stex,
*/
void
mutter_shaped_texture_set_clip_region (MutterShapedTexture *stex,
GdkRegion *clip_region)
MetaRegion *clip_region)
{
MutterShapedTexturePrivate *priv;
@@ -513,7 +634,7 @@ mutter_shaped_texture_set_clip_region (MutterShapedTexture *stex,
if (priv->clip_region)
{
gdk_region_destroy (priv->clip_region);
meta_region_destroy (priv->clip_region);
priv->clip_region = NULL;
}

View File

@@ -26,12 +26,14 @@
#ifndef __MUTTER_SHAPED_TEXTURE_H__
#define __MUTTER_SHAPED_TEXTURE_H__
#include <config.h>
#include <clutter/clutter.h>
#ifdef HAVE_GLX_TEXTURE_PIXMAP
#include <clutter/glx/clutter-glx.h>
#endif /* HAVE_GLX_TEXTURE_PIXMAP */
#include <gdk/gdkregion.h>
#include "region.h"
G_BEGIN_DECLS
@@ -84,6 +86,11 @@ GType mutter_shaped_texture_get_type (void) G_GNUC_CONST;
ClutterActor *mutter_shaped_texture_new (void);
void mutter_shaped_texture_set_create_mipmaps (MutterShapedTexture *stex,
gboolean create_mipmaps);
void mutter_shaped_texture_clear (MutterShapedTexture *stex);
void mutter_shaped_texture_clear_rectangles (MutterShapedTexture *stex);
void mutter_shaped_texture_add_rectangle (MutterShapedTexture *stex,
@@ -94,7 +101,7 @@ void mutter_shaped_texture_add_rectangles (MutterShapedTexture *stex,
/* Assumes ownership of clip_region */
void mutter_shaped_texture_set_clip_region (MutterShapedTexture *stex,
GdkRegion *clip_region);
MetaRegion *clip_region);
G_END_DECLS

View File

@@ -0,0 +1,654 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* MutterTextureTower
*
* Mipmap emulation by creation of scaled down images
*
* Copyright (C) 2009 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.
*/
#include <math.h>
#include <string.h>
#include "mutter-texture-tower.h"
#ifndef M_LOG2E
#define M_LOG2E 1.4426950408889634074
#endif
#define MAX_TEXTURE_LEVELS 12
/* If the texture format in memory doesn't match this, then Mesa
* will do the conversion, so things will still work, but it might
* be slow depending on how efficient Mesa is. These should be the
* native formats unless the display is 16bpp. If conversions
* here are a bottleneck, investigate whether we are converting when
* storing window data *into* the texture before adding extra code
* to handle multiple texture formats.
*/
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_BGRA_8888_PRE
#else
#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_ARGB_8888_PRE
#endif
typedef struct
{
guint16 x1;
guint16 y1;
guint16 x2;
guint16 y2;
} Box;
struct _MutterTextureTower
{
int n_levels;
CoglHandle textures[MAX_TEXTURE_LEVELS];
CoglHandle fbos[MAX_TEXTURE_LEVELS];
Box invalid[MAX_TEXTURE_LEVELS];
};
/**
* mutter_texture_tower_new:
*
* Creates a new texture tower. The base texture has to be set with
* mutter_texture_tower_set_base_texture() before use.
*
* Return value: the new texture tower. Free with mutter_texture_tower_free()
*/
MutterTextureTower *
mutter_texture_tower_new (void)
{
MutterTextureTower *tower;
tower = g_slice_new0 (MutterTextureTower);
return tower;
}
/**
* mutter_texture_tower_free:
* @tower: a #MutterTextureTower
*
* Frees a texture tower created with mutter_texture_tower_new().
*/
void
mutter_texture_tower_free (MutterTextureTower *tower)
{
g_return_if_fail (tower != NULL);
mutter_texture_tower_set_base_texture (tower, COGL_INVALID_HANDLE);
g_slice_free (MutterTextureTower, tower);
}
static gboolean
texture_is_rectangle (CoglHandle texture)
{
GLuint gl_tex;
GLenum gl_target;
cogl_texture_get_gl_texture (texture, &gl_tex, &gl_target);
return gl_target == GL_TEXTURE_RECTANGLE_ARB;
}
static void
free_texture (CoglHandle texture)
{
GLuint gl_tex;
GLenum gl_target;
cogl_texture_get_gl_texture (texture, &gl_tex, &gl_target);
if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
glDeleteTextures (1, &gl_tex);
cogl_handle_unref (texture);
}
/**
* mutter_texture_tower_update_area:
* @tower: a MutterTextureTower
* @texture: the new texture used as a base for scaled down versions
*
* Sets the base texture that is the scaled texture that the
* scaled textures of the tower are derived from. The texture itself
* will be used as level 0 of the tower and will be referenced until
* unset or until the tower is freed.
*/
void
mutter_texture_tower_set_base_texture (MutterTextureTower *tower,
CoglHandle texture)
{
int i;
g_return_if_fail (tower != NULL);
if (texture == tower->textures[0])
return;
if (tower->textures[0] != COGL_INVALID_HANDLE)
{
for (i = 1; i < tower->n_levels; i++)
{
if (tower->textures[i] != COGL_INVALID_HANDLE)
{
free_texture (tower->textures[i]);
tower->textures[i] = COGL_INVALID_HANDLE;
}
if (tower->fbos[i] != COGL_INVALID_HANDLE)
{
cogl_handle_unref (tower->fbos[i]);
tower->fbos[i] = COGL_INVALID_HANDLE;
}
}
cogl_handle_unref (tower->textures[0]);
}
tower->textures[0] = texture;
if (tower->textures[0] != COGL_INVALID_HANDLE)
{
int width, height;
cogl_handle_ref (tower->textures[0]);
width = cogl_texture_get_width (tower->textures[0]);
height = cogl_texture_get_height (tower->textures[0]);
tower->n_levels = 1 + MAX ((int)(M_LOG2E * log (width)), (int)(M_LOG2E * log (height)));
tower->n_levels = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);
mutter_texture_tower_update_area (tower, 0, 0, width, height);
}
else
{
tower->n_levels = 0;
}
}
/**
* mutter_texture_tower_update_area:
* @tower: a MutterTextureTower
* @x: X coordinate of upper left of rectangle that changed
* @y: Y coordinate of upper left of rectangle that changed
* @width: width of rectangle that changed
* @height: height rectangle that changed
*
* Mark a region of the base texture as having changed; the next
* time a scaled down version of the base texture is retrieved,
* the appropriate area of the scaled down texture will be updated.
*/
void
mutter_texture_tower_update_area (MutterTextureTower *tower,
int x,
int y,
int width,
int height)
{
int texture_width, texture_height;
Box invalid;
int i;
g_return_if_fail (tower != NULL);
texture_width = cogl_texture_get_width (tower->textures[0]);
texture_height = cogl_texture_get_height (tower->textures[0]);
invalid.x1 = x;
invalid.y1 = y;
invalid.x2 = x + width;
invalid.y2 = y + height;
for (i = 1; i < tower->n_levels; i++)
{
texture_width = MAX (1, texture_width / 2);
texture_height = MAX (1, texture_height / 2);
invalid.x1 = invalid.x1 / 2;
invalid.y1 = invalid.y1 / 2;
invalid.x2 = MIN (texture_width, (invalid.x2 + 1) / 2);
invalid.y2 = MIN (texture_height, (invalid.y2 + 1) / 2);
if (tower->invalid[i].x1 == tower->invalid[i].x2 ||
tower->invalid[i].y1 == tower->invalid[i].y2)
{
tower->invalid[i] = invalid;
}
else
{
tower->invalid[i].x1 = MIN (tower->invalid[i].x1, invalid.x1);
tower->invalid[i].y1 = MIN (tower->invalid[i].y1, invalid.y1);
tower->invalid[i].x2 = MAX (tower->invalid[i].x2, invalid.x2);
tower->invalid[i].y2 = MAX (tower->invalid[i].y2, invalid.y2);
}
}
}
/* It generally looks worse if we scale up a window texture by even a
* small amount than if we scale it down using bilinear filtering, so
* we always pick the *larger* adjacent level. */
#define LOD_BIAS (-0.49)
/* This determines the appropriate level of detail to use when drawing the
* texture, in a way that corresponds to what the GL specification does
* when mip-mapping. This is probably fancier and slower than what we need,
* but we do the computation only once each time we paint a window, and
* its easier to just use the equations from the specification than to
* come up with something simpler.
*
* If window is being painted at an angle from the viewer, then we have to
* pick a point in the texture; we use the middle of the texture (which is
* why the width/height are passed in.) This is not the normal case for
* Mutter.
*/
static int
get_paint_level (int width, int height)
{
CoglMatrix projection, modelview, pm;
float v[4];
double viewport_width, viewport_height;
double u0, v0;
double xc, yc, wc;
double dxdu_, dxdv_, dydu_, dydv_;
double det_, det_sq;
double rho_sq;
double lambda;
/* See
* http://www.opengl.org/registry/doc/glspec32.core.20090803.pdf
* Section 3.8.9, p. 1.6.2. Here we have
*
* u(x,y) = x_o;
* v(x,y) = y_o;
*
* Since we are mapping 1:1 from object coordinates into pixel
* texture coordinates, the clip coordinates are:
*
* (x_c) (x_o) (u)
* (y_c) = (M_projection)(M_modelview) (y_o) = (PM) (v)
* (z_c) (z_o) (0)
* (w_c) (w_o) (1)
*/
cogl_get_projection_matrix (&projection);
cogl_get_modelview_matrix (&modelview);
cogl_matrix_multiply (&pm, &projection, &modelview);
cogl_get_viewport (v);
viewport_width = v[2];
viewport_height = v[3];
u0 = width / 2.;
v0 = height / 2.;
xc = pm.xx * u0 + pm.xy * v0 + pm.xw;
yc = pm.yx * u0 + pm.yy * v0 + pm.yw;
wc = pm.wx * u0 + pm.wy * v0 + pm.ww;
/* We'll simplify the equations below for a bit of micro-optimization.
* The commented out code is the unsimplified version.
// Partial derivates of window coordinates:
//
// x_w = 0.5 * viewport_width * x_c / w_c + viewport_center_x
// y_w = 0.5 * viewport_height * y_c / w_c + viewport_center_y
//
// with respect to u, v, using
// d(a/b)/dx = da/dx * (1/b) - a * db/dx / (b^2)
dxdu = 0.5 * viewport_width * (pm.xx - pm.wx * (xc/wc)) / wc;
dxdv = 0.5 * viewport_width * (pm.xy - pm.wy * (xc/wc)) / wc;
dydu = 0.5 * viewport_height * (pm.yx - pm.wx * (yc/wc)) / wc;
dydv = 0.5 * viewport_height * (pm.yy - pm.wy * (yc/wc)) / wc;
// Compute the inverse partials as the matrix inverse
det = dxdu * dydv - dxdv * dydu;
dudx = dydv / det;
dudy = - dxdv / det;
dvdx = - dydu / det;
dvdy = dvdu / det;
// Scale factor; maximum of the distance in texels for a change of 1 pixel
// in the X direction or 1 pixel in the Y direction
rho = MAX (sqrt (dudx * dudx + dvdx * dvdx), sqrt(dudy * dudy + dvdy * dvdy));
// Level of detail
lambda = log2 (rho) + LOD_BIAS;
*/
/* dxdu * wc, etc */
dxdu_ = 0.5 * viewport_width * (pm.xx - pm.wx * (xc/wc));
dxdv_ = 0.5 * viewport_width * (pm.xy - pm.wy * (xc/wc));
dydu_ = 0.5 * viewport_height * (pm.yx - pm.wx * (yc/wc));
dydv_ = 0.5 * viewport_height * (pm.yy - pm.wy * (yc/wc));
/* det * wc^2 */
det_ = dxdu_ * dydv_ - dxdv_ * dydu_;
det_sq = det_ * det_;
if (det_sq == 0.0)
return -1;
/* (rho * det * wc)^2 */
rho_sq = MAX (dydv_ * dydv_ + dydu_ * dydu_, dxdv_ * dxdv_ + dxdu_ * dxdu_);
lambda = 0.5 * M_LOG2E * log (rho_sq * wc * wc / det_sq) + LOD_BIAS;
#if 0
g_print ("%g %g %g\n", 0.5 * viewport_width * pm.xx / pm.ww, 0.5 * viewport_height * pm.yy / pm.ww, lambda);
#endif
if (lambda <= 0.)
return 0;
else
return (int)(0.5 + lambda);
}
static gboolean
is_power_of_two (int x)
{
return (x & (x - 1)) == 0;
}
static void
texture_tower_create_texture (MutterTextureTower *tower,
int level,
int width,
int height)
{
if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
texture_is_rectangle (tower->textures[level - 1]))
{
GLuint tex = 0;
glGenTextures (1, &tex);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
GL_RGBA, width,height,
#if TEXTURE_FORMAT == COGL_PIXEL_FORMAT_BGRA_8888_PRE
0, GL_BGRA, GL_UNSIGNED_BYTE,
#else /* assume big endian */
0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
#endif
NULL);
tower->textures[level] = cogl_texture_new_from_foreign (tex, GL_TEXTURE_RECTANGLE_ARB,
width, height,
0, 0,
TEXTURE_FORMAT);
}
else
{
tower->textures[level] = cogl_texture_new_with_size (width, height,
COGL_TEXTURE_NO_AUTO_MIPMAP,
TEXTURE_FORMAT);
}
tower->invalid[level].x1 = 0;
tower->invalid[level].y1 = 0;
tower->invalid[level].x2 = width;
tower->invalid[level].y2 = height;
}
static gboolean
texture_tower_revalidate_fbo (MutterTextureTower *tower,
int level)
{
CoglHandle source_texture = tower->textures[level - 1];
int source_texture_width = cogl_texture_get_width (source_texture);
int source_texture_height = cogl_texture_get_height (source_texture);
CoglHandle dest_texture = tower->textures[level];
int dest_texture_width = cogl_texture_get_width (dest_texture);
int dest_texture_height = cogl_texture_get_height (dest_texture);
Box *invalid = &tower->invalid[level];
CoglMatrix modelview;
if (tower->fbos[level] == COGL_INVALID_HANDLE)
{
/* Work around http://bugzilla.openedhand.com/show_bug.cgi?id=2110 */
cogl_flush();
tower->fbos[level] = cogl_offscreen_new_to_texture (dest_texture);
}
if (tower->fbos[level] == COGL_INVALID_HANDLE)
return FALSE;
cogl_push_framebuffer (tower->fbos[level]);
cogl_ortho (0, dest_texture_width, dest_texture_height, 0, -1., 1.);
cogl_matrix_init_identity (&modelview);
cogl_set_modelview_matrix (&modelview);
cogl_set_source_texture (tower->textures[level - 1]);
cogl_rectangle_with_texture_coords (invalid->x1, invalid->y1,
invalid->x2, invalid->y2,
(2. * invalid->x1) / source_texture_width,
(2. * invalid->y1) / source_texture_height,
(2. * invalid->x2) / source_texture_width,
(2. * invalid->y2) / source_texture_height);
cogl_pop_framebuffer ();
return TRUE;
}
static void
fill_copy (guchar *buf,
const guchar *source,
int width)
{
memcpy (buf, source, width * 4);
}
static void
fill_scale_down (guchar *buf,
const guchar *source,
int width)
{
while (width > 1)
{
buf[0] = (source[0] + source[4]) / 2;
buf[1] = (source[1] + source[5]) / 2;
buf[2] = (source[2] + source[6]) / 2;
buf[3] = (source[3] + source[7]) / 2;
buf += 4;
source += 8;
width -= 2;
}
if (width > 0)
{
buf[0] = source[0] / 2;
buf[1] = source[1] / 2;
buf[2] = source[2] / 2;
buf[3] = source[3] / 2;
}
}
static void
texture_tower_revalidate_client (MutterTextureTower *tower,
int level)
{
CoglHandle source_texture = tower->textures[level - 1];
int source_texture_width = cogl_texture_get_width (source_texture);
int source_texture_height = cogl_texture_get_height (source_texture);
guint source_rowstride;
guchar *source_data;
CoglHandle dest_texture = tower->textures[level];
int dest_texture_width = cogl_texture_get_width (dest_texture);
int dest_texture_height = cogl_texture_get_height (dest_texture);
int dest_x = tower->invalid[level].x1;
int dest_y = tower->invalid[level].y1;
int dest_width = tower->invalid[level].x2 - tower->invalid[level].x1;
int dest_height = tower->invalid[level].y2 - tower->invalid[level].y1;
guchar *dest_data;
guchar *source_tmp1 = NULL, *source_tmp2 = NULL;
int i, j;
source_rowstride = source_texture_width * 4;
source_data = g_malloc (source_texture_height * source_rowstride);
cogl_texture_get_data (source_texture, TEXTURE_FORMAT, source_rowstride,
source_data);
dest_data = g_malloc (dest_height * dest_width * 4);
if (dest_texture_height < source_texture_height)
{
source_tmp1 = g_malloc (dest_width * 4);
source_tmp2 = g_malloc (dest_width * 4);
}
for (i = 0; i < dest_height; i++)
{
guchar *dest_row = dest_data + i * dest_width * 4;
if (dest_texture_height < source_texture_height)
{
guchar *source1, *source2;
guchar *dest;
if (dest_texture_width < source_texture_width)
{
fill_scale_down (source_tmp1,
source_data + ((i + dest_y) * 2) * source_rowstride + dest_x * 2 * 4,
dest_width * 2);
fill_scale_down (source_tmp2,
source_data + ((i + dest_y) * 2 + 1) * source_rowstride + dest_x * 2 * 4,
dest_width * 2);
}
else
{
fill_copy (source_tmp1,
source_data + ((i + dest_y) * 2) * source_rowstride + dest_x * 4,
dest_width);
fill_copy (source_tmp2,
source_data + ((i + dest_y) * 2 + 1) * source_rowstride + dest_x * 4,
dest_width);
}
source1 = source_tmp1;
source2 = source_tmp2;
dest = dest_row;
for (j = 0; j < dest_width * 4; j++)
*(dest++) = (*(source1++) + *(source2++)) / 2;
}
else
{
if (dest_texture_width < source_texture_width)
fill_scale_down (dest_row,
source_data + (i + dest_y) * source_rowstride + dest_x * 2 * 4,
dest_width * 2);
else
fill_copy (dest_row,
source_data + (i + dest_y) * source_rowstride,
dest_width);
}
}
cogl_texture_set_region (dest_texture,
0, 0,
dest_x, dest_y,
dest_width, dest_height,
dest_width, dest_height,
TEXTURE_FORMAT,
4 * dest_width,
dest_data);
if (dest_height < source_texture_height)
{
g_free (source_tmp1);
g_free (source_tmp2);
}
g_free (source_data);
g_free (dest_data);
}
static void
texture_tower_revalidate (MutterTextureTower *tower,
int level)
{
if (!texture_tower_revalidate_fbo (tower, level))
texture_tower_revalidate_client (tower, level);
}
/**
* mutter_texture_tower_get_paint_texture:
* @tower: a MutterTextureTower
*
* Gets the texture from the tower that best matches the current
* rendering scale. (On the assumption here the texture is going to
* be rendered with vertex coordinates that correspond to its
* size in pixels, so a 200x200 texture will be rendered on the
* rectangle (0, 0, 200, 200).
*
* Return value: the COGL texture handle to use for painting, or
* %COGL_INVALID_HANDLE if no base texture has yet been set.
*/
CoglHandle
mutter_texture_tower_get_paint_texture (MutterTextureTower *tower)
{
int texture_width, texture_height;
int level;
g_return_val_if_fail (tower != NULL, COGL_INVALID_HANDLE);
if (tower->textures[0] == COGL_INVALID_HANDLE)
return COGL_INVALID_HANDLE;
texture_width = cogl_texture_get_width (tower->textures[0]);
texture_height = cogl_texture_get_height (tower->textures[0]);
level = get_paint_level(texture_width, texture_height);
if (level < 0) /* singular paint matrix, scaled to nothing */
return COGL_INVALID_HANDLE;
level = MIN (level, tower->n_levels - 1);
if (tower->textures[level] == COGL_INVALID_HANDLE ||
(tower->invalid[level].x2 != tower->invalid[level].x1 &&
tower->invalid[level].y2 != tower->invalid[level].y1))
{
int i;
for (i = 1; i <= level; i++)
{
/* Use "floor" convention here to be consistent with the NPOT texture extension */
texture_width = MAX (1, texture_width / 2);
texture_height = MAX (1, texture_height / 2);
if (tower->textures[i] == COGL_INVALID_HANDLE)
texture_tower_create_texture (tower, i, texture_width, texture_height);
}
for (i = 1; i <= level; i++)
{
if (tower->invalid[level].x2 != tower->invalid[level].x1 &&
tower->invalid[level].y2 != tower->invalid[level].y1)
texture_tower_revalidate (tower, i);
}
}
return tower->textures[level];
}

View File

@@ -0,0 +1,69 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* MutterTextureTower
*
* Mipmap emulation by creation of scaled down images
*
* Copyright (C) 2009 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 __MUTTER_TEXTURE_TOWER_H__
#define __MUTTER_TEXTURE_TOWER_H__
#include <clutter/clutter.h>
G_BEGIN_DECLS
/**
* SECTION:MutterTextureTower
* @short_description: mipmap emulation by creation of scaled down images
*
* A #MutterTextureTower is used to get good looking scaled down images when
* we can't use the GL drivers mipmap support. There are two separate reasons
*
* - Some cards (including radeon cards <= r5xx) only support
* TEXTURE_RECTANGLE_ARB and not NPOT textures. Rectangular textures
* are defined not to support mipmapping.
* - Even when NPOT textures are available, the combination of NPOT
* textures, texture_from_pixmap, and mipmapping doesn't typically
* work, since the X server doesn't allocate pixmaps in the right
* layout for mipmapping.
*
* So, what we do is create the "mipmap" levels ourselves by successive
* power-of-two scaledowns, and when rendering pick the single texture
* that best matches the scale we are rendering at. (Since we aren't
* typically using perspective transforms, we'll frequently have a single
* scale for the entire texture.)
*/
typedef struct _MutterTextureTower MutterTextureTower;
MutterTextureTower *mutter_texture_tower_new (void);
void mutter_texture_tower_free (MutterTextureTower *tower);
void mutter_texture_tower_set_base_texture (MutterTextureTower *tower,
CoglHandle texture);
void mutter_texture_tower_update_area (MutterTextureTower *tower,
int x,
int y,
int width,
int height);
CoglHandle mutter_texture_tower_get_paint_texture (MutterTextureTower *tower);
G_BEGIN_DECLS
#endif /* __MUTTER_TEXTURE_TOWER_H__ */

View File

@@ -1,10 +1,13 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include <config.h>
#define _ISOC99_SOURCE /* for roundf */
#include <math.h>
#include "mutter-window-private.h"
#include "mutter-window-group.h"
#include "region.h"
struct _MutterWindowGroupClass
{
@@ -99,7 +102,7 @@ static void
mutter_window_group_paint (ClutterActor *actor)
{
MutterWindowGroup *window_group = MUTTER_WINDOW_GROUP (actor);
GdkRegion *visible_region;
MetaRegion *visible_region;
GdkRectangle screen_rect = { 0 };
GList *children, *l;
@@ -116,7 +119,7 @@ mutter_window_group_paint (ClutterActor *actor)
* optimization, however.)
*/
meta_screen_get_size (window_group->screen, &screen_rect.width, &screen_rect.height);
visible_region = gdk_region_rectangle (&screen_rect);
visible_region = meta_region_new_from_rectangle (&screen_rect);
for (l = children; l; l = l->next)
{
@@ -132,22 +135,22 @@ mutter_window_group_paint (ClutterActor *actor)
continue;
/* Temporarily move to the coordinate system of the actor */
gdk_region_offset (visible_region, - x, - y);
meta_region_translate (visible_region, - x, - y);
mutter_window_set_visible_region (cw, visible_region);
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (cw)) == 0xff)
{
GdkRegion *obscured_region = mutter_window_get_obscured_region (cw);
MetaRegion *obscured_region = mutter_window_get_obscured_region (cw);
if (obscured_region)
gdk_region_subtract (visible_region, obscured_region);
meta_region_subtract (visible_region, obscured_region);
}
mutter_window_set_visible_region_beneath (cw, visible_region);
gdk_region_offset (visible_region, x, y);
meta_region_translate (visible_region, x, y);
}
gdk_region_destroy (visible_region);
meta_region_destroy (visible_region);
CLUTTER_ACTOR_CLASS (mutter_window_group_parent_class)->paint (actor);

View File

@@ -3,9 +3,11 @@
#ifndef MUTTER_WINDOW_PRIVATE_H
#define MUTTER_WINDOW_PRIVATE_H
#include <config.h>
#include <X11/extensions/Xdamage.h>
#include <gdk/gdk.h>
#include "compositor-mutter.h"
#include "region.h"
MutterWindow *mutter_window_new (MetaWindow *window);
@@ -30,19 +32,18 @@ void mutter_window_pre_paint (MutterWindow *self);
gboolean mutter_window_effect_in_progress (MutterWindow *cw);
void mutter_window_sync_actor_position (MutterWindow *cw);
void mutter_window_sync_visibility (MutterWindow *cw);
void mutter_window_update_window_type (MutterWindow *cw);
void mutter_window_update_shape (MutterWindow *cw,
gboolean shaped);
void mutter_window_update_opacity (MutterWindow *cw);
void mutter_window_mapped (MutterWindow *cw);
void mutter_window_unmapped (MutterWindow *cw);
GdkRegion *mutter_window_get_obscured_region (MutterWindow *cw);
MetaRegion *mutter_window_get_obscured_region (MutterWindow *cw);
void mutter_window_set_visible_region (MutterWindow *cw,
GdkRegion *visible_region);
MetaRegion *visible_region);
void mutter_window_set_visible_region_beneath (MutterWindow *cw,
GdkRegion *beneath_region);
MetaRegion *beneath_region);
void mutter_window_reset_visible_regions (MutterWindow *cw);
void mutter_window_effect_completed (MutterWindow *actor,

View File

@@ -34,7 +34,6 @@ struct _MutterWindowPrivate
ClutterActor *shadow;
Pixmap back_pixmap;
MetaCompWindowType type;
Damage damage;
guint8 opacity;
@@ -42,10 +41,12 @@ struct _MutterWindowPrivate
gchar * desc;
/* If the window is shaped, a region that matches the shape */
GdkRegion *shape_region;
MetaRegion *shape_region;
/* A rectangular region with the unshaped extends of the window
* texture */
GdkRegion *bounding_region;
MetaRegion *bounding_region;
gint freeze_count;
/*
* These need to be counters rather than flags, since more plugins
@@ -65,7 +66,10 @@ struct _MutterWindowPrivate
guint disposed : 1;
guint redecorating : 1;
guint needs_repair : 1;
guint needs_damage_all : 1;
guint received_damage : 1;
guint needs_pixmap : 1;
guint needs_reshape : 1;
guint size_changed : 1;
@@ -272,9 +276,6 @@ mutter_meta_window_decorated_notify (MetaWindow *mw,
priv->damage = None;
}
g_hash_table_remove (info->windows_by_xid, (gpointer) priv->xwindow);
g_hash_table_insert (info->windows_by_xid, (gpointer) new_xwindow, self);
g_free (priv->desc);
priv->desc = NULL;
@@ -322,8 +323,6 @@ mutter_window_constructed (GObject *object)
compositor = meta_display_get_compositor (display);
mutter_window_update_window_type (self);
#ifdef HAVE_SHAPE
/* Listen for ShapeNotify events on the window */
if (meta_display_has_shape (display))
@@ -335,7 +334,8 @@ mutter_window_constructed (GObject *object)
if (priv->attrs.class == InputOnly)
priv->damage = None;
else
priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportNonEmpty);
priv->damage = XDamageCreate (xdisplay, xwindow,
XDamageReportBoundingBox);
format = XRenderFindVisualFormat (xdisplay, priv->attrs.visual);
@@ -355,10 +355,6 @@ mutter_window_constructed (GObject *object)
{
priv->actor = mutter_shaped_texture_new ();
if (!clutter_glx_texture_pixmap_using_extension (
CLUTTER_GLX_TEXTURE_PIXMAP (priv->actor)))
g_warning ("NOTE: Not using GLX TFP!\n");
clutter_container_add_actor (CLUTTER_CONTAINER (self), priv->actor);
/*
@@ -421,7 +417,6 @@ mutter_window_dispose (GObject *object)
}
info->windows = g_list_remove (info->windows, (gconstpointer) self);
g_hash_table_remove (info->windows_by_xid, (gpointer) priv->xwindow);
/*
* Release the extra reference we took on the actor.
@@ -537,13 +532,6 @@ mutter_window_get_property (GObject *object,
}
}
void
mutter_window_update_window_type (MutterWindow *self)
{
MutterWindowPrivate *priv = self->priv;
priv->type = (MetaCompWindowType) meta_window_get_window_type (priv->window);
}
static gboolean
is_shaped (MetaDisplay *display, Window xwindow)
{
@@ -567,6 +555,7 @@ static gboolean
mutter_window_has_shadow (MutterWindow *self)
{
MutterWindowPrivate * priv = self->priv;
MetaWindowType window_type = meta_window_get_window_type (priv->window);
if (priv->no_shadow)
return FALSE;
@@ -620,17 +609,17 @@ mutter_window_has_shadow (MutterWindow *self)
/*
* Don't put shadow around DND icon windows
*/
if (priv->type == META_COMP_WINDOW_DND ||
priv->type == META_COMP_WINDOW_DESKTOP)
if (window_type == META_WINDOW_DND ||
window_type == META_WINDOW_DESKTOP)
{
meta_verbose ("Window 0x%x has no shadow as it is DND or Desktop\n",
(guint)priv->xwindow);
return FALSE;
}
if (priv->type == META_COMP_WINDOW_MENU
if (window_type == META_WINDOW_MENU
#if 0
|| priv->type == META_COMP_WINDOW_DROPDOWN_MENU
|| window_type == META_WINDOW_DROPDOWN_MENU
#endif
)
{
@@ -640,7 +629,7 @@ mutter_window_has_shadow (MutterWindow *self)
}
#if 0
if (priv->type == META_COMP_WINDOW_TOOLTIP)
if (window_type == META_WINDOW_TOOLTIP)
{
meta_verbose ("Window 0x%x has shadow as it is a tooltip\n",
(guint)priv->xwindow);
@@ -653,6 +642,10 @@ mutter_window_has_shadow (MutterWindow *self)
return FALSE;
}
/**
* mutter_window_get_x_window: (skip)
*
*/
Window
mutter_window_get_x_window (MutterWindow *self)
{
@@ -688,15 +681,6 @@ mutter_window_get_texture (MutterWindow *self)
return self->priv->actor;
}
MetaCompWindowType
mutter_window_get_window_type (MutterWindow *self)
{
if (!self)
return 0;
return self->priv->type;
}
gboolean
mutter_window_is_override_redirect (MutterWindow *self)
{
@@ -722,6 +706,18 @@ const char *mutter_window_get_description (MutterWindow *self)
return self->priv->desc;
}
/**
* mutter_window_get_workspace:
* @mcw: #MutterWindow
*
* Returns the index of workspace on which this window is located; if the
* window is sticky, or is not currently located on any workspace, returns -1.
* This function is deprecated and should not be used in newly written code;
* meta_window_get_workspace() instead.
*
* Return value: (transfer none): index of workspace on which this window is
* located.
*/
gint
mutter_window_get_workspace (MutterWindow *self)
{
@@ -738,6 +734,9 @@ mutter_window_get_workspace (MutterWindow *self)
workspace = meta_window_get_workspace (priv->window);
if (!workspace)
return -1;
return meta_workspace_index (workspace);
}
@@ -754,6 +753,60 @@ mutter_window_showing_on_its_workspace (MutterWindow *self)
return meta_window_showing_on_its_workspace (self->priv->window);
}
static void
mutter_window_freeze (MutterWindow *self)
{
self->priv->freeze_count++;
}
static void
mutter_window_damage_all (MutterWindow *self)
{
MutterWindowPrivate *priv = self->priv;
ClutterX11TexturePixmap *texture_x11 = CLUTTER_X11_TEXTURE_PIXMAP (priv->actor);
guint pixmap_width = 0;
guint pixmap_height = 0;
if (!priv->needs_damage_all)
return;
g_object_get (texture_x11,
"pixmap-width", &pixmap_width,
"pixmap-height", &pixmap_height,
NULL);
clutter_x11_texture_pixmap_update_area (texture_x11,
0,
0,
pixmap_width,
pixmap_height);
priv->needs_damage_all = FALSE;
}
static void
mutter_window_thaw (MutterWindow *self)
{
self->priv->freeze_count--;
if (G_UNLIKELY (self->priv->freeze_count < 0))
{
g_warning ("Error in freeze/thaw accounting.");
self->priv->freeze_count = 0;
return;
}
if (self->priv->freeze_count)
return;
/* Since we ignore damage events while a window is frozen for certain effects
* we may need to issue an update_area() covering the whole pixmap if we
* don't know what real damage has happened. */
if (self->priv->needs_damage_all)
mutter_window_damage_all (self);
}
gboolean
mutter_window_effect_in_progress (MutterWindow *self)
{
@@ -765,11 +818,11 @@ mutter_window_effect_in_progress (MutterWindow *self)
}
static void
mutter_window_mark_for_repair (MutterWindow *self)
mutter_window_queue_create_pixmap (MutterWindow *self)
{
MutterWindowPrivate *priv = self->priv;
priv->needs_repair = TRUE;
priv->needs_pixmap = TRUE;
if (!priv->mapped)
return;
@@ -785,6 +838,21 @@ mutter_window_mark_for_repair (MutterWindow *self)
clutter_actor_queue_redraw (priv->actor);
}
static gboolean
is_freeze_thaw_effect (gulong event)
{
switch (event)
{
case MUTTER_PLUGIN_DESTROY:
case MUTTER_PLUGIN_MAXIMIZE:
case MUTTER_PLUGIN_UNMAXIMIZE:
return TRUE;
break;
default:
return FALSE;
}
}
static gboolean
start_simple_effect (MutterWindow *self,
gulong event)
@@ -792,6 +860,7 @@ start_simple_effect (MutterWindow *self,
MutterWindowPrivate *priv = self->priv;
MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen);
gint *counter = NULL;
gboolean use_freeze_thaw = FALSE;
if (!info->plugin_mgr)
return FALSE;
@@ -816,6 +885,11 @@ start_simple_effect (MutterWindow *self,
g_assert (counter);
use_freeze_thaw = is_freeze_thaw_effect (event);
if (use_freeze_thaw)
mutter_window_freeze (self);
(*counter)++;
if (!mutter_plugin_manager_event_simple (info->plugin_mgr,
@@ -823,6 +897,8 @@ start_simple_effect (MutterWindow *self,
event))
{
(*counter)--;
if (use_freeze_thaw)
mutter_window_thaw (self);
return FALSE;
}
@@ -846,7 +922,7 @@ mutter_window_after_effects (MutterWindow *self)
if (!meta_window_is_mapped (priv->window))
mutter_window_detach (self);
if (priv->needs_repair)
if (priv->needs_pixmap)
clutter_actor_queue_redraw (priv->actor);
}
@@ -915,6 +991,9 @@ mutter_window_effect_completed (MutterWindow *self,
break;
}
if (is_freeze_thaw_effect (event))
mutter_window_thaw (self);
if (!mutter_window_effect_in_progress (self))
mutter_window_after_effects (self);
}
@@ -935,12 +1014,19 @@ mutter_window_detach (MutterWindow *self)
if (!priv->back_pixmap)
return;
XFreePixmap (xdisplay, priv->back_pixmap);
priv->back_pixmap = None;
/* Get rid of all references to the pixmap before freeing it; it's unclear whether
* you are supposed to be able to free a GLXPixmap after freeing the underlying
* pixmap, but it certainly doesn't work with current DRI/Mesa
*/
clutter_x11_texture_pixmap_set_pixmap (CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
None);
mutter_shaped_texture_clear (MUTTER_SHAPED_TEXTURE (priv->actor));
cogl_flush();
mutter_window_mark_for_repair (self);
XFreePixmap (xdisplay, priv->back_pixmap);
priv->back_pixmap = None;
mutter_window_queue_create_pixmap (self);
}
void
@@ -949,10 +1035,12 @@ mutter_window_destroy (MutterWindow *self)
MetaWindow *window;
MetaCompScreen *info;
MutterWindowPrivate *priv;
MetaWindowType window_type;
priv = self->priv;
window = priv->window;
window_type = meta_window_get_window_type (window);
meta_window_set_compositor_private (window, NULL);
/*
@@ -961,15 +1049,14 @@ mutter_window_destroy (MutterWindow *self)
*/
info = meta_screen_get_compositor_data (priv->screen);
info->windows = g_list_remove (info->windows, (gconstpointer) self);
g_hash_table_remove (info->windows_by_xid, (gpointer)priv->xwindow);
if (priv->type == META_COMP_WINDOW_DROPDOWN_MENU ||
priv->type == META_COMP_WINDOW_POPUP_MENU ||
priv->type == META_COMP_WINDOW_TOOLTIP ||
priv->type == META_COMP_WINDOW_NOTIFICATION ||
priv->type == META_COMP_WINDOW_COMBO ||
priv->type == META_COMP_WINDOW_DND ||
priv->type == META_COMP_WINDOW_OVERRIDE_OTHER)
if (window_type == META_WINDOW_DROPDOWN_MENU ||
window_type == META_WINDOW_POPUP_MENU ||
window_type == META_WINDOW_TOOLTIP ||
window_type == META_WINDOW_NOTIFICATION ||
window_type == META_WINDOW_COMBO ||
window_type == META_WINDOW_DND ||
window_type == META_WINDOW_OVERRIDE_OTHER)
{
/*
* No effects, just kill it.
@@ -1004,7 +1091,7 @@ mutter_window_sync_actor_position (MutterWindow *self)
priv->attrs.height != window_rect.height)
{
priv->size_changed = TRUE;
mutter_window_mark_for_repair (self);
mutter_window_queue_create_pixmap (self);
}
/* XXX deprecated: please use meta_window_get_outer_rect instead */
@@ -1121,6 +1208,7 @@ mutter_window_maximize (MutterWindow *self,
clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height);
self->priv->maximize_in_progress++;
mutter_window_freeze (self);
if (!info->plugin_mgr ||
!mutter_plugin_manager_event_maximize (info->plugin_mgr,
@@ -1131,6 +1219,7 @@ mutter_window_maximize (MutterWindow *self,
{
self->priv->maximize_in_progress--;
mutter_window_thaw (self);
}
}
@@ -1148,6 +1237,7 @@ mutter_window_unmaximize (MutterWindow *self,
clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height);
self->priv->unmaximize_in_progress++;
mutter_window_freeze (self);
if (!info->plugin_mgr ||
!mutter_plugin_manager_event_maximize (info->plugin_mgr,
@@ -1157,6 +1247,7 @@ mutter_window_unmaximize (MutterWindow *self,
new_rect->width, new_rect->height))
{
self->priv->unmaximize_in_progress--;
mutter_window_thaw (self);
}
}
@@ -1195,6 +1286,8 @@ mutter_window_new (MetaWindow *window)
priv = self->priv;
priv->mapped = meta_window_toplevel_is_mapped (priv->window);
if (priv->mapped)
mutter_window_queue_create_pixmap (self);
mutter_window_sync_actor_position (self);
@@ -1209,7 +1302,6 @@ mutter_window_new (MetaWindow *window)
* before we first paint.
*/
info->windows = g_list_append (info->windows, self);
g_hash_table_insert (info->windows_by_xid, (gpointer) top_window, self);
return self;
}
@@ -1223,7 +1315,7 @@ mutter_window_mapped (MutterWindow *self)
priv->mapped = TRUE;
mutter_window_mark_for_repair (self);
mutter_window_queue_create_pixmap (self);
}
void
@@ -1239,7 +1331,7 @@ mutter_window_unmapped (MutterWindow *self)
return;
mutter_window_detach (self);
priv->needs_repair = FALSE;
priv->needs_pixmap = FALSE;
}
static void
@@ -1249,7 +1341,7 @@ mutter_window_clear_shape_region (MutterWindow *self)
if (priv->shape_region)
{
gdk_region_destroy (priv->shape_region);
meta_region_destroy (priv->shape_region);
priv->shape_region = NULL;
}
}
@@ -1261,7 +1353,7 @@ mutter_window_clear_bounding_region (MutterWindow *self)
if (priv->bounding_region)
{
gdk_region_destroy (priv->bounding_region);
meta_region_destroy (priv->bounding_region);
priv->bounding_region = NULL;
}
}
@@ -1276,7 +1368,7 @@ mutter_window_update_bounding_region (MutterWindow *self,
mutter_window_clear_bounding_region (self);
priv->bounding_region = gdk_region_rectangle (&bounding_rectangle);
priv->bounding_region = meta_region_new_from_rectangle (&bounding_rectangle);
}
static void
@@ -1289,11 +1381,11 @@ mutter_window_update_shape_region (MutterWindow *self,
mutter_window_clear_shape_region (self);
priv->shape_region = gdk_region_new ();
priv->shape_region = meta_region_new ();
for (i = 0; i < n_rects; i++)
{
GdkRectangle rect = { rects[i].x, rects[i].y, rects[i].width, rects[i].height };
gdk_region_union_with_rect (priv->shape_region, &rect);
meta_region_union_rectangle (priv->shape_region, &rect);
}
}
@@ -1307,7 +1399,7 @@ mutter_window_update_shape_region (MutterWindow *self,
* Return value: (transfer none): the area obscured by the window,
* %NULL is the same as an empty region.
*/
GdkRegion *
MetaRegion *
mutter_window_get_obscured_region (MutterWindow *self)
{
MutterWindowPrivate *priv = self->priv;
@@ -1326,13 +1418,13 @@ mutter_window_get_obscured_region (MutterWindow *self)
#if 0
/* Print out a region; useful for debugging */
static void
dump_region (GdkRegion *region)
dump_region (MetaRegion *region)
{
GdkRectangle *rects;
int n_rects;
int i;
gdk_region_get_rectangles (region, &rects, &n_rects);
meta_region_get_rectangles (region, &rects, &n_rects);
g_print ("[");
for (i = 0; i < n_rects; i++)
{
@@ -1356,10 +1448,10 @@ dump_region (GdkRegion *region)
*/
void
mutter_window_set_visible_region (MutterWindow *self,
GdkRegion *visible_region)
MetaRegion *visible_region)
{
MutterWindowPrivate *priv = self->priv;
GdkRegion *texture_clip_region = NULL;
MetaRegion *texture_clip_region = NULL;
/* Get the area of the window texture that would be drawn if
* we weren't obscured at all
@@ -1367,21 +1459,21 @@ mutter_window_set_visible_region (MutterWindow *self,
if (priv->shaped)
{
if (priv->shape_region)
texture_clip_region = gdk_region_copy (priv->shape_region);
texture_clip_region = meta_region_copy (priv->shape_region);
}
else
{
if (priv->bounding_region)
texture_clip_region = gdk_region_copy (priv->bounding_region);
texture_clip_region = meta_region_copy (priv->bounding_region);
}
if (!texture_clip_region)
texture_clip_region = gdk_region_new ();
texture_clip_region = meta_region_new ();
/* Then intersect that with the visible region to get the region
* that we actually need to redraw.
*/
gdk_region_intersect (texture_clip_region, visible_region);
meta_region_intersect (texture_clip_region, visible_region);
/* Assumes ownership */
mutter_shaped_texture_set_clip_region (MUTTER_SHAPED_TEXTURE (priv->actor),
@@ -1402,7 +1494,7 @@ mutter_window_set_visible_region (MutterWindow *self,
*/
void
mutter_window_set_visible_region_beneath (MutterWindow *self,
GdkRegion *beneath_region)
MetaRegion *beneath_region)
{
MutterWindowPrivate *priv = self->priv;
@@ -1410,7 +1502,7 @@ mutter_window_set_visible_region_beneath (MutterWindow *self,
{
GdkRectangle shadow_rect;
ClutterActorBox box;
GdkOverlapType overlap;
MetaOverlapType overlap;
/* We could compute an full clip region as we do for the window
* texture, but the shadow is relatively cheap to draw, and
@@ -1425,10 +1517,10 @@ mutter_window_set_visible_region_beneath (MutterWindow *self,
shadow_rect.width = roundf (box.x2 - box.x1);
shadow_rect.height = roundf (box.y2 - box.y1);
overlap = gdk_region_rect_in (beneath_region, &shadow_rect);
overlap = meta_region_contains_rectangle (beneath_region, &shadow_rect);
tidy_texture_frame_set_needs_paint (TIDY_TEXTURE_FRAME (priv->shadow),
overlap != GDK_OVERLAP_RECTANGLE_OUT);
overlap != META_REGION_OVERLAP_OUT);
}
}
@@ -1451,7 +1543,7 @@ mutter_window_reset_visible_regions (MutterWindow *self)
}
static void
check_needs_repair (MutterWindow *self)
check_needs_pixmap (MutterWindow *self)
{
MutterWindowPrivate *priv = self->priv;
MetaScreen *screen = priv->screen;
@@ -1462,7 +1554,7 @@ check_needs_repair (MutterWindow *self)
Window xwindow = priv->xwindow;
gboolean full = FALSE;
if (!priv->needs_repair)
if (!priv->needs_pixmap)
return;
if (!priv->mapped)
@@ -1509,17 +1601,21 @@ check_needs_repair (MutterWindow *self)
return;
}
/* MUST call before setting pixmap or serious performance issues
* seemingly caused by cogl_texture_set_filters() in set_filter
* Not sure if that call is actually needed.
*/
if (!compositor->no_mipmaps)
clutter_texture_set_filter_quality (CLUTTER_TEXTURE (priv->actor),
CLUTTER_TEXTURE_QUALITY_HIGH );
if (compositor->no_mipmaps)
mutter_shaped_texture_set_create_mipmaps (MUTTER_SHAPED_TEXTURE (priv->actor),
FALSE);
clutter_x11_texture_pixmap_set_pixmap
(CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
priv->back_pixmap);
/*
* This only works *after* actually setting the pixmap, so we have to
* do it here.
* See: http://bugzilla.clutter-project.org/show_bug.cgi?id=2236
*/
if (!clutter_glx_texture_pixmap_using_extension (
CLUTTER_GLX_TEXTURE_PIXMAP (priv->actor)))
g_warning ("NOTE: Not using GLX TFP!\n");
g_object_get (priv->actor,
"pixmap-width", &pxm_width,
@@ -1534,74 +1630,52 @@ check_needs_repair (MutterWindow *self)
full = TRUE;
}
/*
* TODO -- on some gfx hardware updating the whole texture instead of
* the individual rectangles is actually quicker, so we might want to
* make this a configurable option (on desktop HW with multiple pipelines
* it is usually quicker to just update the damaged parts).
*
* If we are using TFP we update the whole texture (this simply trigers
* the texture rebind).
*/
if (full
#ifdef HAVE_GLX_TEXTURE_PIXMAP
|| (CLUTTER_GLX_IS_TEXTURE_PIXMAP (priv->actor) &&
clutter_glx_texture_pixmap_using_extension
(CLUTTER_GLX_TEXTURE_PIXMAP (priv->actor)))
#endif /* HAVE_GLX_TEXTURE_PIXMAP */
)
{
XDamageSubtract (xdisplay, priv->damage, None, None);
clutter_x11_texture_pixmap_update_area
(CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
0,
0,
clutter_actor_get_width (priv->actor),
clutter_actor_get_height (priv->actor));
}
else
{
XRectangle *r_damage;
XRectangle r_bounds;
XserverRegion parts;
int i, r_count;
parts = XFixesCreateRegion (xdisplay, 0, 0);
XDamageSubtract (xdisplay, priv->damage, None, parts);
r_damage = XFixesFetchRegionAndBounds (xdisplay,
parts,
&r_count,
&r_bounds);
if (r_damage)
{
for (i = 0; i < r_count; ++i)
{
clutter_x11_texture_pixmap_update_area
(CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
r_damage[i].x,
r_damage[i].y,
r_damage[i].width,
r_damage[i].height);
}
}
XFree (r_damage);
XFixesDestroyRegion (xdisplay, parts);
}
meta_error_trap_pop (display, FALSE);
priv->needs_repair = FALSE;
priv->needs_pixmap = FALSE;
}
static gboolean
is_frozen (MutterWindow *self)
{
return self->priv->freeze_count ? TRUE : FALSE;
}
void
mutter_window_process_damage (MutterWindow *self,
XDamageNotifyEvent *event)
{
mutter_window_mark_for_repair (self);
MutterWindowPrivate *priv = self->priv;
ClutterX11TexturePixmap *texture_x11 = CLUTTER_X11_TEXTURE_PIXMAP (priv->actor);
priv->received_damage = TRUE;
if (is_frozen (self))
{
/* The window is frozen due to an effect in progress: we ignore damage
* here on the off chance that this will stop the corresponding
* texture_from_pixmap from being update.
*
* needs_damage_all tracks that some unknown damage happened while the
* window was frozen so that when the window becomes unfrozen we can
* issue a full window update to cover any lost damage.
*
* It should be noted that this is an unreliable mechanism since it's
* quite likely that drivers will aim to provide a zero-copy
* implementation of the texture_from_pixmap extension and in those cases
* any drawing done to the window is always immediately reflected in the
* texture regardless of damage event handling.
*/
priv->needs_damage_all = TRUE;
return;
}
clutter_x11_texture_pixmap_update_area (texture_x11,
event->area.x,
event->area.y,
event->area.width,
event->area.height);
}
void
@@ -1622,6 +1696,8 @@ static void
check_needs_reshape (MutterWindow *self)
{
MutterWindowPrivate *priv = self->priv;
MetaScreen *screen = priv->screen;
MetaDisplay *display = meta_screen_get_display (screen);
if (!priv->needs_reshape)
return;
@@ -1632,15 +1708,17 @@ check_needs_reshape (MutterWindow *self)
#ifdef HAVE_SHAPE
if (priv->shaped)
{
Display *xdisplay = meta_display_get_xdisplay (meta_window_get_display (priv->window));
Display *xdisplay = meta_display_get_xdisplay (display);
XRectangle *rects;
int n_rects, ordering;
meta_error_trap_push (display);
rects = XShapeGetRectangles (xdisplay,
priv->xwindow,
ShapeBounding,
&n_rects,
&ordering);
meta_error_trap_pop (display, TRUE);
if (rects)
{
@@ -1673,16 +1751,27 @@ void
mutter_window_pre_paint (MutterWindow *self)
{
MutterWindowPrivate *priv = self->priv;
MetaScreen *screen = priv->screen;
MetaDisplay *display = meta_screen_get_display (screen);
Display *xdisplay = meta_display_get_xdisplay (display);
/* The window is frozen due to a pending animation: we'll wait until
* the animation finishes to reshape and repair the window */
if (priv->destroy_in_progress ||
priv->maximize_in_progress ||
priv->unmaximize_in_progress)
return;
if (is_frozen (self))
{
/* The window is frozen due to a pending animation: we'll wait until
* the animation finishes to reshape and repair the window */
return;
}
if (priv->received_damage)
{
meta_error_trap_push (display);
XDamageSubtract (xdisplay, priv->damage, None, None);
meta_error_trap_pop (display, FALSE);
priv->received_damage = FALSE;
}
check_needs_reshape (self);
check_needs_repair (self);
check_needs_pixmap (self);
}
void

View File

@@ -22,6 +22,7 @@
*/
#include "mutter-plugin.h"
#include "window.h"
#include <libintl.h>
#define _(x) dgettext (GETTEXT_PACKAGE, x)
@@ -81,11 +82,12 @@ static void unmaximize (MutterPlugin *plugin,
gint x, gint y, gint width, gint height);
static void switch_workspace (MutterPlugin *plugin,
const GList **actors, gint from, gint to,
gint from, gint to,
MetaMotionDirection direction);
static void kill_effect (MutterPlugin *plugin,
MutterWindow *actor, gulong event);
static void kill_window_effects (MutterPlugin *plugin,
MutterWindow *actor);
static void kill_switch_workspace (MutterPlugin *plugin);
static const MutterPluginInfo * plugin_info (MutterPlugin *plugin);
@@ -99,7 +101,6 @@ struct _MutterDefaultPluginPrivate
/* Valid only when switch_workspace effect is in progress */
ClutterTimeline *tml_switch_workspace1;
ClutterTimeline *tml_switch_workspace2;
GList **actors;
ClutterActor *desktop1;
ClutterActor *desktop2;
@@ -175,10 +176,9 @@ mutter_default_plugin_get_property (GObject *object,
}
static void
mutter_default_plugin_constructed (GObject *object)
start (MutterPlugin *plugin)
{
MutterPlugin *plugin = MUTTER_PLUGIN (object);
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (object)->priv;
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
guint destroy_timeout = DESTROY_TIMEOUT;
guint minimize_timeout = MINIMIZE_TIMEOUT;
@@ -201,7 +201,6 @@ mutter_default_plugin_constructed (GObject *object)
map_timeout *= 2;
switch_timeout *= 2;
}
}
static void
@@ -212,18 +211,19 @@ mutter_default_plugin_class_init (MutterDefaultPluginClass *klass)
gobject_class->finalize = mutter_default_plugin_finalize;
gobject_class->dispose = mutter_default_plugin_dispose;
gobject_class->constructed = mutter_default_plugin_constructed;
gobject_class->set_property = mutter_default_plugin_set_property;
gobject_class->get_property = mutter_default_plugin_get_property;
plugin_class->start = start;
plugin_class->map = map;
plugin_class->minimize = minimize;
plugin_class->maximize = maximize;
plugin_class->unmaximize = unmaximize;
plugin_class->destroy = destroy;
plugin_class->switch_workspace = switch_workspace;
plugin_class->kill_effect = kill_effect;
plugin_class->plugin_info = plugin_info;
plugin_class->kill_window_effects = kill_window_effects;
plugin_class->kill_switch_workspace = kill_switch_workspace;
g_type_class_add_private (gobject_class, sizeof (MutterDefaultPluginPrivate));
}
@@ -272,20 +272,12 @@ get_actor_private (MutterWindow *actor)
return priv;
}
typedef struct SwitchWorkspaceData
{
MutterPlugin *plugin;
const GList **actors;
} SwitchWorkspaceData;
static void
on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
{
SwitchWorkspaceData *sw_data = data;
MutterPlugin *plugin = sw_data->plugin;
MutterPlugin *plugin = MUTTER_PLUGIN (data);
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
GList *l = *((GList**)sw_data->actors);
MutterWindow *actor_for_cb = l->data;
GList *l = mutter_plugin_get_windows (plugin);
while (l)
{
@@ -305,21 +297,17 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
clutter_actor_destroy (priv->desktop1);
clutter_actor_destroy (priv->desktop2);
priv->actors = NULL;
priv->tml_switch_workspace1 = NULL;
priv->tml_switch_workspace2 = NULL;
priv->desktop1 = NULL;
priv->desktop2 = NULL;
g_free (data);
mutter_plugin_effect_completed (plugin, actor_for_cb,
MUTTER_PLUGIN_SWITCH_WORKSPACE);
mutter_plugin_switch_workspace_completed (plugin);
}
static void
switch_workspace (MutterPlugin *plugin,
const GList **actors, gint from, gint to,
gint from, gint to,
MetaMotionDirection direction)
{
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
@@ -330,12 +318,8 @@ switch_workspace (MutterPlugin *plugin,
ClutterActor *stage;
int screen_width, screen_height;
MetaScreen *screen = mutter_plugin_get_screen (plugin);
SwitchWorkspaceData *sw_data = g_new (SwitchWorkspaceData, 1);
ClutterAnimation *animation;
sw_data->plugin = plugin;
sw_data->actors = actors;
stage = mutter_plugin_get_stage (plugin);
mutter_plugin_query_screen_size (plugin,
@@ -355,14 +339,13 @@ switch_workspace (MutterPlugin *plugin,
if (from == to)
{
mutter_plugin_effect_completed (plugin, NULL,
MUTTER_PLUGIN_SWITCH_WORKSPACE);
mutter_plugin_switch_workspace_completed (plugin);
return;
}
n_workspaces = meta_screen_get_n_workspaces (screen);
l = g_list_last (*((GList**) actors));
l = g_list_last (mutter_plugin_get_windows (plugin));
while (l)
{
@@ -397,7 +380,6 @@ switch_workspace (MutterPlugin *plugin,
l = l->prev;
}
priv->actors = (GList **)actors;
priv->desktop1 = workspace0;
priv->desktop2 = workspace1;
@@ -410,7 +392,7 @@ switch_workspace (MutterPlugin *plugin,
g_signal_connect (priv->tml_switch_workspace1,
"completed",
G_CALLBACK (on_switch_workspace_effect_complete),
sw_data);
plugin);
animation = clutter_actor_animate (workspace1, CLUTTER_EASE_IN_SINE,
SWITCH_TIMEOUT,
@@ -448,8 +430,7 @@ on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data
CLUTTER_GRAVITY_NORTH_WEST);
/* Now notify the manager that we are done with this effect */
mutter_plugin_effect_completed (plugin, mc_window,
MUTTER_PLUGIN_MINIMIZE);
mutter_plugin_minimize_completed (plugin, mc_window);
g_free (data);
}
@@ -461,12 +442,14 @@ on_minimize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data
static void
minimize (MutterPlugin *plugin, MutterWindow *mc_window)
{
MetaCompWindowType type;
MetaWindowType type;
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
type = mutter_window_get_window_type (mc_window);
if (type == META_COMP_WINDOW_NORMAL)
type = meta_window_get_window_type (meta_window);
if (type == META_WINDOW_NORMAL)
{
ClutterAnimation *animation;
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
@@ -492,8 +475,7 @@ minimize (MutterPlugin *plugin, MutterWindow *mc_window)
}
else
mutter_plugin_effect_completed (plugin, mc_window,
MUTTER_PLUGIN_MINIMIZE);
mutter_plugin_minimize_completed (plugin, mc_window);
}
/*
@@ -518,8 +500,7 @@ on_maximize_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data
CLUTTER_GRAVITY_NORTH_WEST);
/* Now notify the manager that we are done with this effect */
mutter_plugin_effect_completed (plugin, mc_window,
MUTTER_PLUGIN_MAXIMIZE);
mutter_plugin_maximize_completed (plugin, mc_window);
g_free (data);
}
@@ -537,17 +518,18 @@ maximize (MutterPlugin *plugin,
MutterWindow *mc_window,
gint end_x, gint end_y, gint end_width, gint end_height)
{
MetaCompWindowType type;
MetaWindowType type;
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
gdouble scale_x = 1.0;
gdouble scale_y = 1.0;
gfloat anchor_x = 0;
gfloat anchor_y = 0;
type = mutter_window_get_window_type (mc_window);
type = meta_window_get_window_type (meta_window);
if (type == META_COMP_WINDOW_NORMAL)
if (type == META_WINDOW_NORMAL)
{
ClutterAnimation *animation;
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
@@ -589,8 +571,7 @@ maximize (MutterPlugin *plugin,
return;
}
mutter_plugin_effect_completed (plugin, mc_window,
MUTTER_PLUGIN_MAXIMIZE);
mutter_plugin_maximize_completed (plugin, mc_window);
}
/*
@@ -603,9 +584,10 @@ unmaximize (MutterPlugin *plugin,
MutterWindow *mc_window,
gint end_x, gint end_y, gint end_width, gint end_height)
{
MetaCompWindowType type = mutter_window_get_window_type (mc_window);
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
MetaWindowType type = meta_window_get_window_type (meta_window);
if (type == META_COMP_WINDOW_NORMAL)
if (type == META_WINDOW_NORMAL)
{
ActorPrivate *apriv = get_actor_private (mc_window);
@@ -613,8 +595,7 @@ unmaximize (MutterPlugin *plugin,
}
/* Do this conditionally, if the effect requires completion callback. */
mutter_plugin_effect_completed (plugin, mc_window,
MUTTER_PLUGIN_UNMAXIMIZE);
mutter_plugin_unmaximize_completed (plugin, mc_window);
}
static void
@@ -633,7 +614,7 @@ on_map_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
CLUTTER_GRAVITY_NORTH_WEST);
/* Now notify the manager that we are done with this effect */
mutter_plugin_effect_completed (plugin, mc_window, MUTTER_PLUGIN_MAP);
mutter_plugin_map_completed (plugin, mc_window);
g_free (data);
}
@@ -645,12 +626,13 @@ on_map_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
static void
map (MutterPlugin *plugin, MutterWindow *mc_window)
{
MetaCompWindowType type;
MetaWindowType type;
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
type = mutter_window_get_window_type (mc_window);
type = meta_window_get_window_type (meta_window);
if (type == META_COMP_WINDOW_NORMAL)
if (type == META_WINDOW_NORMAL)
{
ClutterAnimation *animation;
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
@@ -679,8 +661,7 @@ map (MutterPlugin *plugin, MutterWindow *mc_window)
}
else
mutter_plugin_effect_completed (plugin, mc_window,
MUTTER_PLUGIN_MAP);
mutter_plugin_map_completed (plugin, mc_window);
}
/*
@@ -696,8 +677,7 @@ on_destroy_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
apriv->tml_destroy = NULL;
mutter_plugin_effect_completed (plugin, mc_window,
MUTTER_PLUGIN_DESTROY);
mutter_plugin_destroy_completed (plugin, mc_window);
}
/*
@@ -706,12 +686,13 @@ on_destroy_effect_complete (ClutterTimeline *timeline, EffectCompleteData *data)
static void
destroy (MutterPlugin *plugin, MutterWindow *mc_window)
{
MetaCompWindowType type;
MetaWindowType type;
ClutterActor *actor = CLUTTER_ACTOR (mc_window);
MetaWindow *meta_window = mutter_window_get_meta_window (mc_window);
type = mutter_window_get_window_type (mc_window);
type = meta_window_get_window_type (meta_window);
if (type == META_COMP_WINDOW_NORMAL)
if (type == META_WINDOW_NORMAL)
{
ClutterAnimation *animation;
EffectCompleteData *data = g_new0 (EffectCompleteData, 1);
@@ -734,54 +715,48 @@ destroy (MutterPlugin *plugin, MutterWindow *mc_window)
data);
}
else
mutter_plugin_effect_completed (plugin, mc_window,
MUTTER_PLUGIN_DESTROY);
mutter_plugin_destroy_completed (plugin, mc_window);
}
static void
kill_effect (MutterPlugin *plugin, MutterWindow *mc_window, gulong event)
kill_switch_workspace (MutterPlugin *plugin)
{
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
if (priv->tml_switch_workspace1)
{
clutter_timeline_stop (priv->tml_switch_workspace1);
clutter_timeline_stop (priv->tml_switch_workspace2);
g_signal_emit_by_name (priv->tml_switch_workspace1, "completed", NULL);
}
}
static void
kill_window_effects (MutterPlugin *plugin, MutterWindow *mc_window)
{
ActorPrivate *apriv;
if (event & MUTTER_PLUGIN_SWITCH_WORKSPACE)
{
MutterDefaultPluginPrivate *priv = MUTTER_DEFAULT_PLUGIN (plugin)->priv;
if (priv->tml_switch_workspace1)
{
clutter_timeline_stop (priv->tml_switch_workspace1);
clutter_timeline_stop (priv->tml_switch_workspace2);
g_signal_emit_by_name (priv->tml_switch_workspace1, "completed", NULL);
}
if (!(event & ~MUTTER_PLUGIN_SWITCH_WORKSPACE))
{
/* Workspace switch only, nothing more to do */
return;
}
}
apriv = get_actor_private (mc_window);
if ((event & MUTTER_PLUGIN_MINIMIZE) && apriv->tml_minimize)
if (apriv->tml_minimize)
{
clutter_timeline_stop (apriv->tml_minimize);
g_signal_emit_by_name (apriv->tml_minimize, "completed", NULL);
}
if ((event & MUTTER_PLUGIN_MAXIMIZE) && apriv->tml_maximize)
if (apriv->tml_maximize)
{
clutter_timeline_stop (apriv->tml_maximize);
g_signal_emit_by_name (apriv->tml_maximize, "completed", NULL);
}
if ((event & MUTTER_PLUGIN_MAP) && apriv->tml_map)
if (apriv->tml_map)
{
clutter_timeline_stop (apriv->tml_map);
g_signal_emit_by_name (apriv->tml_map, "completed", NULL);
}
if ((event & MUTTER_PLUGIN_DESTROY) && apriv->tml_destroy)
if (apriv->tml_destroy)
{
clutter_timeline_stop (apriv->tml_destroy);
g_signal_emit_by_name (apriv->tml_destroy, "completed", NULL);

View File

@@ -155,7 +155,7 @@ tidy_texture_frame_unrealize (ClutterActor *self)
if (priv->material == COGL_INVALID_HANDLE)
return;
cogl_material_unref (priv->material);
cogl_handle_unref (priv->material);
priv->material = COGL_INVALID_HANDLE;
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
@@ -415,7 +415,7 @@ tidy_texture_frame_dispose (GObject *gobject)
if (priv->material)
{
cogl_material_unref (priv->material);
cogl_handle_unref (priv->material);
priv->material = COGL_INVALID_HANDLE;
}

View File

@@ -1,138 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Metacity Alt-Tab abstraction */
/*
* Copyright (C) 2009 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.
*/
#include <config.h>
#include "alttabhandlerdefault.h"
#include "screen-private.h"
static GType handler_type = G_TYPE_INVALID;
GType meta_alt_tab_handler_default_get_type (void);
void
meta_alt_tab_handler_register (GType type)
{
handler_type = type;
}
MetaAltTabHandler *
meta_alt_tab_handler_new (MetaScreen *screen,
gboolean immediate)
{
if (handler_type == G_TYPE_INVALID)
handler_type = meta_alt_tab_handler_default_get_type ();
return g_object_new (handler_type,
"screen", screen,
"immediate", immediate,
NULL);
}
static void meta_alt_tab_handler_class_init (GObjectClass *object_class);
GType
meta_alt_tab_handler_get_type (void)
{
static volatile gsize g_define_type_id__volatile = 0;
if (g_once_init_enter (&g_define_type_id__volatile))
{
const GTypeInfo type_info =
{
sizeof (MetaAltTabHandlerInterface), /* class_size */
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc)meta_alt_tab_handler_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
0,
0, /* n_preallocs */
NULL
};
GType g_define_type_id =
g_type_register_static (G_TYPE_INTERFACE, "MetaAltTabHandler",
&type_info, 0);
g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
}
return g_define_type_id__volatile;
}
static void
meta_alt_tab_handler_class_init (GObjectClass *object_class)
{
g_object_interface_install_property (object_class,
g_param_spec_object ("screen",
"Screen",
"MetaScreen this is the switcher for",
META_TYPE_SCREEN,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property (object_class,
g_param_spec_boolean ("immediate",
"Immediate mode",
"Whether or not to select windows immediately",
FALSE,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
}
void
meta_alt_tab_handler_add_window (MetaAltTabHandler *handler,
MetaWindow *window)
{
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->add_window (handler, window);
}
void
meta_alt_tab_handler_show (MetaAltTabHandler *handler,
MetaWindow *initial_selection)
{
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->show (handler,
initial_selection);
}
void
meta_alt_tab_handler_destroy (MetaAltTabHandler *handler)
{
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->destroy (handler);
}
void
meta_alt_tab_handler_forward (MetaAltTabHandler *handler)
{
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->forward (handler);
}
void
meta_alt_tab_handler_backward (MetaAltTabHandler *handler)
{
META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->backward (handler);
}
MetaWindow *
meta_alt_tab_handler_get_selected (MetaAltTabHandler *handler)
{
return META_ALT_TAB_HANDLER_GET_INTERFACE (handler)->get_selected (handler);
}

View File

@@ -1,223 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Metacity Alt-Tab abstraction: default implementation */
/*
* Copyright (C) 2009 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.
*/
#include <config.h>
#include "alttabhandlerdefault.h"
#include "frame-private.h"
#include "window-private.h"
static void meta_alt_tab_handler_default_interface_init (MetaAltTabHandlerInterface *handler_iface);
G_DEFINE_TYPE_WITH_CODE (MetaAltTabHandlerDefault, meta_alt_tab_handler_default, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (META_TYPE_ALT_TAB_HANDLER,
meta_alt_tab_handler_default_interface_init))
enum {
PROP_SCREEN = 1,
PROP_IMMEDIATE
};
static void
meta_alt_tab_handler_default_init (MetaAltTabHandlerDefault *hd)
{
hd->entries = g_array_new (FALSE, FALSE, sizeof (MetaTabEntry));
}
static void
meta_alt_tab_handler_default_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (object);
switch (prop_id)
{
case PROP_SCREEN:
hd->screen = g_value_get_object (value);
break;
case PROP_IMMEDIATE:
hd->immediate_mode = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_alt_tab_handler_default_finalize (GObject *object)
{
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (object);
g_array_free (hd->entries, TRUE);
if (hd->tab_popup)
meta_ui_tab_popup_free (hd->tab_popup);
G_OBJECT_CLASS (meta_alt_tab_handler_default_parent_class)->finalize (object);
}
static void
meta_alt_tab_handler_default_add_window (MetaAltTabHandler *handler,
MetaWindow *window)
{
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
MetaTabEntry entry;
MetaRectangle r;
entry.key = (MetaTabEntryKey) window;
entry.title = window->title;
entry.icon = window->icon;
entry.blank = FALSE;
entry.hidden = !meta_window_showing_on_its_workspace (window);
entry.demands_attention = window->wm_state_demands_attention;
if (hd->immediate_mode || !entry.hidden ||
!meta_window_get_icon_geometry (window, &r))
meta_window_get_outer_rect (window, &r);
entry.rect = r;
/* Find inside of highlight rectangle to be used when window is
* outlined for tabbing. This should be the size of the
* east/west frame, and the size of the south frame, on those
* sides. On the top it should be the size of the south frame
* edge.
*/
#define OUTLINE_WIDTH 5
/* Top side */
if (!entry.hidden &&
window->frame && window->frame->bottom_height > 0 &&
window->frame->child_y >= window->frame->bottom_height)
entry.inner_rect.y = window->frame->bottom_height;
else
entry.inner_rect.y = OUTLINE_WIDTH;
/* Bottom side */
if (!entry.hidden &&
window->frame && window->frame->bottom_height != 0)
entry.inner_rect.height = r.height
- entry.inner_rect.y - window->frame->bottom_height;
else
entry.inner_rect.height = r.height
- entry.inner_rect.y - OUTLINE_WIDTH;
/* Left side */
if (!entry.hidden && window->frame && window->frame->child_x != 0)
entry.inner_rect.x = window->frame->child_x;
else
entry.inner_rect.x = OUTLINE_WIDTH;
/* Right side */
if (!entry.hidden &&
window->frame && window->frame->right_width != 0)
entry.inner_rect.width = r.width
- entry.inner_rect.x - window->frame->right_width;
else
entry.inner_rect.width = r.width
- entry.inner_rect.x - OUTLINE_WIDTH;
g_array_append_val (hd->entries, entry);
}
static void
meta_alt_tab_handler_default_show (MetaAltTabHandler *handler,
MetaWindow *initial_selection)
{
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
if (hd->tab_popup)
return;
hd->tab_popup = meta_ui_tab_popup_new ((MetaTabEntry *)hd->entries->data,
hd->screen->number,
hd->entries->len,
5, /* FIXME */
TRUE);
meta_ui_tab_popup_select (hd->tab_popup, (MetaTabEntryKey) initial_selection);
meta_ui_tab_popup_set_showing (hd->tab_popup, !hd->immediate_mode);
}
static void
meta_alt_tab_handler_default_destroy (MetaAltTabHandler *handler)
{
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
if (hd->tab_popup)
{
meta_ui_tab_popup_free (hd->tab_popup);
hd->tab_popup = NULL;
}
}
static void
meta_alt_tab_handler_default_forward (MetaAltTabHandler *handler)
{
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
if (hd->tab_popup)
meta_ui_tab_popup_forward (hd->tab_popup);
}
static void
meta_alt_tab_handler_default_backward (MetaAltTabHandler *handler)
{
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
if (hd->tab_popup)
meta_ui_tab_popup_backward (hd->tab_popup);
}
static MetaWindow *
meta_alt_tab_handler_default_get_selected (MetaAltTabHandler *handler)
{
MetaAltTabHandlerDefault *hd = META_ALT_TAB_HANDLER_DEFAULT (handler);
if (hd->tab_popup)
return (MetaWindow *)meta_ui_tab_popup_get_selected (hd->tab_popup);
else
return NULL;
}
static void
meta_alt_tab_handler_default_class_init (MetaAltTabHandlerDefaultClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = meta_alt_tab_handler_default_set_property;
object_class->finalize = meta_alt_tab_handler_default_finalize;
g_object_class_override_property (object_class, PROP_SCREEN, "screen");
g_object_class_override_property (object_class, PROP_IMMEDIATE, "immediate");
}
static void
meta_alt_tab_handler_default_interface_init (MetaAltTabHandlerInterface *handler_iface)
{
handler_iface->add_window = meta_alt_tab_handler_default_add_window;
handler_iface->show = meta_alt_tab_handler_default_show;
handler_iface->destroy = meta_alt_tab_handler_default_destroy;
handler_iface->forward = meta_alt_tab_handler_default_forward;
handler_iface->backward = meta_alt_tab_handler_default_backward;
handler_iface->get_selected = meta_alt_tab_handler_default_get_selected;
}

View File

@@ -52,6 +52,9 @@
#include "bell.h"
#include "screen-private.h"
#include "prefs.h"
#ifdef HAVE_LIBCANBERRA
#include <canberra-gtk.h>
#endif
/**
* Flashes one entire screen. This is done by making a window the size of the
@@ -228,18 +231,18 @@ bell_flash_window_frame (MetaWindow *window)
*/
static void
bell_flash_frame (MetaDisplay *display,
XkbAnyEvent *xkb_ev)
XkbAnyEvent *xkb_ev)
{
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
MetaWindow *window;
g_assert (xkb_ev->xkb_type == XkbBellNotify);
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
if (!window && (display->focus_window) && (display->focus_window->frame))
if (!window && (display->focus_window))
{
window = display->focus_window;
}
if (window)
if (window && window->frame)
{
bell_flash_window_frame (window);
}
@@ -285,6 +288,48 @@ meta_bell_notify (MetaDisplay *display,
/* flash something */
if (meta_prefs_get_visual_bell ())
bell_visual_notify (display, xkb_ev);
#ifdef HAVE_LIBCANBERRA
if (meta_prefs_bell_is_audible ())
{
ca_proplist *p;
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
MetaWindow *window;
int res;
ca_proplist_create (&p);
ca_proplist_sets (p, CA_PROP_EVENT_ID, "bell-window-system");
ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
if (!window && (display->focus_window) && (display->focus_window->frame))
window = display->focus_window;
if (window)
{
ca_proplist_sets (p, CA_PROP_WINDOW_NAME, window->title);
ca_proplist_setf (p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long)window->xwindow);
ca_proplist_sets (p, CA_PROP_APPLICATION_NAME, window->res_name);
ca_proplist_setf (p, CA_PROP_APPLICATION_PROCESS_ID, "%d", window->net_wm_pid);
}
/* First, we try to play a real sound ... */
res = ca_context_play_full (ca_gtk_context_get (), 1, p, NULL, NULL);
ca_proplist_destroy (p);
if (res != CA_SUCCESS && res != CA_ERROR_DISABLED)
{
/* ...and in case that failed we use the classic X11 bell. */
XkbForceDeviceBell (display->xdisplay,
xkb_bell_event->device,
xkb_bell_event->bell_class,
xkb_bell_event->bell_id,
xkb_bell_event->percent);
}
}
#endif /* HAVE_LIBCANBERRA */
}
#endif /* HAVE_XKB */
@@ -292,11 +337,19 @@ void
meta_bell_set_audible (MetaDisplay *display, gboolean audible)
{
#ifdef HAVE_XKB
#ifdef HAVE_LIBCANBERRA
/* When we are playing sounds using libcanberra support, we handle the
* bell whether its an audible bell or a visible bell */
gboolean enable_system_bell = FALSE;
#else
gboolean enable_system_bell = audible;
#endif /* HAVE_LIBCANBERRA */
XkbChangeEnabledControls (display->xdisplay,
XkbUseCoreKbd,
XkbAudibleBellMask,
audible ? XkbAudibleBellMask : 0);
#endif
XkbUseCoreKbd,
XkbAudibleBellMask,
enable_system_bell ? XkbAudibleBellMask : 0);
#endif /* HAVE_XKB */
}
gboolean
@@ -323,11 +376,7 @@ meta_bell_init (MetaDisplay *display)
XkbUseCoreKbd,
XkbBellNotifyMask,
XkbBellNotifyMask);
XkbChangeEnabledControls (display->xdisplay,
XkbUseCoreKbd,
XkbAudibleBellMask,
meta_prefs_bell_is_audible ()
? XkbAudibleBellMask : 0);
meta_bell_set_audible (display, meta_prefs_bell_is_audible ());
if (visual_bell_auto_reset) {
XkbSetAutoResetControls (display->xdisplay,
XkbAudibleBellMask,

View File

@@ -30,6 +30,35 @@
#include "util.h"
#include <X11/Xutil.h> /* Just for the definition of the various gravities */
/* It would make sense to use GSlice here, but until we clean up the
* rest of this file and the internal API to use these functions, we
* leave it using g_malloc()/g_free() for consistency.
*/
MetaRectangle *
meta_rectangle_copy (const MetaRectangle *rect)
{
return g_memdup (rect, sizeof (MetaRectangle));
}
void
meta_rectangle_free (MetaRectangle *rect)
{
g_free (rect);
}
GType
meta_rectangle_get_type (void)
{
static GType type_id = 0;
if (!type_id)
type_id = g_boxed_type_register_static (g_intern_static_string ("MetaRectangle"),
(GBoxedCopyFunc) meta_rectangle_copy,
(GBoxedFreeFunc) meta_rectangle_free);
return type_id;
}
char*
meta_rectangle_to_string (const MetaRectangle *rect,
char *output)
@@ -500,7 +529,12 @@ compare_rect_areas (gconstpointer a, gconstpointer b)
return b_area - a_area; /* positive ret value denotes b > a, ... */
}
/* This function is trying to find a "minimal spanning set (of rectangles)"
/**
* meta_rectangle_get_minimal_spanning_set_for_region:
* @basic_rect: Input rectangle
* @all_struts: (element-type Meta.Rectangle): List of struts
*
* This function is trying to find a "minimal spanning set (of rectangles)"
* for a given region.
*
* The region is given by taking basic_rect, then removing the areas
@@ -513,10 +547,7 @@ compare_rect_areas (gconstpointer a, gconstpointer b)
* the region if and only if it is contained within at least one of the
* rectangles.
*
* The GList* returned will be a list of (allocated) MetaRectangles.
* The list will need to be freed by calling
* meta_rectangle_free_spanning_set() on it (or by manually
* implementing that function...)
* Returns: (transfer full) (element-type Meta.Rectangle): Minimal spanning set
*/
GList*
meta_rectangle_get_minimal_spanning_set_for_region (
@@ -649,6 +680,10 @@ meta_rectangle_get_minimal_spanning_set_for_region (
return ret;
}
/**
* meta_rectangle_expand_region: (skip)
*
*/
GList*
meta_rectangle_expand_region (GList *region,
const int left_expand,
@@ -665,6 +700,10 @@ meta_rectangle_expand_region (GList *region,
0);
}
/**
* meta_rectangle_expand_region_conditionally: (skip)
*
*/
GList*
meta_rectangle_expand_region_conditionally (GList *region,
const int left_expand,
@@ -1642,7 +1681,10 @@ fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
}
}
/* This function removes intersections of edges with the rectangles from the
/**
* meta_rectangle_remove_intersections_with_boxes_from_edges: (skip)
*
* This function removes intersections of edges with the rectangles from the
* list of edges.
*/
GList*
@@ -1708,7 +1750,11 @@ meta_rectangle_remove_intersections_with_boxes_from_edges (
return edges;
}
/* This function is trying to find all the edges of an onscreen region. */
/**
* meta_rectangle_find_onscreen_edges: (skip)
*
* This function is trying to find all the edges of an onscreen region.
*/
GList*
meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
const GSList *all_struts)
@@ -1791,6 +1837,10 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
return ret;
}
/**
* meta_rectangle_find_nonintersected_monitor_edges: (skip)
*
*/
GList*
meta_rectangle_find_nonintersected_monitor_edges (
const GList *monitor_rects,

View File

@@ -27,6 +27,7 @@
#include "constraints.h"
#include "workspace-private.h"
#include "place.h"
#include "prefs.h"
#include <stdlib.h>
#include <math.h>
@@ -97,6 +98,7 @@ typedef enum
PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1,
PRIORITY_SIZE_HINTS_INCREMENTS = 1,
PRIORITY_MAXIMIZATION = 2,
PRIORITY_TILING = 2,
PRIORITY_FULLSCREEN = 2,
PRIORITY_SIZE_HINTS_LIMITS = 3,
PRIORITY_TITLEBAR_VISIBLE = 4,
@@ -139,11 +141,18 @@ typedef struct
GList *usable_screen_region;
GList *usable_monitor_region;
} ConstraintInfo;
static gboolean constrain_modal_dialog (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
gboolean check_only);
static gboolean constrain_maximization (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
gboolean check_only);
static gboolean constrain_tiling (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
gboolean check_only);
static gboolean constrain_fullscreen (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
@@ -209,7 +218,9 @@ typedef struct {
} Constraint;
static const Constraint all_constraints[] = {
{constrain_modal_dialog, "constrain_modal_dialog"},
{constrain_maximization, "constrain_maximization"},
{constrain_tiling, "constrain_tiling"},
{constrain_fullscreen, "constrain_fullscreen"},
{constrain_size_increments, "constrain_size_increments"},
{constrain_size_limits, "constrain_size_limits"},
@@ -424,7 +435,8 @@ setup_constraint_info (ConstraintInfo *info,
/* Workaround braindead legacy apps that don't know how to
* fullscreen themselves properly.
*/
if (meta_rectangle_equal (new, &monitor_info->rect) &&
if (meta_prefs_get_force_fullscreen() &&
meta_rectangle_equal (new, &monitor_info->rect) &&
window->has_fullscreen_func &&
!window->fullscreen)
{
@@ -526,10 +538,11 @@ place_window_if_needed(MetaWindow *window,
if (window->placed || did_placement)
{
if (window->maximize_horizontally_after_placement ||
window->maximize_vertically_after_placement)
window->maximize_vertically_after_placement ||
window->fullscreen_after_placement)
{
/* define a sane saved_rect so that the user can unmaximize to
* something reasonable.
/* define a sane saved_rect so that the user can unmaximize or
* make unfullscreen to something reasonable.
*/
if (info->current.width >= info->work_area_monitor.width)
{
@@ -556,6 +569,15 @@ place_window_if_needed(MetaWindow *window,
if (window->frame && !window->fullscreen)
meta_frame_calc_geometry (window->frame, info->fgeom);
if (window->fullscreen_after_placement)
{
window->saved_rect = info->current;
window->fullscreen = TRUE;
window->fullscreen_after_placement = FALSE;
g_object_notify (G_OBJECT (window), "fullscreen");
}
window->maximize_horizontally_after_placement = FALSE;
window->maximize_vertically_after_placement = FALSE;
}
@@ -714,6 +736,48 @@ get_size_limits (const MetaWindow *window,
}
}
static gboolean
constrain_modal_dialog (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
gboolean check_only)
{
int x, y;
MetaWindow *parent = meta_window_get_transient_for (window);
gboolean constraint_already_satisfied;
if (!meta_prefs_get_attach_modal_dialogs ())
return TRUE;
if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
return TRUE;
x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2);
y = 0;
if (parent->frame)
{
MetaFrameGeometry fgeom;
x += parent->frame->rect.x;
y += parent->frame->rect.y;
meta_frame_calc_geometry (parent->frame, &fgeom);
y += fgeom.top_height;
y += info->fgeom->top_height;
}
else
y = parent->rect.y + info->fgeom->top_height;
constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
if (check_only || constraint_already_satisfied)
return constraint_already_satisfied;
info->current.y = y;
info->current.x = x;
return TRUE;
}
static gboolean
constrain_maximization (MetaWindow *window,
ConstraintInfo *info,
@@ -730,7 +794,8 @@ constrain_maximization (MetaWindow *window,
return TRUE;
/* Determine whether constraint applies; exit if it doesn't */
if (!window->maximized_horizontally && !window->maximized_vertically)
if ((!window->maximized_horizontally && !window->maximized_vertically) ||
META_WINDOW_TILED (window))
return TRUE;
/* Calculate target_size = maximized size of (window + frame) */
@@ -798,6 +863,59 @@ constrain_maximization (MetaWindow *window,
return TRUE;
}
static gboolean
constrain_tiling (MetaWindow *window,
ConstraintInfo *info,
ConstraintPriority priority,
gboolean check_only)
{
MetaRectangle target_size;
MetaRectangle min_size, max_size;
gboolean hminbad, vminbad;
gboolean horiz_equal, vert_equal;
gboolean constraint_already_satisfied;
if (priority > PRIORITY_TILING)
return TRUE;
/* Determine whether constraint applies; exit if it doesn't */
if (!META_WINDOW_TILED (window))
return TRUE;
/* Calculate target_size - as the tile previews need this as well, we
* use an external function for the actual calculation
*/
meta_window_get_current_tile_area (window, &target_size);
unextend_by_frame (&target_size, info->fgeom);
/* Check min size constraints; max size constraints are ignored as for
* maximized windows.
*/
get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
hminbad = target_size.width < min_size.width;
vminbad = target_size.height < min_size.height;
if (hminbad || vminbad)
return TRUE;
/* Determine whether constraint is already satisfied; exit if it is */
horiz_equal = target_size.x == info->current.x &&
target_size.width == info->current.width;
vert_equal = target_size.y == info->current.y &&
target_size.height == info->current.height;
constraint_already_satisfied = horiz_equal && vert_equal;
if (check_only || constraint_already_satisfied)
return constraint_already_satisfied;
/*** Enforce constraint ***/
info->current.x = target_size.x;
info->current.width = target_size.width;
info->current.y = target_size.y;
info->current.height = target_size.height;
return TRUE;
}
static gboolean
constrain_fullscreen (MetaWindow *window,
ConstraintInfo *info,
@@ -849,7 +967,7 @@ constrain_size_increments (MetaWindow *window,
/* Determine whether constraint applies; exit if it doesn't */
if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
info->action_type == ACTION_MOVE)
META_WINDOW_TILED (window) || info->action_type == ACTION_MOVE)
return TRUE;
/* Determine whether constraint is already satisfied; exit if it is */
@@ -980,7 +1098,7 @@ constrain_aspect_ratio (MetaWindow *window,
constraints_are_inconsistent = minr > maxr;
if (constraints_are_inconsistent ||
META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
info->action_type == ACTION_MOVE)
META_WINDOW_TILED (window) || info->action_type == ACTION_MOVE)
return TRUE;
/* Determine whether constraint is already satisfied; exit if it is. We

View File

@@ -28,6 +28,7 @@
#include "frame-private.h"
#include "workspace-private.h"
#include "prefs.h"
#include "errors.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.
@@ -260,15 +261,14 @@ meta_core_user_raise (Display *xdisplay,
meta_window_raise (window);
}
void
meta_core_user_lower_and_unfocus (Display *xdisplay,
Window frame_xwindow,
guint32 timestamp)
static gboolean
lower_window_and_transients (MetaWindow *window,
gpointer data)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_lower (window);
meta_window_foreach_transient (window, lower_window_and_transients, NULL);
if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
meta_prefs_get_raise_on_click ())
{
@@ -296,11 +296,59 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
}
}
/* focus the default window, if needed */
if (window->has_focus)
meta_workspace_focus_default_window (window->screen->active_workspace,
NULL,
timestamp);
return FALSE;
}
void
meta_core_user_lower_and_unfocus (Display *xdisplay,
Window frame_xwindow,
guint32 timestamp)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
lower_window_and_transients (window, NULL);
/* Rather than try to figure that out whether we just lowered
* the focus window, assume that's always the case. (Typically,
* this will be invoked via keyboard action or by a mouse action;
* in either case the window or a modal child will have been focused.) */
meta_workspace_focus_default_window (window->screen->active_workspace,
NULL,
timestamp);
}
void
meta_core_lower_beneath_focus_window (Display *xdisplay,
Window xwindow,
guint32 timestamp)
{
XWindowChanges changes;
MetaDisplay *display;
MetaScreen *screen;
MetaWindow *focus_window;
display = meta_display_for_x_display (xdisplay);
screen = meta_display_screen_for_xwindow (display, xwindow);
focus_window = meta_stack_get_top (screen->stack);
if (focus_window == NULL)
return;
changes.stack_mode = Below;
changes.sibling = focus_window->frame ? focus_window->frame->xwindow
: focus_window->xwindow;
meta_stack_tracker_record_lower_below (screen->stack_tracker,
xwindow,
changes.sibling,
XNextRequest (screen->display->xdisplay));
meta_error_trap_push (display);
XConfigureWindow (xdisplay,
xwindow,
CWSibling | CWStackMode,
&changes);
meta_error_trap_pop (display, FALSE);
}
void
@@ -526,6 +574,9 @@ meta_core_get_menu_accelerator (MetaMenuOp menu_op,
switch (menu_op)
{
case META_MENU_OP_NONE:
/* No keybinding for this one */
break;
case META_MENU_OP_DELETE:
name = "close";
break;

View File

@@ -22,8 +22,7 @@
* 02111-1307, USA.
*/
#define _GNU_SOURCE
#define _SVID_SOURCE /* for gethostname() */
#define _XOPEN_SOURCE /* for kill() */
#include <config.h>
#include "util.h"
@@ -32,6 +31,7 @@
#include "workspace.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
@@ -55,27 +55,16 @@ delete_ping_reply_func (MetaDisplay *display,
/* we do nothing */
}
static gboolean
delete_window_callback (gpointer w_p)
{
meta_window_kill ((MetaWindow*) w_p);
return FALSE; /* don't do it again */
}
static void
sigchld_handler (MetaNexus *nexus, guint arg1, gpointer arg2, gpointer user_data)
dialog_exited (GPid pid, int status, gpointer user_data)
{
MetaWindow *ours = (MetaWindow*) user_data;
if (GPOINTER_TO_INT (arg2) == ours->dialog_pid)
{
if (arg1 == 1 /* pressed "force quit" */)
g_idle_add_full (G_PRIORITY_DEFAULT,
delete_window_callback, user_data, NULL);
ours->dialog_pid = -1;
ours->dialog_pid = -1; /* forget it anyway */
}
/* exit status of 1 means the user pressed "Force Quit" */
if (WIFEXITED (status) && WEXITSTATUS (status) == 1)
meta_window_kill (ours);
}
static void
@@ -86,7 +75,7 @@ delete_ping_timeout_func (MetaDisplay *display,
{
MetaWindow *window = user_data;
char *window_title;
gchar *window_content;
gchar *window_content, *tmp;
GPid dialog_pid;
meta_topic (META_DEBUG_PING,
@@ -101,11 +90,14 @@ delete_ping_timeout_func (MetaDisplay *display,
window_title = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL);
window_content = g_strdup_printf(
_("<big><b><tt>%s</tt> is not responding.</b></big>\n\n"
"<i>You may choose to wait a short while for it to "
"continue or force the application to quit entirely.</i>"),
window_title);
/* Translators: %s is a window title */
tmp = g_strdup_printf (_("<tt>%s</tt> is not responding."),
window_title);
window_content = g_strdup_printf (
"<big><b>%s</b></big>\n\n<i>%s</i>",
tmp,
_("You may choose to wait a short while for it to "
"continue or force the application to quit entirely."));
g_free (window_title);
@@ -117,13 +109,10 @@ delete_ping_timeout_func (MetaDisplay *display,
NULL, NULL);
g_free (window_content);
g_free (tmp);
window->dialog_pid = dialog_pid;
g_signal_connect (sigchld_nexus, "sigchld",
G_CALLBACK (sigchld_handler),
window);
g_child_watch_add (dialog_pid, dialog_exited, window);
}
void
@@ -189,36 +178,23 @@ meta_window_delete (MetaWindow *window,
void
meta_window_kill (MetaWindow *window)
{
char buf[257];
meta_topic (META_DEBUG_WINDOW_OPS,
"Killing %s brutally\n",
window->desc);
if (window->wm_client_machine != NULL &&
if (!meta_window_is_remote (window) &&
window->net_wm_pid > 0)
{
if (gethostname (buf, sizeof(buf)-1) == 0)
{
if (strcmp (buf, window->wm_client_machine) == 0)
{
meta_topic (META_DEBUG_WINDOW_OPS,
"Killing %s with kill()\n",
window->desc);
meta_topic (META_DEBUG_WINDOW_OPS,
"Killing %s with kill()\n",
window->desc);
if (kill (window->net_wm_pid, 9) < 0)
meta_topic (META_DEBUG_WINDOW_OPS,
"Failed to signal %s: %s\n",
window->desc, strerror (errno));
}
}
else
{
meta_warning (_("Failed to get hostname: %s\n"),
strerror (errno));
}
if (kill (window->net_wm_pid, 9) < 0)
meta_topic (META_DEBUG_WINDOW_OPS,
"Failed to signal %s: %s\n",
window->desc, strerror (errno));
}
meta_topic (META_DEBUG_WINDOW_OPS,
"Disconnecting %s with XKillClient()\n",
window->desc);

View File

@@ -83,10 +83,11 @@ struct _MetaDisplay
char *name;
Display *xdisplay;
char *hostname;
Window leader_window;
Window timestamp_pinging_window;
/* Pull in all the names of atoms as fields; we will intern them when the
* class is constructed.
*/
@@ -150,6 +151,15 @@ struct _MetaDisplay
guint32 current_time;
/* We maintain a sequence counter, incremented for each #MetaWindow
* created. This is exposed by meta_window_get_stable_sequence()
* but is otherwise not used inside mutter.
*
* It can be useful to plugins which want to sort windows in a
* stable fashion.
*/
guint32 window_sequence_counter;
/* Pings which we're waiting for a reply from */
GSList *pending_pings;
@@ -175,6 +185,9 @@ struct _MetaDisplay
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
guint grab_frame_action : 1;
/* During a resize operation, the directions in which we've broken
* out of the initial maximization state */
guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
MetaRectangle grab_initial_window_pos;
int grab_initial_x, grab_initial_y; /* These are only relevant for */
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */
@@ -294,22 +307,15 @@ struct _MetaDisplayClass
GObjectClass parent_class;
};
/* Xserver time can wraparound, thus comparing two timestamps needs to take
* this into account. Here's a little macro to help out. If no wraparound
* has occurred, this is equivalent to
* time1 < time2
* Of course, the rest of the ugliness of this macro comes from accounting
* for the fact that wraparound can occur and the fact that a timestamp of
* 0 must be special-cased since it means older than anything else.
*
* Note that this is NOT an equivalent for time1 <= time2; if that's what
* you need then you'll need to swap the order of the arguments and negate
* the result.
*/
#define XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) \
( (( (time1) < (time2) ) && ( (time2) - (time1) < ((guint32)-1)/2 )) || \
(( (time1) > (time2) ) && ( (time1) - (time2) > ((guint32)-1)/2 )) \
)
/**
* XSERVER_TIME_IS_BEFORE:
*
* See the docs for meta_display_xserver_time_is_before().
*/
#define XSERVER_TIME_IS_BEFORE(time1, time2) \
( (time1) == 0 || \
(XSERVER_TIME_IS_BEFORE_ASSUMING_REAL_TIMESTAMPS(time1, time2) && \
@@ -349,6 +355,9 @@ void meta_display_register_x_window (MetaDisplay *display,
void meta_display_unregister_x_window (MetaDisplay *display,
Window xwindow);
void meta_display_notify_window_created (MetaDisplay *display,
MetaWindow *window);
GSList* meta_display_list_windows (MetaDisplay *display,
MetaListWindowsFlags flags);
@@ -378,9 +387,8 @@ void meta_display_grab_focus_window_button (MetaDisplay *display,
void meta_display_ungrab_focus_window_button (MetaDisplay *display,
MetaWindow *window);
/* Next two functions are defined in edge-resistance.c */
void meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display);
void meta_display_cleanup_edges (MetaDisplay *display);
/* Next function is defined in edge-resistance.c */
void meta_display_cleanup_edges (MetaDisplay *display);
/* make a request to ensure the event serial has changed */
void meta_display_increment_event_serial (MetaDisplay *display);

View File

@@ -30,6 +30,8 @@
* The display is represented as a MetaDisplay struct.
*/
#define _XOPEN_SOURCE 600 /* for gethostname() */
#include <config.h>
#include "display-private.h"
#include "util.h"
@@ -72,6 +74,7 @@
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xfixes.h>
#include <string.h>
#include <unistd.h>
#define GRAB_OP_IS_WINDOW_SWITCH(g) \
(g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL || \
@@ -129,6 +132,9 @@ enum
{
OVERLAY_KEY,
FOCUS_WINDOW,
WINDOW_CREATED,
WINDOW_DEMANDS_ATTENTION,
WINDOW_MARKED_URGENT,
LAST_SIGNAL
};
@@ -148,8 +154,10 @@ static guint display_signals [LAST_SIGNAL] = { 0 };
*/
static MetaDisplay *the_display = NULL;
#ifdef WITH_VERBOSE_MODE
static void meta_spew_event (MetaDisplay *display,
XEvent *event);
#endif
static gboolean event_callback (XEvent *event,
gpointer data);
@@ -226,6 +234,34 @@ meta_display_class_init (MetaDisplayClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
display_signals[WINDOW_CREATED] =
g_signal_new ("window-created",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, META_TYPE_WINDOW);
display_signals[WINDOW_DEMANDS_ATTENTION] =
g_signal_new ("window-demands-attention",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, META_TYPE_WINDOW);
display_signals[WINDOW_MARKED_URGENT] =
g_signal_new ("window-marked-urgent",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
META_TYPE_WINDOW);
g_object_class_install_property (object_class,
PROP_FOCUS_WINDOW,
g_param_spec_object ("focus-window",
@@ -396,6 +432,7 @@ meta_display_open (void)
GSList *tmp;
int i;
guint32 timestamp;
char buf[257];
/* A list of all atom names, so that we can intern them in one go. */
char *atom_names[] = {
@@ -430,6 +467,11 @@ meta_display_open (void)
*/
the_display->name = g_strdup (XDisplayName (NULL));
the_display->xdisplay = xdisplay;
if (gethostname (buf, sizeof(buf)-1) == 0)
{
buf[sizeof(buf)-1] = '\0';
the_display->hostname = g_strdup (buf);
}
the_display->error_trap_synced_at_last_pop = TRUE;
the_display->error_traps = 0;
the_display->error_trap_handler = NULL;
@@ -1287,6 +1329,43 @@ meta_grab_op_is_moving (MetaGrabOp op)
}
}
/**
* meta_display_xserver_time_is_before:
* @display: a #MetaDisplay
* @time1: An event timestamp
* @time2: An event timestamp
*
* Xserver time can wraparound, thus comparing two timestamps needs to take
* this into account. If no wraparound has occurred, this is equivalent to
* time1 < time2
* Otherwise, we need to account for the fact that wraparound can occur
* and the fact that a timestamp of 0 must be special-cased since it
* means "older than anything else".
*
* Note that this is NOT an equivalent for time1 <= time2; if that's what
* you need then you'll need to swap the order of the arguments and negate
* the result.
*/
gboolean
meta_display_xserver_time_is_before (MetaDisplay *display,
guint32 time1,
guint32 time2)
{
return XSERVER_TIME_IS_BEFORE(time1, time2);
}
/**
* meta_display_get_last_user_time:
* @display: a #MetaDisplay
*
* Returns: Timestamp of the last user interaction event with a window
*/
guint32
meta_display_get_last_user_time (MetaDisplay *display)
{
return display->last_user_time;
}
/* Get time of current event, or CurrentTime if none. */
guint32
meta_display_get_current_time (MetaDisplay *display)
@@ -1656,7 +1735,8 @@ event_callback (XEvent *event,
}
#endif /* HAVE_SHAPE */
if (window && ((event->type == KeyPress) || (event->type == ButtonPress)))
if (window && !window->override_redirect &&
((event->type == KeyPress) || (event->type == ButtonPress)))
{
if (CurrentTime == display->current_time)
{
@@ -2556,7 +2636,7 @@ event_callback (XEvent *event,
{
case XkbBellNotify:
if (XSERVER_TIME_IS_BEFORE(display->last_bell_time,
xkb_ev->time - 1000))
xkb_ev->time - 100))
{
display->last_bell_time = xkb_ev->time;
meta_bell_notify (display, xkb_ev);
@@ -3210,6 +3290,13 @@ meta_display_unregister_x_window (MetaDisplay *display,
remove_pending_pings_for_window (display, xwindow);
}
void
meta_display_notify_window_created (MetaDisplay *display,
MetaWindow *window)
{
g_signal_emit (display, display_signals[WINDOW_CREATED], 0, window);
}
/**
* meta_display_xwindow_is_a_no_focus_window:
* @display: A #MetaDisplay
@@ -3523,6 +3610,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_last_user_action_was_snap = FALSE;
#endif
display->grab_frame_action = frame_action;
display->grab_resize_unmaximize = 0;
if (display->grab_resize_timeout_id)
{
@@ -3598,18 +3686,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);
/* If this is a move or resize, cache the window edges for
* resistance/snapping
*/
if (meta_grab_op_is_resizing (display->grab_op) ||
meta_grab_op_is_moving (display->grab_op))
{
meta_topic (META_DEBUG_WINDOW_OPS,
"Computing edges to resist-movement or snap-to for %s.\n",
window->desc);
meta_display_compute_resistance_and_snapping_edges (display);
}
/* Save the old stacking */
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
{
@@ -4104,8 +4180,8 @@ meta_set_syncing (gboolean setting)
if (setting != is_syncing)
{
is_syncing = setting;
XSynchronize (meta_get_display ()->xdisplay, is_syncing);
if (meta_get_display ())
XSynchronize (meta_get_display ()->xdisplay, is_syncing);
}
}
@@ -4113,7 +4189,7 @@ meta_set_syncing (gboolean setting)
* How long, in milliseconds, we should wait after pinging a window
* before deciding it's not going to get back to us.
*/
#define PING_TIMEOUT_DELAY 2250
#define PING_TIMEOUT_DELAY 5000
/**
* Does whatever it is we decided to do when a window didn't respond
@@ -4475,6 +4551,18 @@ find_tab_backward (MetaDisplay *display,
return NULL;
}
/**
* meta_display_get_tab_list:
* @display: a #MetaDisplay
* @type: type of tab list
* @screen: a #MetaScreen
* @workspace: origin workspace
*
* Determine the list of windows that should be displayed for Alt-TAB
* functionality. The windows are returned in most recently used order.
*
* Returns: (transfer container) (element-type Meta.Window): List of windows
*/
GList*
meta_display_get_tab_list (MetaDisplay *display,
MetaTabList type,
@@ -4538,7 +4626,8 @@ meta_display_get_tab_list (MetaDisplay *display,
/* Check to see if it demands attention */
if (l_window->wm_state_demands_attention &&
l_window->workspace!=workspace)
l_window->workspace!=workspace &&
IN_TAB_CHAIN (l_window, type))
{
/* if it does, add it to the popup */
tab_list = g_list_prepend (tab_list, l_window);
@@ -4551,6 +4640,21 @@ meta_display_get_tab_list (MetaDisplay *display,
return tab_list;
}
/**
* meta_display_get_tab_next:
* @display: a #MetaDisplay
* @type: type of tab list
* @screen: a #MetaScreen
* @workspace: origin workspace
* @window: (allow-none): starting window
* @backward: If %TRUE, look for the previous window.
*
* Determine the next window that should be displayed for Alt-TAB
* functionality.
*
* Returns: (transfer none): Next window
*
*/
MetaWindow*
meta_display_get_tab_next (MetaDisplay *display,
MetaTabList type,
@@ -4601,6 +4705,18 @@ meta_display_get_tab_next (MetaDisplay *display,
return ret;
}
/**
* meta_display_get_tab_current:
* @display: a #MetaDisplay
* @type: type of tab list
* @screen: a #MetaScreen
* @workspace: origin workspace
*
* Determine the active window that should be displayed for Alt-TAB.
*
* Returns: (transfer none): Current window
*
*/
MetaWindow*
meta_display_get_tab_current (MetaDisplay *display,
MetaTabList type,
@@ -4945,6 +5061,34 @@ meta_display_stack_cmp (const void *a,
return 0; /* not reached in theory, if windows on same display */
}
/**
* meta_display_sort_windows_by_stacking:
* @display: a #MetaDisplay
* @windows: (element-type MetaWindow): Set of windows
*
* Sorts a set of windows according to their current stacking order. If windows
* from multiple screens are present in the set of input windows, then all the
* windows on screen 0 are sorted below all the windows on screen 1, and so forth.
* Since the stacking order of override-redirect windows isn't controlled by
* Metacity, if override-redirect windows are in the input, the result may not
* correspond to the actual stacking order in the X server.
*
* An example of using this would be to sort the list of transient dialogs for a
* window into their current stacking order.
*
* Returns: (transfer container): Input windows sorted by stacking order, from lowest to highest
*/
GSList *
meta_display_sort_windows_by_stacking (MetaDisplay *display,
GSList *windows)
{
GSList *copy = g_slist_copy (windows);
copy = g_slist_sort (copy, meta_display_stack_cmp);
return copy;
}
void
meta_display_devirtualize_modifiers (MetaDisplay *display,
MetaVirtualModifier modifiers,
@@ -5049,6 +5193,34 @@ prefs_changed_callback (MetaPreference pref,
else
disable_compositor (display);
}
else if (pref == META_PREF_ATTACH_MODAL_DIALOGS)
{
MetaDisplay *display = data;
GSList *windows;
GSList *tmp;
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
for (tmp = windows; tmp != NULL; tmp = tmp->next)
{
MetaWindow *w = tmp->data;
MetaWindow *parent = meta_window_get_transient_for (w);
meta_window_recalc_features (w);
if (w->type == META_WINDOW_MODAL_DIALOG && parent && parent != w)
{
int x, y;
/* Forcing a call to move_resize() does two things: first, it handles
* resizing the dialog frame window to the correct size when we remove
* or add the decorations. Second, it will take care of positioning the
* dialog as "attached" to the parent when we turn the preference on
* via the constrain_modal_dialog() constraint.
**/
meta_window_get_position (w, &x, &y);
meta_window_move (w, FALSE, x, y);
}
}
}
}
void
@@ -5249,18 +5421,32 @@ meta_display_get_compositor_version (MetaDisplay *display,
*minor = display->composite_minor_version;
}
/**
* meta_display_get_xdisplay: (skip)
*
*/
Display *
meta_display_get_xdisplay (MetaDisplay *display)
{
return display->xdisplay;
}
/**
* meta_display_get_compositor: (skip)
*
*/
MetaCompositor *
meta_display_get_compositor (MetaDisplay *display)
{
return display->compositor;
}
/**
* meta_display_get_screens:
* @display: a #MetaDisplay
*
* Returns: (transfer none) (element-type Meta.Screen): Screens for this display
*/
GSList *
meta_display_get_screens (MetaDisplay *display)
{
@@ -5311,3 +5497,19 @@ Atom meta_display_get_atom (MetaDisplay *display, MetaAtom meta_atom)
return atoms[meta_atom - 1];
}
/**
* meta_display_get_leader_window:
* @display: a #MetaDisplay
*
* Returns the window manager's leader window (as defined by the
* _NET_SUPPORTING_WM_CHECK mechanism of EWMH). For use by plugins that wish
* to attach additional custom properties to this window.
*
* Return value: (transfer none): xid of the leader window.
**/
Window
meta_display_get_leader_window (MetaDisplay *display)
{
return display->leader_window;
}

View File

@@ -63,6 +63,8 @@ struct MetaEdgeResistanceData
ResistanceDataForAnEdge bottom_data;
};
static void compute_resistance_and_snapping_edges (MetaDisplay *display);
/* !WARNING!: this function can return invalid indices (namely, either -1 or
* edges->len); this is by design, but you need to remember this.
*/
@@ -550,7 +552,9 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
gboolean modified;
int new_left, new_right, new_top, new_bottom;
g_assert (display->grab_edge_resistance_data != NULL);
if (display->grab_edge_resistance_data == NULL)
compute_resistance_and_snapping_edges (display);
edge_data = display->grab_edge_resistance_data;
if (auto_snap)
@@ -671,7 +675,8 @@ meta_display_cleanup_edges (MetaDisplay *display)
MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
GHashTable *edges_to_be_freed;
g_assert (edge_data != NULL);
if (edge_data == NULL) /* Not currently cached */
return;
/* We first need to clean out any window edges */
edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal,
@@ -938,8 +943,8 @@ initialize_grab_edge_resistance_data (MetaDisplay *display)
edge_data->bottom_data.keyboard_buildup = 0;
}
void
meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display)
static void
compute_resistance_and_snapping_edges (MetaDisplay *display)
{
GList *stacked_windows;
GList *cur_window_iter;
@@ -952,6 +957,11 @@ meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display)
*/
GSList *rem_windows, *rem_win_stacking;
g_assert (display->grab_window != NULL);
meta_topic (META_DEBUG_WINDOW_OPS,
"Computing edges to resist-movement or snap-to for %s.\n",
display->grab_window->desc);
/*
* 1st: Get the list of relevant windows, from bottom to top
*/

View File

@@ -28,18 +28,68 @@
#include <errno.h>
#include <stdlib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h> /* Only for GTK_CHECK_VERSION */
/* In GTK+-3.0, the error trapping code was significantly rewritten. The new code
* has some neat features (like knowing automatically if a sync is needed or not
* and handling errors asynchronously when the error code isn't needed immediately),
* but it's basically incompatible with the hacks we played with GTK+-2.0 to
* use a custom error handler along with gdk_error_trap_push().
*
* Since the main point of our custom error trap was to get the error logged
* to the right place, with GTK+-3.0 we simply omit our own error handler and
* use the GTK+ handling straight-up.
* (See https://bugzilla.gnome.org/show_bug.cgi?id=630216 for restoring logging.)
*/
#if GTK_CHECK_VERSION(2, 90, 0)
#define USE_GDK_ERROR_HANDLERS 1
#endif
#ifndef USE_GDK_ERROR_HANDLERS
static int x_error_handler (Display *display,
XErrorEvent *error);
static int x_io_error_handler (Display *display);
#endif
void
meta_errors_init (void)
{
#ifndef USE_GDK_ERROR_HANDLERS
XSetErrorHandler (x_error_handler);
XSetIOErrorHandler (x_io_error_handler);
#endif
}
#ifdef USE_GDK_ERROR_HANDLERS
void
meta_error_trap_push (MetaDisplay *display)
{
gdk_error_trap_push ();
}
void
meta_error_trap_pop (MetaDisplay *display,
gboolean last_request_was_roundtrip)
{
gdk_error_trap_pop_ignored ();
}
void
meta_error_trap_push_with_return (MetaDisplay *display)
{
gdk_error_trap_push ();
}
int
meta_error_trap_pop_with_return (MetaDisplay *display,
gboolean last_request_was_roundtrip)
{
return gdk_error_trap_pop ();
}
#else /* !USE_GDK_ERROR_HANDLERS */
static void
meta_error_trap_push_internal (MetaDisplay *display,
gboolean need_sync)
@@ -186,10 +236,10 @@ x_error_handler (Display *xdisplay,
display = meta_display_for_x_display (xdisplay);
/* Display can be NULL here because the compositing manager
* has its own Display, but Xlib only has one global error handler
/* Display can be NULL here Xlib only has one global error handler; and
* there might be other displays open in the process.
*/
if (display->error_traps > 0)
if (display && display->error_traps > 0)
{
/* we're in an error trap, chain to the trap handler
* saved from GDK
@@ -228,21 +278,18 @@ x_io_error_handler (Display *xdisplay)
display = meta_display_for_x_display (xdisplay);
if (display == NULL)
meta_bug ("IO error received for unknown display?\n");
if (errno == EPIPE)
{
meta_warning (_("Lost connection to the display '%s';\n"
"most likely the X server was shut down or you killed/destroyed\n"
"the window manager.\n"),
display->name);
display ? display->name : DisplayString (xdisplay));
}
else
{
meta_warning (_("Fatal IO error %d (%s) on display '%s'.\n"),
errno, g_strerror (errno),
display->name);
display ? display->name : DisplayString (xdisplay));
}
/* Xlib would force an exit anyhow */
@@ -250,3 +297,5 @@ x_io_error_handler (Display *xdisplay)
return 0;
}
#endif /* USE_GDK_ERROR_HANDLERS */

View File

@@ -276,7 +276,7 @@ meta_frame_get_flags (MetaFrame *frame)
if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
if (frame->window->has_focus)
if (meta_window_appears_focused (frame->window))
flags |= META_FRAME_HAS_FOCUS;
if (frame->window->shaded)

View File

@@ -104,6 +104,10 @@ meta_group_unref (MetaGroup *group)
}
}
/**
* meta_window_get_group: (skip)
*
*/
MetaGroup*
meta_window_get_group (MetaWindow *window)
{
@@ -198,6 +202,10 @@ meta_window_shutdown_group (MetaWindow *window)
remove_window_from_group (window);
}
/**
* meta_display_lookup_group: (skip)
*
*/
MetaGroup*
meta_display_lookup_group (MetaDisplay *display,
Window group_leader)
@@ -213,6 +221,12 @@ meta_display_lookup_group (MetaDisplay *display,
return group;
}
/**
* meta_group_list_windows:
* @group: A #MetaGroup
*
* Returns: (transfer container) (element-type Meta.Window): List of windows
*/
GSList*
meta_group_list_windows (MetaGroup *group)
{
@@ -263,6 +277,10 @@ meta_group_get_startup_id (MetaGroup *group)
return group->startup_id;
}
/**
* meta_group_property_notify: (skip)
*
*/
gboolean
meta_group_property_notify (MetaGroup *group,
XEvent *event)

View File

@@ -394,17 +394,15 @@ try_pixmap_and_mask (MetaDisplay *display,
get_pixmap_geometry (display, src_pixmap, &w, &h, NULL);
unscaled = meta_gdk_pixbuf_get_from_pixmap (NULL,
src_pixmap,
0, 0, 0, 0,
unscaled = meta_gdk_pixbuf_get_from_pixmap (src_pixmap,
0, 0,
w, h);
if (unscaled && src_mask != None)
{
get_pixmap_geometry (display, src_mask, &w, &h, NULL);
mask = meta_gdk_pixbuf_get_from_pixmap (NULL,
src_mask,
0, 0, 0, 0,
mask = meta_gdk_pixbuf_get_from_pixmap (src_mask,
0, 0,
w, h);
}

View File

@@ -499,14 +499,25 @@ display_get_keybinding (MetaDisplay *display,
return NULL;
}
static MetaKeyBindingAction
display_get_keybinding_action (MetaDisplay *display,
unsigned int keysym,
unsigned int keycode,
unsigned long mask)
/**
* meta_display_get_keybinding_action:
* @display: A #MetaDisplay
* @keysym: Key symbol
* @keycode: Raw keycode
* @mask: Event mask
*
* Returns: The action that should be taken for the given key, or %META_KEYBINDING_ACTION_NONE.
*
*/
MetaKeyBindingAction
meta_display_get_keybinding_action (MetaDisplay *display,
unsigned int keysym,
unsigned int keycode,
unsigned long mask)
{
MetaKeyBinding *binding;
mask = mask & 0xff & ~display->ignored_modifier_mask;
binding = display_get_keybinding (display, keysym, keycode, mask);
if (binding)
@@ -2047,15 +2058,11 @@ process_tab_grab (MetaDisplay *display,
action = META_KEYBINDING_ACTION_NONE;
/*
* There are currently two different ways of customizing Alt-Tab, you can either
* provide a replacement AltTabHandler object, or you can hook into the keybindings
* meta_keybindings_set_custom_handler() and call meta_display_begin_grab_op()
* yourself with one of the "tabbing" grab ops META_GRAB_OP_KEYBOARD_TABBING_NORMAL,
* etc. See meta_display_process_key_event() for the complete list. If screen->tab_handler
* is NULL, the latter mechanism is being used. We skip most of our normal
* processing and just make sure that the right custom handlers get called.
* If there is no tab_pop up object, i.e., there is some custom handler
* implementing Alt+Tab & Co., we call this custom handler; we do not
* mess about with the grab, as that is up to the handler to deal with.
*/
if (!screen->tab_handler)
if (!screen->tab_popup)
{
if (event->type == KeyRelease)
{
@@ -2102,6 +2109,16 @@ process_tab_grab (MetaDisplay *display,
return TRUE;
}
break;
case META_KEYBINDING_ACTION_NONE:
{
/*
* If this is simply user pressing the Shift key, we do not want
* to cancel the grab.
*/
if (is_modifier (display, event->xkey.keycode))
return TRUE;
}
default:
break;
}
@@ -2760,10 +2777,10 @@ process_workspace_switch_grab (MetaDisplay *display,
MetaWorkspace *target_workspace;
MetaKeyBindingAction action;
action = display_get_keybinding_action (display,
keysym,
event->xkey.keycode,
display->grab_mask);
action = meta_display_get_keybinding_action (display,
keysym,
event->xkey.keycode,
display->grab_mask);
switch (action)
{
@@ -3530,6 +3547,10 @@ meta_keybindings_set_custom_handler (const gchar *name,
return TRUE;
}
/**
* meta_keybindings_switch_window: (skip)
*
*/
void
meta_keybindings_switch_window (MetaDisplay *display,
MetaScreen *screen,

View File

@@ -68,6 +68,7 @@
#include <fcntl.h>
#include <locale.h>
#include <time.h>
#include <unistd.h>
#include <clutter/clutter.h>
#include <clutter/x11/clutter-x11.h>
@@ -124,11 +125,13 @@ log_handler (const gchar *log_domain,
static void
version (void)
{
const int latest_year = 2010;
g_print (_("mutter %s\n"
"Copyright (C) 2001-2008 Havoc Pennington, Red Hat, Inc., and others\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"This is free software; see the source for copying conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
VERSION);
VERSION, latest_year);
exit (0);
}
@@ -226,6 +229,7 @@ typedef struct
gboolean sync;
gboolean composite;
gboolean no_composite;
gboolean no_force_fullscreen;
gboolean no_tab_popup;
gchar *introspect;
} MetaArguments;
@@ -304,6 +308,12 @@ meta_parse_options (int *argc, char ***argv,
N_("Turn compositing off"),
NULL
},
{
"no-force-fullscreen", 0, COMPOSITE_OPTS_FLAGS, G_OPTION_ARG_NONE,
&my_args.no_force_fullscreen,
N_("Don't make fullscreen windows that are maximized and have no decorations"),
NULL
},
{
"mutter-plugins", 0, 0, G_OPTION_ARG_STRING,
&my_args.mutter_plugins,
@@ -331,6 +341,7 @@ meta_parse_options (int *argc, char ***argv,
ctx = g_option_context_new (NULL);
g_option_context_add_main_entries (ctx, options, "mutter");
g_option_context_add_group (ctx, clutter_get_option_group_without_init ());
g_option_context_add_group (ctx, cogl_get_option_group ());
if (!g_option_context_parse (ctx, argc, argv, &error))
{
@@ -390,7 +401,7 @@ static GSourceFuncs event_funcs = {
static void
meta_clutter_init (GOptionContext *ctx, int *argc, char ***argv)
{
clutter_x11_set_display (gdk_display);
clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
clutter_x11_disable_event_retrieval ();
if (CLUTTER_INIT_SUCCESS == clutter_init (argc, argv))
@@ -436,37 +447,28 @@ meta_finalize (void)
meta_session_shutdown ();
}
static int sigterm_pipe_fds[2] = { -1, -1 };
static void
sigterm_handler (int signum)
{
meta_finalize ();
exit (meta_exit_code);
}
static guint sigchld_signal_id = 0;
static void
sigchld_handler (int signum, siginfo_t *info, void *context)
{
int stat;
if (info->si_code == CLD_EXITED)
if (sigterm_pipe_fds[1] >= 0)
{
g_signal_emit (sigchld_nexus, sigchld_signal_id, 0,
info->si_status,
GINT_TO_POINTER (info->si_pid));
int dummy;
dummy = write (sigterm_pipe_fds[1], "", 1);
close (sigterm_pipe_fds[1]);
sigterm_pipe_fds[1] = -1;
}
g_signal_handlers_disconnect_matched (sigchld_nexus,
G_SIGNAL_MATCH_DATA,
sigchld_signal_id,
0, NULL, NULL,
GINT_TO_POINTER (info->si_pid));
waitpid (info->si_pid, &stat, WNOHANG);
}
static gboolean
on_sigterm (void)
{
meta_quit (META_EXIT_SUCCESS);
return FALSE;
}
/**
* This is where the story begins. It parses commandline options and
* environment variables, sets up the screen, hands control off to
@@ -489,8 +491,9 @@ main (int argc, char **argv)
"Pango", "GLib-GObject", "GThread"
};
guint i;
GIOChannel *channel;
GOptionContext *ctx;
if (!g_thread_supported ())
g_thread_init (NULL);
@@ -512,29 +515,21 @@ main (int argc, char **argv)
g_strerror (errno));
#endif
if (pipe (sigterm_pipe_fds) != 0)
g_printerr ("Failed to create SIGTERM pipe: %s\n",
g_strerror (errno));
channel = g_io_channel_unix_new (sigterm_pipe_fds[0]);
g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_sigterm, NULL);
g_io_channel_set_close_on_unref (channel, TRUE);
g_io_channel_unref (channel);
act.sa_handler = &sigterm_handler;
if (sigaction (SIGTERM, &act, NULL) < 0)
g_printerr ("Failed to register SIGTERM handler: %s\n",
g_strerror (errno));
sigchld_nexus = g_object_new (META_TYPE_NEXUS, NULL);
sigchld_signal_id =
g_signal_new ("sigchld", META_TYPE_NEXUS,
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
g_cclosure_marshal_VOID__UINT_POINTER,
G_TYPE_NONE,
2,
G_TYPE_UINT, G_TYPE_POINTER);
act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
act.sa_handler = SIG_DFL;
act.sa_sigaction = &sigchld_handler;
if (sigaction (SIGCHLD, &act, NULL) < 0)
g_printerr ("Failed to register SIGCHLD handler: %s\n",
g_strerror (errno));
if (g_getenv ("MUTTER_VERBOSE"))
meta_set_verbose (TRUE);
if (g_getenv ("MUTTER_DEBUG"))
@@ -591,7 +586,7 @@ main (int argc, char **argv)
* is initialized at this point, and we don't plan to run any real
* plugin code.
*/
MutterPluginManager *mgr = mutter_plugin_manager_new (NULL);
MutterPluginManager *mgr = mutter_plugin_manager_get_default ();
if (!mutter_plugin_manager_load (mgr))
g_critical ("failed to load plugins");
}
@@ -716,6 +711,9 @@ main (int argc, char **argv)
if (meta_args.composite || meta_args.no_composite)
meta_prefs_set_compositing_manager (meta_args.composite);
if (meta_args.no_force_fullscreen)
meta_prefs_set_force_fullscreen (FALSE);
if (meta_args.no_tab_popup)
{
meta_prefs_override_no_tab_popup (TRUE);

View File

@@ -27,6 +27,7 @@
#include "prefs.h"
#include "ui.h"
#include "util.h"
#include "compositor/mutter-plugin-manager.h"
#ifdef HAVE_GCONF
#include <gconf/gconf-client.h>
#endif
@@ -52,6 +53,7 @@
#define KEY_COMPOSITOR "/apps/metacity/general/compositing_manager"
#define KEY_GNOME_ACCESSIBILITY "/desktop/gnome/interface/accessibility"
#define KEY_COMMAND_DIRECTORY "/apps/metacity/keybinding_commands"
#define KEY_COMMAND_PREFIX "/apps/metacity/keybinding_commands/command_"
#define KEY_TERMINAL_DIR "/desktop/gnome/applications/terminal"
@@ -62,6 +64,7 @@
#define KEY_WINDOW_BINDINGS_PREFIX "/apps/metacity/window_keybindings"
#define KEY_LIST_BINDINGS_SUFFIX "_list"
#define KEY_WORKSPACE_NAME_DIRECTORY "/apps/metacity/workspace_names"
#define KEY_WORKSPACE_NAME_PREFIX "/apps/metacity/workspace_names/name_"
#define KEY_CLUTTER_PLUGINS "/apps/mutter/general/clutter_plugins"
@@ -83,6 +86,7 @@ static MetaVirtualModifier mouse_button_mods = Mod1Mask;
static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
static MetaFocusNewWindows focus_new_windows = META_FOCUS_NEW_WINDOWS_SMART;
static gboolean raise_on_click = TRUE;
static gboolean attach_modal_dialogs = FALSE;
static char* current_theme = NULL;
static int num_workspaces = 4;
static MetaActionTitlebar action_double_click_titlebar = META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE;
@@ -100,6 +104,8 @@ static char *cursor_theme = NULL;
static int cursor_size = 24;
static gboolean compositing_manager = FALSE;
static gboolean resize_with_right_button = FALSE;
static gboolean side_by_side_tiling = FALSE;
static gboolean force_fullscreen = TRUE;
static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH;
static MetaButtonLayout button_layout;
@@ -121,18 +127,30 @@ static gboolean no_tab_popup = FALSE;
#ifdef HAVE_GCONF
static gboolean handle_preference_update_enum (const gchar *key, GConfValue *value);
static gboolean update_key_binding (const char *name,
static char *binding_name (const char *gconf_key);
static gboolean update_key_binding (const char *key,
const char *value);
static gboolean find_and_update_list_binding (MetaKeyPref *bindings,
const char *name,
GSList *value);
static gboolean update_key_list_binding (const char *name,
GSList *value);
typedef enum
{
META_LIST_OF_STRINGS,
META_LIST_OF_GCONFVALUE_STRINGS
} MetaStringListType;
static gboolean find_and_update_list_binding (MetaKeyPref *bindings,
const char *key,
GSList *value,
MetaStringListType type_of_value);
static gboolean update_key_list_binding (const char *key,
GSList *value,
MetaStringListType type_of_value);
static gboolean update_command (const char *name,
const char *value);
static gboolean update_workspace_name (const char *name,
const char *value);
static void notify_new_value (const char *key,
GConfValue *value);
static void change_notify (GConfClient *client,
guint cnxn_id,
GConfEntry *entry,
@@ -142,14 +160,8 @@ static char* gconf_key_for_workspace_name (int i);
static void queue_changed (MetaPreference pref);
typedef enum
{
META_LIST_OF_STRINGS,
META_LIST_OF_GCONFVALUE_STRINGS
} MetaStringListType;
static gboolean update_list_binding (MetaKeyPref *binding,
GSList *value,
static gboolean update_list_binding (MetaKeyPref *binding,
GSList *value,
MetaStringListType type_of_value);
static void cleanup_error (GError **error);
@@ -221,7 +233,12 @@ static GConfEnumStringPair symtab_titlebar_action[] =
{ 0, NULL },
};
/**
/*
* Note that 'gchar *key' is the first element of all these structures;
* we count on that below in key_is_used and do_override.
*/
/*
* The details of one preference which is constrained to be
* one of a small number of string values-- in other words,
* an enumeration.
@@ -234,21 +251,6 @@ static GConfEnumStringPair symtab_titlebar_action[] =
* been outweighed by the bugs caused when the ordering of the enum
* strings got out of sync with the actual enum statement. Also,
* there is existing library code to use this kind of symbol tables.
*
* Other things we might consider doing to clean this up in the
* future include:
*
* - most of the keys begin with the same prefix, and perhaps we
* could assume it if they don't start with a slash
*
* - there are several cases where a single identifier could be used
* to generate an entire entry, and perhaps this could be done
* with a macro. (This would reduce clarity, however, and is
* probably a bad thing.)
*
* - these types all begin with a gchar* (and contain a MetaPreference)
* and we can factor out the repeated code in the handlers by taking
* advantage of this using some kind of union arrangement.
*/
typedef struct
{
@@ -361,6 +363,11 @@ static MetaEnumPreference preferences_enum[] =
static MetaBoolPreference preferences_bool[] =
{
{ "/apps/mutter/general/attach_modal_dialogs",
META_PREF_ATTACH_MODAL_DIALOGS,
&attach_modal_dialogs,
TRUE,
},
{ "/apps/metacity/general/raise_on_click",
META_PREF_RAISE_ON_CLICK,
&raise_on_click,
@@ -416,6 +423,11 @@ static MetaBoolPreference preferences_bool[] =
&resize_with_right_button,
FALSE,
},
{ "/apps/metacity/general/side_by_side_tiling",
META_PREF_SIDE_BY_SIDE_TILING,
&side_by_side_tiling,
FALSE,
},
{ "/apps/mutter/general/live_hidden_windows",
META_PREF_LIVE_HIDDEN_WINDOWS,
&live_hidden_windows,
@@ -489,6 +501,20 @@ static MetaIntPreference preferences_int[] =
{ NULL, 0, NULL, 0, 0, 0, },
};
/*
* This is used to keep track of preferences that have been
* repointed to a different GConf key location; we modify the
* preferences arrays directly, but we also need to remember
* what we have done to handle subsequent overrides correctly.
*/
typedef struct
{
gchar *original_key;
gchar *new_key;
} MetaPrefsOverriddenKey;
static GSList *overridden_keys;
static void
handle_preference_init_enum (void)
{
@@ -872,6 +898,10 @@ handle_preference_update_int (const gchar *key, GConfValue *value)
/* Listeners. */
/****************************************************************************/
/**
* meta_prefs_add_listener: (skip)
*
*/
void
meta_prefs_add_listener (MetaPrefsChangedFunc func,
gpointer data)
@@ -885,6 +915,10 @@ meta_prefs_add_listener (MetaPrefsChangedFunc func,
listeners = g_list_prepend (listeners, l);
}
/**
* meta_prefs_remove_listener: (skip)
*
*/
void
meta_prefs_remove_listener (MetaPrefsChangedFunc func,
gpointer data)
@@ -1024,6 +1058,7 @@ meta_prefs_init (void)
#ifdef HAVE_GCONF
GError *err = NULL;
gchar **gconf_dir_cursor;
MutterPluginManager *plugin_manager;
if (default_client != NULL)
return;
@@ -1042,12 +1077,7 @@ meta_prefs_init (void)
cleanup_error (&err);
}
/* Pick up initial values. */
handle_preference_init_enum ();
handle_preference_init_bool ();
handle_preference_init_string ();
handle_preference_init_int ();
/* The plugin list is special and needs to be handled first */
if (!clutter_plugins_overridden)
clutter_plugins = gconf_client_get_list (default_client, KEY_CLUTTER_PLUGINS,
@@ -1055,6 +1085,18 @@ meta_prefs_init (void)
cleanup_error (&err);
/* We now initialize plugins so that they can override any preference locations */
plugin_manager = mutter_plugin_manager_get_default ();
mutter_plugin_manager_load (plugin_manager);
/* Pick up initial values. */
handle_preference_init_enum ();
handle_preference_init_bool ();
handle_preference_init_string ();
handle_preference_init_int ();
/* @@@ Is there any reason we don't do the add_dir here? */
for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
*gconf_dir_cursor!=NULL;
@@ -1087,6 +1129,160 @@ meta_prefs_init (void)
init_workspace_names ();
}
/* This count on the key being the first element of the
* preference structure */
static gboolean
key_is_used (void *prefs,
size_t pref_size,
const char *new_key)
{
void *p = prefs;
while (TRUE)
{
char **key = p;
if (*key == NULL)
break;
if (strcmp (*key, new_key) == 0)
return TRUE;
p = (guchar *)p + pref_size;
}
return FALSE;
}
static gboolean
do_override (void *prefs,
size_t pref_size,
const char *search_key,
char *new_key)
{
void *p = prefs;
while (TRUE)
{
char **key = p;
if (*key == NULL)
break;
if (strcmp (*key, search_key) == 0)
{
*key = new_key;
return TRUE;
}
p = (guchar *)p + pref_size;
}
return FALSE;
}
/**
* meta_prefs_override_preference_location
* @original_key: the normal Metacity preference location
* @new_key: the Metacity preference location to use instead.
*
* Substitute a different location to use instead of a standard Metacity
* GConf key location. This might be used if a plugin expected a different
* value for some preference than the Metacity default. While this function
* can be called at any point, this function should generally be called
* in a plugin's constructor, rather than in its start() method so the
* preference isn't first loaded with one value then changed to another
* value.
*/
void
meta_prefs_override_preference_location (const char *original_key,
const char *new_key)
{
const char *search_key;
char *new_key_copy;
gboolean found;
MetaPrefsOverriddenKey *overridden;
GSList *tmp;
/* Merge identical overrides, this isn't an error */
for (tmp = overridden_keys; tmp; tmp = tmp->next)
{
MetaPrefsOverriddenKey *tmp_overridden = tmp->data;
if (strcmp (tmp_overridden->original_key, original_key) == 0 &&
strcmp (tmp_overridden->new_key, new_key) == 0)
return;
}
/* We depend on a unique mapping from GConf key to preference, so
* enforce this */
if (key_is_used (preferences_enum, sizeof(MetaEnumPreference), new_key) ||
key_is_used (preferences_bool, sizeof(MetaBoolPreference), new_key) ||
key_is_used (preferences_string, sizeof(MetaStringPreference), new_key) ||
key_is_used (preferences_int, sizeof(MetaIntPreference), new_key))
{
meta_warning (_("GConf key %s is already in use and can't be used to override %s\n"),
new_key, original_key);
}
new_key_copy = g_strdup (new_key);
search_key = original_key;
overridden = NULL;
for (tmp = overridden_keys; tmp; tmp = tmp->next)
{
MetaPrefsOverriddenKey *tmp_overridden = tmp->data;
if (strcmp (overridden->original_key, original_key) == 0)
{
overridden = tmp_overridden;
search_key = tmp_overridden->new_key;
}
}
found =
do_override (preferences_enum, sizeof(MetaEnumPreference), search_key, new_key_copy) ||
do_override (preferences_bool, sizeof(MetaBoolPreference), search_key, new_key_copy) ||
do_override (preferences_string, sizeof(MetaStringPreference), search_key, new_key_copy) ||
do_override (preferences_int, sizeof(MetaIntPreference), search_key, new_key_copy);
if (found)
{
if (overridden)
{
g_free (overridden->new_key);
overridden->new_key = new_key_copy;
}
else
{
overridden = g_slice_new (MetaPrefsOverriddenKey);
overridden->original_key = g_strdup (original_key);
overridden->new_key = new_key_copy;
}
#ifdef HAVE_GCONF
if (default_client != NULL)
{
/* We're already initialized, so notify of a change */
GConfValue *value;
GError *err = NULL;
value = gconf_client_get (default_client, new_key, &err);
cleanup_error (&err);
notify_new_value (new_key, value);
if (value)
gconf_value_free (value);
}
#endif /* HAVE_GCONF */
}
else
{
meta_warning (_("Can't override GConf key, %s not found\n"), original_key);
g_free (new_key_copy);
}
}
/****************************************************************************/
/* Updates. */
@@ -1102,6 +1298,23 @@ gboolean (*preference_update_handler[]) (const gchar*, GConfValue*) = {
NULL
};
static void
notify_new_value (const char *key,
GConfValue *value)
{
int i = 0;
/* FIXME: Use MetaGenericPreference and save a bit of code duplication */
while (preference_update_handler[i] != NULL)
{
if (preference_update_handler[i] (key, value))
return;
i++;
}
}
static void
change_notify (GConfClient *client,
guint cnxn_id,
@@ -1110,25 +1323,13 @@ change_notify (GConfClient *client,
{
const char *key;
GConfValue *value;
gint i=0;
key = gconf_entry_get_key (entry);
value = gconf_entry_get_value (entry);
/* First, search for a handler that might know what to do. */
/* FIXME: When this is all working, since the first item in every
* array is the gchar* of the key, there's no reason we can't
* find the correct record for that key here and save code duplication.
*/
while (preference_update_handler[i]!=NULL)
{
if (preference_update_handler[i] (key, value))
goto out; /* Get rid of this eventually */
i++;
}
notify_new_value (key, value);
if (g_str_has_prefix (key, KEY_WINDOW_BINDINGS_PREFIX) ||
g_str_has_prefix (key, KEY_SCREEN_BINDINGS_PREFIX))
@@ -1146,7 +1347,7 @@ change_notify (GConfClient *client,
list = value ? gconf_value_get_list (value) : NULL;
if (update_key_list_binding (key, list))
if (update_key_list_binding (key, list, META_LIST_OF_GCONFVALUE_STRINGS))
queue_changed (META_PREF_KEYBINDINGS);
}
else
@@ -1304,6 +1505,12 @@ meta_prefs_get_focus_new_windows (void)
return focus_new_windows;
}
gboolean
meta_prefs_get_attach_modal_dialogs (void)
{
return attach_modal_dialogs;
}
gboolean
meta_prefs_get_raise_on_click (void)
{
@@ -1725,6 +1932,9 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_FOCUS_NEW_WINDOWS:
return "FOCUS_NEW_WINDOWS";
case META_PREF_ATTACH_MODAL_DIALOGS:
return "ATTACH_MODAL_DIALOGS";
case META_PREF_RAISE_ON_CLICK:
return "RAISE_ON_CLICK";
@@ -1800,6 +2010,12 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_RESIZE_WITH_RIGHT_BUTTON:
return "RESIZE_WITH_RIGHT_BUTTON";
case META_PREF_SIDE_BY_SIDE_TILING:
return "SIDE_BY_SIDE_TILING";
case META_PREF_FORCE_FULLSCREEN:
return "FORCE_FULLSCREEN";
case META_PREF_CLUTTER_PLUGINS:
return "CLUTTER_PLUGINS";
@@ -1888,57 +2104,64 @@ init_special_bindings (void)
static void
init_bindings (void)
{
#ifdef HAVE_GCONF
int i = 0;
GError *err;
#ifdef HAVE_GCONF
const char *prefix[] = {
KEY_WINDOW_BINDINGS_PREFIX,
KEY_SCREEN_BINDINGS_PREFIX,
NULL
};
int i;
GSList *list, *l, *list_val;
const char *str_val;
const char *key;
GConfEntry *entry;
GConfValue *value;
GHashTable *to_update;
to_update = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
for (i = 0; prefix[i]; i++)
{
list = gconf_client_all_entries (default_client, prefix[i], NULL);
for (l = list; l; l = l->next)
{
entry = l->data;
key = gconf_entry_get_key (entry);
value = gconf_entry_get_value (entry);
if (g_str_has_suffix (key, KEY_LIST_BINDINGS_SUFFIX))
{
/* List bindings are used in addition to the normal bindings and never
* have defaults, so we just go ahead and set them immediately; there
* will be only a few of them, so don't worry about the linear scan
* in find_and_update_list_binding.
*/
list_val = gconf_client_get_list (default_client, key, GCONF_VALUE_STRING, NULL);
update_key_list_binding (key, list_val, META_LIST_OF_STRINGS);
g_slist_foreach (list_val, (GFunc)g_free, NULL);
g_slist_free (list_val);
}
else
{
str_val = gconf_value_get_string (value);
g_hash_table_insert (to_update, binding_name (key), g_strdup (str_val));
}
gconf_entry_free (entry);
}
g_slist_free (list);
}
i = 0;
while (key_bindings[i].name)
{
GSList *list_val, *tmp;
char *str_val;
char *key;
key = g_strconcat (key_bindings[i].per_window?
KEY_WINDOW_BINDINGS_PREFIX:
KEY_SCREEN_BINDINGS_PREFIX,
"/",
key_bindings[i].name, NULL);
err = NULL;
str_val = gconf_client_get_string (default_client, key, &err);
cleanup_error (&err);
update_binding (&key_bindings[i], str_val);
g_free (str_val);
g_free (key);
key = g_strconcat (key_bindings[i].per_window?
KEY_WINDOW_BINDINGS_PREFIX:
KEY_SCREEN_BINDINGS_PREFIX,
"/",
key_bindings[i].name,
KEY_LIST_BINDINGS_SUFFIX, NULL);
err = NULL;
list_val = gconf_client_get_list (default_client, key, GCONF_VALUE_STRING, &err);
cleanup_error (&err);
update_list_binding (&key_bindings[i], list_val, META_LIST_OF_STRINGS);
tmp = list_val;
while (tmp)
{
g_free (tmp->data);
tmp = tmp->next;
}
g_slist_free (list_val);
g_free (key);
update_binding (&key_bindings[i],
g_hash_table_lookup (to_update, key_bindings[i].name));
++i;
}
g_hash_table_destroy (to_update);
#else /* HAVE_GCONF */
int i = 0;
while (key_bindings[i].name)
@@ -1960,28 +2183,23 @@ static void
init_commands (void)
{
#ifdef HAVE_GCONF
int i;
GError *err;
i = 0;
while (i < MAX_COMMANDS)
GSList *list, *l;
const char *str_val;
const char *key;
GConfEntry *entry;
GConfValue *value;
list = gconf_client_all_entries (default_client, KEY_COMMAND_DIRECTORY, NULL);
for (l = list; l; l = l->next)
{
char *str_val;
char *key;
key = meta_prefs_get_gconf_key_for_command (i);
err = NULL;
str_val = gconf_client_get_string (default_client, key, &err);
cleanup_error (&err);
entry = l->data;
key = gconf_entry_get_key (entry);
value = gconf_entry_get_value (entry);
str_val = gconf_value_get_string (value);
update_command (key, str_val);
g_free (str_val);
g_free (key);
++i;
gconf_entry_free (entry);
}
g_slist_free (list);
#else
int i;
for (i = 0; i < MAX_COMMANDS; i++)
@@ -1992,39 +2210,34 @@ init_commands (void)
static void
init_workspace_names (void)
{
int i;
#ifdef HAVE_GCONF
int i;
GError *err;
i = 0;
while (i < MAX_REASONABLE_WORKSPACES)
GSList *list, *l;
const char *str_val;
const char *key;
GConfEntry *entry;
GConfValue *value;
list = gconf_client_all_entries (default_client, KEY_WORKSPACE_NAME_DIRECTORY, NULL);
for (l = list; l; l = l->next)
{
char *str_val;
char *key;
key = gconf_key_for_workspace_name (i);
err = NULL;
str_val = gconf_client_get_string (default_client, key, &err);
cleanup_error (&err);
entry = l->data;
key = gconf_entry_get_key (entry);
value = gconf_entry_get_value (entry);
str_val = gconf_value_get_string (value);
update_workspace_name (key, str_val);
g_assert (workspace_names[i] != NULL);
g_free (str_val);
g_free (key);
++i;
gconf_entry_free (entry);
}
#else
int i;
g_slist_free (list);
#endif /* HAVE_GCONF */
for (i = 0; i < MAX_REASONABLE_WORKSPACES; i++)
workspace_names[i] = g_strdup_printf (_("Workspace %d"), i + 1);
if (workspace_names[i] == NULL)
workspace_names[i] = g_strdup_printf (_("Workspace %d"), i + 1);
meta_topic (META_DEBUG_PREFS,
"Initialized workspace names\n");
#endif /* HAVE_GCONF */
}
static gboolean
@@ -2275,16 +2488,22 @@ update_list_binding (MetaKeyPref *binding,
return changed;
}
static const gchar*
relative_key (const gchar* key)
static char *
binding_name (const char *gconf_key)
{
const gchar* end;
end = strrchr (key, '/');
const char *start, *end;
++end;
if (*gconf_key == '/')
start = strrchr (gconf_key, '/') + 1;
else
start = gconf_key;
return end;
if (g_str_has_suffix (gconf_key, KEY_LIST_BINDINGS_SUFFIX))
end = gconf_key + strlen(gconf_key) - strlen (KEY_LIST_BINDINGS_SUFFIX);
else
end = gconf_key + strlen(gconf_key);
return g_strndup (start, end - start);
}
/* Return value is TRUE if a preference changed and we need to
@@ -2292,22 +2511,19 @@ relative_key (const gchar* key)
*/
static gboolean
find_and_update_binding (MetaKeyPref *bindings,
const char *name,
const char *key,
const char *value)
{
const char *key;
char *name = binding_name (key);
int i;
if (*name == '/')
key = relative_key (name);
else
key = name;
i = 0;
while (bindings[i].name &&
strcmp (key, bindings[i].name) != 0)
strcmp (name, bindings[i].name) != 0)
++i;
g_free (name);
if (bindings[i].name)
return update_binding (&bindings[i], value);
else
@@ -2315,46 +2531,40 @@ find_and_update_binding (MetaKeyPref *bindings,
}
static gboolean
update_key_binding (const char *name,
const char *value)
update_key_binding (const char *key,
const char *value)
{
return find_and_update_binding (key_bindings, name, value);
return find_and_update_binding (key_bindings, key, value);
}
static gboolean
find_and_update_list_binding (MetaKeyPref *bindings,
const char *name,
GSList *value)
find_and_update_list_binding (MetaKeyPref *bindings,
const char *key,
GSList *value,
MetaStringListType type_of_value)
{
const char *key;
char *name = binding_name (key);
int i;
gchar *name_without_suffix = g_strdup(name);
name_without_suffix[strlen(name_without_suffix) - strlen(KEY_LIST_BINDINGS_SUFFIX)] = 0;
if (*name_without_suffix == '/')
key = relative_key (name_without_suffix);
else
key = name_without_suffix;
i = 0;
while (bindings[i].name &&
strcmp (key, bindings[i].name) != 0)
strcmp (name, bindings[i].name) != 0)
++i;
g_free (name_without_suffix);
g_free (name);
if (bindings[i].name)
return update_list_binding (&bindings[i], value, META_LIST_OF_GCONFVALUE_STRINGS);
return update_list_binding (&bindings[i], value, type_of_value);
else
return FALSE;
}
static gboolean
update_key_list_binding (const char *name,
GSList *value)
update_key_list_binding (const char *key,
GSList *value,
MetaStringListType type_of_value)
{
return find_and_update_list_binding (key_bindings, name, value);
return find_and_update_list_binding (key_bindings, key, value, type_of_value);
}
static gboolean
@@ -2713,6 +2923,12 @@ meta_prefs_get_gnome_animations ()
return gnome_animations;
}
gboolean
meta_prefs_get_side_by_side_tiling ()
{
return side_by_side_tiling;
}
MetaKeyBindingAction
meta_prefs_get_keybinding_action (const char *name)
{
@@ -2792,6 +3008,12 @@ meta_prefs_get_mouse_button_menu (void)
return resize_with_right_button ? 2: 3;
}
gboolean
meta_prefs_get_force_fullscreen (void)
{
return force_fullscreen;
}
void
meta_prefs_set_compositing_manager (gboolean whether)
{
@@ -2814,6 +3036,11 @@ meta_prefs_set_compositing_manager (gboolean whether)
#endif
}
/**
* meta_prefs_get_clutter_plugins:
*
* Returns: (transfer none) (element-type utf8): Plugin names to load
*/
GSList *
meta_prefs_get_clutter_plugins (void)
{
@@ -2823,6 +3050,7 @@ meta_prefs_get_clutter_plugins (void)
void
meta_prefs_set_clutter_plugins (GSList *list)
{
#ifdef HAVE_GCONF
GError *err = NULL;
gconf_client_set_list (default_client,
@@ -2837,6 +3065,7 @@ meta_prefs_set_clutter_plugins (GSList *list)
err->message);
g_error_free (err);
}
#endif
}
void
@@ -2957,3 +3186,10 @@ init_button_layout(void)
};
#endif
void
meta_prefs_set_force_fullscreen (gboolean whether)
{
force_fullscreen = whether;
}

View File

@@ -37,7 +37,6 @@
#include "screen.h"
#include <X11/Xutil.h>
#include "stack-tracker.h"
#include "alttabhandler.h"
#include "ui.h"
typedef struct _MetaMonitorInfo MetaMonitorInfo;
@@ -82,9 +81,11 @@ struct _MetaScreen
Visual *default_xvisual;
MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */
MetaUI *ui;
MetaAltTabHandler *tab_handler;
MetaTabPopup *ws_popup;
MetaTabPopup *tab_popup, *ws_popup;
MetaTilePreview *tile_preview;
guint tile_preview_timeout_id;
MetaWorkspace *active_workspace;
/* This window holds the focus when we don't want to focus
@@ -118,8 +119,9 @@ struct _MetaScreen
#endif
Window wm_cm_selection_window;
guint32 wm_cm_timestamp;
guint work_area_idle;
guint work_area_later;
int rows_of_workspaces;
int columns_of_workspaces;
@@ -131,9 +133,6 @@ struct _MetaScreen
int closing;
/* gc for XOR on root window */
GC root_xor_gc;
/* Managed by compositor.c */
gpointer compositor_data;
@@ -147,7 +146,8 @@ struct _MetaScreenClass
{
GObjectClass parent_class;
void (*restacked) (MetaScreen *);
void (*restacked) (MetaScreen *);
void (*workareas_changed) (MetaScreen *);
};
MetaScreen* meta_screen_new (MetaDisplay *display,
@@ -182,6 +182,9 @@ void meta_screen_workspace_popup_select (MetaScreen *screen,
MetaWorkspace*meta_screen_workspace_popup_get_selected (MetaScreen *screen);
void meta_screen_workspace_popup_destroy (MetaScreen *screen);
void meta_screen_tile_preview_update (MetaScreen *screen,
gboolean delay);
MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen,
MetaWindow *not_this_one);

View File

@@ -38,7 +38,6 @@
#include "stack.h"
#include "xprops.h"
#include "compositor.h"
#include "alttabhandlerdefault.h"
#include "mutter-marshal.h"
#include "mutter-enum-types.h"
@@ -86,6 +85,7 @@ enum
WORKSPACE_REMOVED,
WORKSPACE_SWITCHED,
STARTUP_SEQUENCE_CHANGED,
WORKAREAS_CHANGED,
LAST_SIGNAL
};
@@ -218,6 +218,15 @@ meta_screen_class_init (MetaScreenClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
screen_signals[WORKAREAS_CHANGED] =
g_signal_new ("workareas-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MetaScreenClass, workareas_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_object_class_install_property (object_class,
PROP_N_WORKSPACES,
pspec);
@@ -255,6 +264,13 @@ set_wm_check_hint (MetaScreen *screen)
return Success;
}
static void
unset_wm_check_hint (MetaScreen *screen)
{
XDeleteProperty (screen->display->xdisplay, screen->xroot,
screen->display->atom__NET_SUPPORTING_WM_CHECK);
}
static int
set_supported_hint (MetaScreen *screen)
{
@@ -687,7 +703,7 @@ meta_screen_new (MetaDisplay *display,
screen->wm_cm_selection_window = meta_create_offscreen_window (xdisplay,
xroot,
NoEventMask);
screen->work_area_idle = 0;
screen->work_area_later = 0;
screen->active_workspace = NULL;
screen->workspaces = NULL;
@@ -698,35 +714,6 @@ meta_screen_new (MetaDisplay *display,
screen->compositor_data = NULL;
screen->guard_window = None;
{
XFontStruct *font_info;
XGCValues gc_values;
gulong value_mask = 0;
gc_values.subwindow_mode = IncludeInferiors;
value_mask |= GCSubwindowMode;
gc_values.function = GXinvert;
value_mask |= GCFunction;
gc_values.line_width = META_WIREFRAME_XOR_LINE_WIDTH;
value_mask |= GCLineWidth;
font_info = XLoadQueryFont (screen->display->xdisplay, "fixed");
if (font_info != NULL)
{
gc_values.font = font_info->fid;
value_mask |= GCFont;
XFreeFontInfo (NULL, font_info, 1);
}
else
meta_warning ("xserver doesn't have 'fixed' font.\n");
screen->root_xor_gc = XCreateGC (screen->display->xdisplay,
screen->xroot,
value_mask,
&gc_values);
}
screen->monitor_infos = NULL;
screen->n_monitor_infos = 0;
screen->last_monitor_index = 0;
@@ -781,9 +768,12 @@ meta_screen_new (MetaDisplay *display,
screen->ui = meta_ui_new (screen->display->xdisplay,
screen->xscreen);
screen->tab_handler = NULL;
screen->tab_popup = NULL;
screen->ws_popup = NULL;
screen->tile_preview = NULL;
screen->tile_preview_timeout_id = 0;
screen->stack = meta_stack_new (screen);
screen->stack_tracker = meta_stack_tracker_new (screen);
@@ -822,7 +812,6 @@ meta_screen_free (MetaScreen *screen,
guint32 timestamp)
{
MetaDisplay *display;
XGCValues gc_values = { 0 };
display = screen->display;
@@ -871,27 +860,22 @@ meta_screen_free (MetaScreen *screen,
meta_warning (_("Could not release screen %d on display \"%s\"\n"),
screen->number, screen->display->name);
unset_wm_check_hint (screen);
XDestroyWindow (screen->display->xdisplay,
screen->wm_sn_selection_window);
if (screen->work_area_idle != 0)
g_source_remove (screen->work_area_idle);
if (screen->work_area_later != 0)
g_source_remove (screen->work_area_later);
if (XGetGCValues (screen->display->xdisplay,
screen->root_xor_gc,
GCFont,
&gc_values))
{
XUnloadFont (screen->display->xdisplay,
gc_values.font);
}
XFreeGC (screen->display->xdisplay,
screen->root_xor_gc);
if (screen->monitor_infos)
g_free (screen->monitor_infos);
if (screen->tile_preview_timeout_id)
g_source_remove (screen->tile_preview_timeout_id);
if (screen->tile_preview)
meta_tile_preview_free (screen->tile_preview);
g_free (screen->screen_name);
@@ -1291,7 +1275,8 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
GList *l;
MetaWorkspace *neighbour = NULL;
GList *next = NULL;
int index;
int index;
int new_num;
l = screen->workspaces;
while (l)
@@ -1333,7 +1318,10 @@ meta_screen_remove_workspace (MetaScreen *screen, MetaWorkspace *workspace,
/* This also removes the workspace from the screens list */
meta_workspace_remove (workspace);
set_number_of_spaces_hint (screen, g_list_length (screen->workspaces));
new_num = g_list_length (screen->workspaces);
set_number_of_spaces_hint (screen, new_num);
meta_prefs_set_num_workspaces (new_num);
l = next;
while (l)
@@ -1369,6 +1357,7 @@ meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate,
guint32 timestamp)
{
MetaWorkspace *w;
int new_num;
/* This also adds the workspace to the screen list */
w = meta_workspace_new (screen);
@@ -1379,7 +1368,10 @@ meta_screen_append_new_workspace (MetaScreen *screen, gboolean activate,
if (activate)
meta_workspace_activate (w, timestamp);
set_number_of_spaces_hint (screen, g_list_length (screen->workspaces));
new_num = g_list_length (screen->workspaces);
set_number_of_spaces_hint (screen, new_num);
meta_prefs_set_num_workspaces (new_num);
meta_screen_queue_workarea_recalc (screen);
@@ -1406,6 +1398,9 @@ update_num_workspaces (MetaScreen *screen,
g_assert (new_num > 0);
if (g_list_length (screen->workspaces) == (guint) new_num)
return;
last_remaining = NULL;
extras = NULL;
i = 0;
@@ -1516,58 +1511,146 @@ meta_screen_tab_popup_create (MetaScreen *screen,
MetaTabShowType show_type,
MetaWindow *initial_selection)
{
MetaTabEntry *entries;
GList *tab_list;
GList *tmp;
int len;
int i;
g_return_if_fail (screen->tab_handler == NULL);
screen->tab_handler = meta_alt_tab_handler_new (screen,
show_type == META_TAB_SHOW_INSTANTLY);
if (screen->tab_popup)
return;
tab_list = meta_display_get_tab_list (screen->display,
list_type,
screen,
screen->active_workspace);
for (tmp = tab_list; tmp; tmp = tmp->next)
meta_alt_tab_handler_add_window (screen->tab_handler, tmp->data);
meta_alt_tab_handler_show (screen->tab_handler, initial_selection);
len = g_list_length (tab_list);
entries = g_new (MetaTabEntry, len + 1);
entries[len].key = NULL;
entries[len].title = NULL;
entries[len].icon = NULL;
i = 0;
tmp = tab_list;
while (i < len)
{
MetaWindow *window;
MetaRectangle r;
window = tmp->data;
entries[i].key = (MetaTabEntryKey) window;
entries[i].title = window->title;
entries[i].icon = g_object_ref (window->icon);
entries[i].blank = FALSE;
entries[i].hidden = !meta_window_showing_on_its_workspace (window);
entries[i].demands_attention = window->wm_state_demands_attention;
if (show_type == META_TAB_SHOW_INSTANTLY ||
!entries[i].hidden ||
!meta_window_get_icon_geometry (window, &r))
meta_window_get_outer_rect (window, &r);
entries[i].rect = r;
/* Find inside of highlight rectangle to be used when window is
* outlined for tabbing. This should be the size of the
* east/west frame, and the size of the south frame, on those
* sides. On the top it should be the size of the south frame
* edge.
*/
#define OUTLINE_WIDTH 5
/* Top side */
if (!entries[i].hidden &&
window->frame && window->frame->bottom_height > 0 &&
window->frame->child_y >= window->frame->bottom_height)
entries[i].inner_rect.y = window->frame->bottom_height;
else
entries[i].inner_rect.y = OUTLINE_WIDTH;
/* Bottom side */
if (!entries[i].hidden &&
window->frame && window->frame->bottom_height != 0)
entries[i].inner_rect.height = r.height
- entries[i].inner_rect.y - window->frame->bottom_height;
else
entries[i].inner_rect.height = r.height
- entries[i].inner_rect.y - OUTLINE_WIDTH;
/* Left side */
if (!entries[i].hidden && window->frame && window->frame->child_x != 0)
entries[i].inner_rect.x = window->frame->child_x;
else
entries[i].inner_rect.x = OUTLINE_WIDTH;
/* Right side */
if (!entries[i].hidden &&
window->frame && window->frame->right_width != 0)
entries[i].inner_rect.width = r.width
- entries[i].inner_rect.x - window->frame->right_width;
else
entries[i].inner_rect.width = r.width
- entries[i].inner_rect.x - OUTLINE_WIDTH;
++i;
tmp = tmp->next;
}
if (!meta_prefs_get_no_tab_popup ())
screen->tab_popup = meta_ui_tab_popup_new (entries,
screen->number,
len,
5, /* FIXME */
TRUE);
for (i = 0; i < len; i++)
g_object_unref (entries[i].icon);
g_free (entries);
g_list_free (tab_list);
meta_ui_tab_popup_select (screen->tab_popup,
(MetaTabEntryKey) initial_selection);
if (show_type != META_TAB_SHOW_INSTANTLY)
meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE);
}
void
meta_screen_tab_popup_forward (MetaScreen *screen)
{
g_return_if_fail (screen->tab_handler != NULL);
g_return_if_fail (screen->tab_popup != NULL);
meta_alt_tab_handler_forward (screen->tab_handler);
meta_ui_tab_popup_forward (screen->tab_popup);
}
void
meta_screen_tab_popup_backward (MetaScreen *screen)
{
g_return_if_fail (screen->tab_handler != NULL);
g_return_if_fail (screen->tab_popup != NULL);
meta_alt_tab_handler_backward (screen->tab_handler);
meta_ui_tab_popup_backward (screen->tab_popup);
}
MetaWindow *
meta_screen_tab_popup_get_selected (MetaScreen *screen)
{
g_return_val_if_fail (screen->tab_handler != NULL, NULL);
g_return_val_if_fail (screen->tab_popup != NULL, NULL);
return meta_alt_tab_handler_get_selected (screen->tab_handler);
return (MetaWindow *) meta_ui_tab_popup_get_selected (screen->tab_popup);
}
void
meta_screen_tab_popup_destroy (MetaScreen *screen)
{
if (!screen->tab_handler)
return;
meta_alt_tab_handler_destroy (screen->tab_handler);
g_object_unref (screen->tab_handler);
screen->tab_handler = NULL;
if (screen->tab_popup)
{
meta_ui_tab_popup_free (screen->tab_popup);
screen->tab_popup = NULL;
}
}
void
@@ -1580,8 +1663,9 @@ meta_screen_workspace_popup_create (MetaScreen *screen,
MetaWorkspaceLayout layout;
int n_workspaces;
int current_workspace;
g_return_if_fail (screen->ws_popup == NULL);
if (screen->ws_popup || meta_prefs_get_no_tab_popup ())
return;
current_workspace = meta_workspace_index (screen->active_workspace);
n_workspaces = meta_screen_get_n_workspaces (screen);
@@ -1668,6 +1752,69 @@ meta_screen_workspace_popup_destroy (MetaScreen *screen)
}
}
static gboolean
meta_screen_tile_preview_update_timeout (gpointer data)
{
MetaScreen *screen = data;
MetaWindow *window = screen->display->grab_window;
gboolean composited = screen->display->compositor != NULL;
screen->tile_preview_timeout_id = 0;
if (!screen->tile_preview)
{
Window xwindow;
gulong create_serial;
screen->tile_preview = meta_tile_preview_new (screen->number,
composited);
xwindow = meta_tile_preview_get_xwindow (screen->tile_preview,
&create_serial);
meta_stack_tracker_record_add (screen->stack_tracker,
xwindow,
create_serial);
}
if (window
&& !META_WINDOW_TILED (window)
&& window->tile_mode != META_TILE_NONE)
{
MetaRectangle tile_rect;
meta_window_get_current_tile_area (window, &tile_rect);
meta_tile_preview_show (screen->tile_preview, &tile_rect);
}
else
meta_tile_preview_hide (screen->tile_preview);
return FALSE;
}
#define TILE_PREVIEW_TIMEOUT_MS 200
void
meta_screen_tile_preview_update (MetaScreen *screen,
gboolean delay)
{
if (delay)
{
if (screen->tile_preview_timeout_id > 0)
return;
screen->tile_preview_timeout_id =
g_timeout_add (TILE_PREVIEW_TIMEOUT_MS,
meta_screen_tile_preview_update_timeout,
screen);
}
else
{
if (screen->tile_preview_timeout_id > 0)
g_source_remove (screen->tile_preview_timeout_id);
meta_screen_tile_preview_update_timeout ((gpointer)screen);
}
}
MetaWindow*
meta_screen_get_mouse_window (MetaScreen *screen,
MetaWindow *not_this_one)
@@ -2200,15 +2347,17 @@ set_work_area_hint (MetaScreen *screen)
(guchar*) data, num_workspaces*4);
g_free (data);
meta_error_trap_pop (screen->display, FALSE);
g_signal_emit (screen, screen_signals[WORKAREAS_CHANGED], 0);
}
static gboolean
set_work_area_idle_func (MetaScreen *screen)
set_work_area_later_func (MetaScreen *screen)
{
meta_topic (META_DEBUG_WORKAREA,
"Running work area idle function\n");
"Running work area hint computation function\n");
screen->work_area_idle = 0;
screen->work_area_later = 0;
set_work_area_hint (screen);
@@ -2218,16 +2367,16 @@ set_work_area_idle_func (MetaScreen *screen)
void
meta_screen_queue_workarea_recalc (MetaScreen *screen)
{
/* Recompute work area in an idle */
if (screen->work_area_idle == 0)
/* Recompute work area later before redrawing */
if (screen->work_area_later == 0)
{
meta_topic (META_DEBUG_WORKAREA,
"Adding work area hint idle function\n");
screen->work_area_idle =
g_idle_add_full (META_PRIORITY_BEFORE_REDRAW,
(GSourceFunc) set_work_area_idle_func,
screen,
NULL);
"Adding work area hint computation function\n");
screen->work_area_later =
meta_later_add (META_LATER_BEFORE_REDRAW,
(GSourceFunc) set_work_area_later_func,
screen,
NULL);
}
}
@@ -3045,6 +3194,10 @@ meta_screen_get_display (MetaScreen *screen)
return screen->display;
}
/**
* meta_screen_get_xroot: (skip)
*
*/
Window
meta_screen_get_xroot (MetaScreen *screen)
{
@@ -3060,6 +3213,10 @@ meta_screen_get_size (MetaScreen *screen,
*height = screen->rect.height;
}
/**
* meta_screen_get_compositor_data: (skip)
*
*/
gpointer
meta_screen_get_compositor_data (MetaScreen *screen)
{
@@ -3079,11 +3236,14 @@ meta_screen_set_cm_selection (MetaScreen *screen)
char selection[32];
Atom a;
screen->wm_cm_timestamp = meta_display_get_current_time_roundtrip (
screen->display);
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
meta_verbose ("Setting selection: %s\n", selection);
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
XSetSelectionOwner (screen->display->xdisplay, a,
screen->wm_cm_selection_window, CurrentTime);
screen->wm_cm_selection_window, screen->wm_cm_timestamp);
}
void
@@ -3094,9 +3254,16 @@ meta_screen_unset_cm_selection (MetaScreen *screen)
g_snprintf (selection, sizeof(selection), "_NET_WM_CM_S%d", screen->number);
a = XInternAtom (screen->display->xdisplay, selection, FALSE);
XSetSelectionOwner (screen->display->xdisplay, a, None, CurrentTime);
XSetSelectionOwner (screen->display->xdisplay, a,
None, screen->wm_cm_timestamp);
}
/**
* meta_screen_get_workspaces: (skip)
* @screen: a #MetaScreen
*
* Returns: (transfer none) (element-type Meta.Workspace): The workspaces for @screen
*/
GList *
meta_screen_get_workspaces (MetaScreen *screen)
{

View File

@@ -29,6 +29,7 @@
#include <X11/Xatom.h>
#include <time.h>
#include <sys/wait.h>
#ifndef HAVE_SM
void
@@ -83,6 +84,7 @@ static char* load_state (const char *previous_save_file);
static void regenerate_save_file (void);
static const char* full_save_file (void);
static void warn_about_lame_clients_and_finish_interact (gboolean shutdown);
static void disconnect (void);
/* This is called when data is available on an ICE connection. */
static gboolean
@@ -105,9 +107,12 @@ process_ice_messages (GIOChannel *channel,
IcePointer context = IceGetConnectionContext (connection);
#endif
/* We were disconnected */
IceSetShutdownNegotiation (connection, False);
IceCloseConnection (connection);
/* We were disconnected; close our connection to the
* session manager, this will result in the ICE connection
* being cleaned up, since it is owned by libSM.
*/
disconnect ();
meta_quit (META_EXIT_SUCCESS);
return FALSE;
}
@@ -1104,8 +1109,6 @@ load_state (const char *previous_save_file)
{
/* oh, just give up */
meta_warning (_("Failed to read saved session file %s: %s\n"),
canonical_session_file, error->message);
g_error_free (error);
g_free (session_file);
g_free (canonical_session_file);
@@ -1749,11 +1752,11 @@ finish_interact (gboolean shutdown)
}
static void
sigchld_handler (MetaNexus *nexus, guint arg1, gpointer arg2, gpointer user_data)
dialog_closed (GPid pid, int status, gpointer user_data)
{
gboolean shutdown = GPOINTER_TO_INT (user_data);
if (arg1 == 0) /* pressed "OK" */
if (WIFEXITED (status) && WEXITSTATUS (status) == 0) /* pressed "OK" */
{
finish_interact (shutdown);
}
@@ -1767,6 +1770,7 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
GSList *lame_details = NULL;
GSList *tmp;
GSList *columns = NULL;
GPid pid;
windows = meta_display_list_windows (meta_get_display (), META_LIST_DEFAULT);
tmp = windows;
@@ -1814,23 +1818,20 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
}
g_slist_free (lame);
meta_show_dialog("--list",
_("These windows do not support &quot;save current setup&quot; "
"and will have to be restarted manually next time "
"you log in."),
"240",
meta_screen_get_screen_number (meta_get_display()->active_screen),
NULL, NULL,
None,
columns,
lame_details);
pid = meta_show_dialog("--list",
_("These windows do not support &quot;save current setup&quot; "
"and will have to be restarted manually next time "
"you log in."),
"240",
meta_screen_get_screen_number (meta_get_display()->active_screen),
NULL, NULL,
None,
columns,
lame_details);
g_slist_free (lame_details);
g_signal_connect (sigchld_nexus, "sigchld",
G_CALLBACK (sigchld_handler),
GINT_TO_POINTER (shutdown));
g_child_watch_add (pid, dialog_closed, GINT_TO_POINTER (shutdown));
}
#endif /* HAVE_SM */

View File

@@ -23,6 +23,7 @@
#include <string.h>
#include "frame-private.h"
#include "screen-private.h"
#include "stack-tracker.h"
#include "util.h"
@@ -134,7 +135,7 @@ struct _MetaStackTracker
/* Idle function used to sync the compositor's view of the window
* stack up with our best guess before a frame is drawn.
*/
guint sync_stack_idle;
guint sync_stack_later;
};
static void
@@ -383,8 +384,8 @@ meta_stack_tracker_new (MetaScreen *screen)
void
meta_stack_tracker_free (MetaStackTracker *tracker)
{
if (tracker->sync_stack_idle)
g_source_remove (tracker->sync_stack_idle);
if (tracker->sync_stack_later)
meta_later_remove (tracker->sync_stack_later);
g_array_free (tracker->server_stack, TRUE);
if (tracker->predicted_stack)
@@ -667,10 +668,10 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
int n_windows;
int i;
if (tracker->sync_stack_idle)
if (tracker->sync_stack_later)
{
g_source_remove (tracker->sync_stack_idle);
tracker->sync_stack_idle = 0;
meta_later_remove (tracker->sync_stack_later);
tracker->sync_stack_later = 0;
}
meta_stack_tracker_get_stack (tracker, &windows, &n_windows);
@@ -682,7 +683,15 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
meta_window = meta_display_lookup_x_window (tracker->screen->display,
windows[i]);
if (meta_window)
/* When mapping back from xwindow to MetaWindow we have to be a bit careful;
* children of the root could include unmapped windows created by toolkits
* for internal purposes, including ones that we have registered in our
* XID => window table. (Wine uses a toplevel for _NET_WM_USER_TIME_WINDOW;
* see window-prop.c:reload_net_wm_user_time_window() for registration.)
*/
if (meta_window &&
(windows[i] == meta_window->xwindow ||
(meta_window->frame && windows[i] == meta_window->frame->xwindow)))
meta_windows = g_list_prepend (meta_windows, meta_window);
}
@@ -696,7 +705,7 @@ meta_stack_tracker_sync_stack (MetaStackTracker *tracker)
}
static gboolean
stack_tracker_sync_stack_idle (gpointer data)
stack_tracker_sync_stack_later (gpointer data)
{
meta_stack_tracker_sync_stack (data);
@@ -719,10 +728,10 @@ stack_tracker_sync_stack_idle (gpointer data)
void
meta_stack_tracker_queue_sync_stack (MetaStackTracker *tracker)
{
if (tracker->sync_stack_idle == 0)
if (tracker->sync_stack_later == 0)
{
tracker->sync_stack_idle = g_idle_add_full (META_PRIORITY_BEFORE_REDRAW,
stack_tracker_sync_stack_idle,
tracker->sync_stack_later = meta_later_add (META_LATER_BEFORE_REDRAW,
stack_tracker_sync_stack_later,
tracker, NULL);
}
}

View File

@@ -26,9 +26,12 @@
#define _POSIX_C_SOURCE 200112L /* for fdopen() */
#include <config.h>
#include "common.h"
#include "util.h"
#include "main.h"
#include <clutter/clutter.h> /* For clutter_threads_add_repaint_func() */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -37,7 +40,12 @@
#include <X11/Xlib.h> /* must explicitly be included for Solaris; #326746 */
#include <X11/Xutil.h> /* Just for the definition of the various gravities */
MetaNexus *sigchld_nexus;
#ifdef WITH_VERBOSE_MODE
static void
meta_topic_real_valist (MetaDebugTopic topic,
const char *format,
va_list args);
#endif
#ifdef HAVE_BACKTRACE
#include <execinfo.h>
@@ -70,7 +78,7 @@ meta_print_backtrace (void)
}
#endif
static gboolean is_verbose = FALSE;
static gint verbose_topics = 0;
static gboolean is_debugging = FALSE;
static gboolean replace_current = FALSE;
static int no_prefix = 0;
@@ -127,7 +135,7 @@ ensure_logfile (void)
gboolean
meta_is_verbose (void)
{
return is_verbose;
return verbose_topics != 0;
}
void
@@ -140,8 +148,48 @@ meta_set_verbose (gboolean setting)
if (setting)
ensure_logfile ();
#endif
is_verbose = setting;
if (setting)
meta_add_verbose_topic (META_DEBUG_VERBOSE);
else
meta_remove_verbose_topic (META_DEBUG_VERBOSE);
}
/**
* meta_add_verbose_topic:
* @topic: Topic for which logging will be started
*
* Ensure log messages for the given topic @topic
* will be printed.
*/
void
meta_add_verbose_topic (MetaDebugTopic topic)
{
if (verbose_topics == META_DEBUG_VERBOSE)
return;
if (topic == META_DEBUG_VERBOSE)
verbose_topics = META_DEBUG_VERBOSE;
else
verbose_topics |= topic;
}
/**
* meta_remove_verbose_topic:
* @topic: Topic for which logging will be stopped
*
* Stop printing log messages for the given topic @topic. Note
* that this method does not stack with meta_add_verbose_topic();
* i.e. if two calls to meta_add_verbose_topic() for the same
* topic are made, one call to meta_remove_verbose_topic() will
* remove it.
*/
void
meta_remove_verbose_topic (MetaDebugTopic topic)
{
if (topic == META_DEBUG_VERBOSE)
verbose_topics = 0;
else
verbose_topics &= ~topic;
}
gboolean
@@ -249,27 +297,10 @@ void
meta_verbose_real (const char *format, ...)
{
va_list args;
gchar *str;
FILE *out;
g_return_if_fail (format != NULL);
if (!is_verbose)
return;
va_start (args, format);
str = g_strdup_vprintf (format, args);
meta_topic_real_valist (META_DEBUG_VERBOSE, format, args);
va_end (args);
out = logfile ? logfile : stderr;
if (no_prefix == 0)
utf8_fputs ("Window manager: ", out);
utf8_fputs (str, out);
fflush (out);
g_free (str);
}
#endif /* WITH_VERBOSE_MODE */
@@ -323,6 +354,8 @@ topic_name (MetaDebugTopic topic)
return "COMPOSITOR";
case META_DEBUG_EDGE_RESISTANCE:
return "EDGE_RESISTANCE";
case META_DEBUG_VERBOSE:
return "VERBOSE";
}
return "WM";
@@ -330,23 +363,22 @@ topic_name (MetaDebugTopic topic)
static int sync_count = 0;
void
meta_topic_real (MetaDebugTopic topic,
const char *format,
...)
static void
meta_topic_real_valist (MetaDebugTopic topic,
const char *format,
va_list args)
{
va_list args;
gchar *str;
FILE *out;
g_return_if_fail (format != NULL);
if (!is_verbose)
if (verbose_topics == 0
|| (topic == META_DEBUG_VERBOSE && verbose_topics != META_DEBUG_VERBOSE)
|| (!(verbose_topics & topic)))
return;
va_start (args, format);
str = g_strdup_vprintf (format, args);
va_end (args);
out = logfile ? logfile : stderr;
@@ -365,6 +397,18 @@ meta_topic_real (MetaDebugTopic topic,
g_free (str);
}
void
meta_topic_real (MetaDebugTopic topic,
const char *format,
...)
{
va_list args;
va_start (args, format);
meta_topic_real_valist (topic, format, args);
va_end (args);
}
#endif /* WITH_VERBOSE_MODE */
void
@@ -557,7 +601,7 @@ meta_show_dialog (const char *type,
int i=0;
GPid child_pid;
const char **argvl = g_malloc(sizeof (char*) *
(15 +
(17 +
g_slist_length (columns)*2 +
g_slist_length (entries)));
@@ -565,6 +609,8 @@ meta_show_dialog (const char *type,
argvl[i++] = type;
argvl[i++] = "--screen";
argvl[i++] = screen_number_text;
argvl[i++] = "--class";
argvl[i++] = "mutter-dialog";
argvl[i++] = "--title";
/* Translators: This is the title used on dialog boxes */
argvl[i++] = _("Mutter");
@@ -638,30 +684,225 @@ meta_show_dialog (const char *type,
return child_pid;
}
GType
meta_nexus_get_type (void)
/***************************************************************************
* Later functions: like idles but integrated with the Clutter repaint loop
***************************************************************************/
static guint last_later_id = 0;
typedef struct
{
static GType nexus_type = 0;
guint id;
MetaLaterType when;
GSourceFunc func;
gpointer data;
GDestroyNotify notify;
int source;
gboolean run_once;
} MetaLater;
if (!nexus_type)
static GSList *laters = NULL;
/* This is a dummy timeline used to get the Clutter master clock running */
static ClutterTimeline *later_timeline;
static guint later_repaint_func = 0;
static void ensure_later_repaint_func (void);
static void
destroy_later (MetaLater *later)
{
if (later->source)
g_source_remove (later->source);
if (later->notify)
later->notify (later->data);
g_slice_free (MetaLater, later);
}
/* Used to sort the list of laters with the highest priority
* functions first.
*/
static int
compare_laters (gconstpointer a,
gconstpointer b)
{
return ((const MetaLater *)a)->when - ((const MetaLater *)b)->when;
}
static gboolean
run_repaint_laters (gpointer data)
{
GSList *old_laters = laters;
GSList *l;
gboolean keep_timeline_running = FALSE;
laters = NULL;
for (l = old_laters; l; l = l->next)
{
static const GTypeInfo nexus_info =
{
sizeof (MetaNexusClass),
NULL, NULL, NULL, NULL, NULL,
sizeof (MetaNexus),
0,
NULL, NULL
};
nexus_type = g_type_register_static (G_TYPE_OBJECT,
"MetaNexus",
&nexus_info,
0);
MetaLater *later = l->data;
if (later->source == 0 ||
(later->when <= META_LATER_BEFORE_REDRAW && !later->run_once))
{
if (later->func (later->data))
{
if (later->source == 0)
keep_timeline_running = TRUE;
laters = g_slist_insert_sorted (laters, later, compare_laters);
}
else
destroy_later (later);
}
else
laters = g_slist_insert_sorted (laters, later, compare_laters);
}
return nexus_type;
if (!keep_timeline_running)
clutter_timeline_stop (later_timeline);
g_slist_free (old_laters);
/* Just keep the repaint func around - it's cheap if the list is empty */
return TRUE;
}
static void
ensure_later_repaint_func (void)
{
if (!later_timeline)
later_timeline = clutter_timeline_new (G_MAXUINT);
if (later_repaint_func == 0)
later_repaint_func = clutter_threads_add_repaint_func (run_repaint_laters,
NULL, NULL);
/* Make sure the repaint function gets run */
clutter_timeline_start (later_timeline);
}
static gboolean
call_idle_later (gpointer data)
{
MetaLater *later = data;
if (!later->func (later->data))
{
laters = g_slist_remove (laters, later);
later->source = 0;
destroy_later (later);
return FALSE;
}
else
{
later->run_once = TRUE;
return TRUE;
}
}
/**
* meta_later_add:
* @when: enumeration value determining the phase at which to run the callback
* @func: callback to run later
* @data: data to pass to the callback
* @notify: function to call to destroy @data when it is no longer in use, or %NULL
*
* Sets up a callback to be called at some later time. @when determines the
* particular later occasion at which it is called. This is much like g_idle_add(),
* except that the functions interact properly with clutter event handling.
* If a "later" function is added from a clutter event handler, and is supposed
* to be run before the stage is redrawn, it will be run before that redraw
* of the stage, not the next one.
*
* Return value: an integer ID (guaranteed to be non-zero) that can be used
* to cancel the callback and prevent it from being run.
*/
guint
meta_later_add (MetaLaterType when,
GSourceFunc func,
gpointer data,
GDestroyNotify notify)
{
MetaLater *later = g_slice_new0 (MetaLater);
later->id = ++last_later_id;
later->when = when;
later->func = func;
later->data = data;
later->notify = notify;
laters = g_slist_insert_sorted (laters, later, compare_laters);
switch (when)
{
case META_LATER_RESIZE:
/* We add this one two ways - as a high-priority idle and as a
* repaint func. If we are in a clutter event callback, the repaint
* handler will get hit first, and we'll take care of this function
* there so it gets called before the stage is redrawn, even if
* we haven't gotten back to the main loop. Otherwise, the idle
* handler will get hit first and we want to call this function
* there so it will happen before GTK+ repaints.
*/
later->source = g_idle_add_full (META_PRIORITY_RESIZE, call_idle_later, later, NULL);
ensure_later_repaint_func ();
break;
case META_LATER_BEFORE_REDRAW:
ensure_later_repaint_func ();
break;
case META_LATER_IDLE:
later->source = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, call_idle_later, later, NULL);
break;
}
return later->id;
}
/**
* meta_later_remove:
* @later_id: the integer ID returned from meta_later_add()
*
* Removes a callback added with meta_later_add()
*/
void
meta_later_remove (guint later_id)
{
GSList *l;
for (l = laters; l; l = l->next)
{
MetaLater *later = l->data;
if (later->id == later_id)
{
laters = g_slist_remove_link (laters, l);
/* If this was a "repaint func" later, we just let the
* repaint func run and get removed
*/
destroy_later (later);
}
}
}
#ifdef USE_CAIRO_REGION
#include "region.h"
void
meta_region_get_rectangles (MetaRegion *region,
GdkRectangle **rectangles,
int *n_rectangles)
{
int n = cairo_region_num_rectangles (region);
if (n_rectangles != NULL)
*n_rectangles = n;
if (rectangles != NULL)
{
int i;
*rectangles = g_new (cairo_rectangle_int_t, n);
for (i = 0; i < n; i++)
cairo_region_get_rectangle (region, i, *rectangles + i);
}
}
#endif
/* eof util.c */

View File

@@ -46,9 +46,6 @@
typedef struct _MetaWindowQueue MetaWindowQueue;
typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window,
void *data);
typedef enum {
META_CLIENT_TYPE_UNKNOWN = 0,
META_CLIENT_TYPE_APPLICATION = 1,
@@ -64,6 +61,12 @@ typedef enum {
#define NUMBER_OF_QUEUES 3
typedef enum {
META_TILE_NONE,
META_TILE_LEFT,
META_TILE_RIGHT
} MetaTileMode;
struct _MetaWindow
{
GObject parent_instance;
@@ -99,6 +102,7 @@ struct _MetaWindow
char *sm_client_id;
char *wm_client_machine;
char *startup_id;
char *mutter_hints;
int net_wm_pid;
@@ -124,12 +128,23 @@ struct _MetaWindow
guint maximize_vertically_after_placement : 1;
guint minimize_after_placement : 1;
/* The current or requested tile mode. If maximized_vertically is true,
* this is the current mode. If not, it is the mode which will be
* requested after the window grab is released */
guint tile_mode : 2;
/* Whether we're shaded */
guint shaded : 1;
/* Whether we're fullscreen */
guint fullscreen : 1;
/* Whether the urgent flag of WM_HINTS is set */
guint wm_hints_urgent : 1;
/* Whether we have to fullscreen after placement */
guint fullscreen_after_placement : 1;
/* Area to cover when in fullscreen mode. If _NET_WM_FULLSCREEN_MONITORS has
* been overridden (via a client message), the window will cover the union of
* these monitors. If not, this is the single monitor which the window's
@@ -246,6 +261,9 @@ struct _MetaWindow
/* Have we placed this window? */
guint placed : 1;
/* Must we force_save_user_window_placement? */
guint force_save_user_rect : 1;
/* Is this not a transient of the focus window which is being denied focus? */
guint denied_focus_and_not_transient : 1;
@@ -316,6 +334,9 @@ struct _MetaWindow
*/
int unmaps_pending;
/* See docs for meta_window_get_stable_sequence() */
guint32 stable_sequence;
/* set to the most recent user-interaction event timestamp that we
know about for this window */
guint32 net_wm_user_time;
@@ -377,6 +398,7 @@ struct _MetaWindowClass
void (*workspace_changed) (MetaWindow *window, int old_workspace);
void (*focus) (MetaWindow *window);
void (*raised) (MetaWindow *window);
void (*unmanaged) (MetaWindow *window);
};
/* These differ from window->has_foo_func in that they consider
@@ -387,8 +409,11 @@ struct _MetaWindowClass
(w)->maximized_vertically)
#define META_WINDOW_MAXIMIZED_VERTICALLY(w) ((w)->maximized_vertically)
#define META_WINDOW_MAXIMIZED_HORIZONTALLY(w) ((w)->maximized_horizontally)
#define META_WINDOW_TILED(w) ((w)->maximized_vertically && \
!(w)->maximized_horizontally && \
(w)->tile_mode != META_TILE_NONE)
#define META_WINDOW_ALLOWS_MOVE(w) ((w)->has_move_func && !(w)->fullscreen)
#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !(w)->fullscreen && !(w)->shaded)
#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !META_WINDOW_TILED(w) && !(w)->fullscreen && !(w)->shaded)
#define META_WINDOW_ALLOWS_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && \
(((w)->size_hints.min_width < (w)->size_hints.max_width) || \
((w)->size_hints.min_height < (w)->size_hints.max_height)))
@@ -411,6 +436,11 @@ void meta_window_queue (MetaWindow *window,
void meta_window_maximize_internal (MetaWindow *window,
MetaMaximizeFlags directions,
MetaRectangle *saved_rect);
void meta_window_unmaximize_with_gravity (MetaWindow *window,
MetaMaximizeFlags directions,
int new_width,
int new_height,
int gravity);
void meta_window_make_above (MetaWindow *window);
void meta_window_unmake_above (MetaWindow *window);
void meta_window_shade (MetaWindow *window,
@@ -431,6 +461,8 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
unsigned long left,
unsigned long right);
gboolean meta_window_appears_focused (MetaWindow *window);
/* args to move are window pos, not frame pos */
void meta_window_move (MetaWindow *window,
gboolean user_op,
@@ -493,8 +525,6 @@ void meta_window_get_geometry (MetaWindow *window,
void meta_window_kill (MetaWindow *window);
void meta_window_focus (MetaWindow *window,
guint32 timestamp);
void meta_window_raise (MetaWindow *window);
void meta_window_lower (MetaWindow *window);
void meta_window_update_unfocused_button_grabs (MetaWindow *window);
@@ -552,6 +582,9 @@ void meta_window_get_work_area_for_monitor (MetaWindow *window,
void meta_window_get_work_area_all_monitors (MetaWindow *window,
MetaRectangle *area);
void meta_window_get_current_tile_area (MetaWindow *window,
MetaRectangle *tile_area);
gboolean meta_window_same_application (MetaWindow *window,
MetaWindow *other_window);
@@ -569,12 +602,6 @@ void meta_window_refresh_resize_popup (MetaWindow *window);
void meta_window_free_delete_dialog (MetaWindow *window);
void meta_window_foreach_transient (MetaWindow *window,
MetaWindowForeachFunc func,
void *data);
void meta_window_foreach_ancestor (MetaWindow *window,
MetaWindowForeachFunc func,
void *data);
void meta_window_begin_grab_op (MetaWindow *window,
MetaGrabOp op,
@@ -597,10 +624,6 @@ void meta_window_stack_just_below (MetaWindow *window,
void meta_window_set_user_time (MetaWindow *window,
guint32 timestamp);
void meta_window_set_demands_attention (MetaWindow *window);
void meta_window_unset_demands_attention (MetaWindow *window);
void meta_window_update_icon_now (MetaWindow *window);
void meta_window_update_role (MetaWindow *window);

View File

@@ -523,6 +523,49 @@ reload_wm_name (MetaWindow *window,
}
}
static void
reload_mutter_hints (MetaWindow *window,
MetaPropValue *value,
gboolean initial)
{
if (value->type != META_PROP_VALUE_INVALID)
{
char *new_hints = value->v.str;
char *old_hints = window->mutter_hints;
gboolean changed = FALSE;
if (new_hints)
{
if (!old_hints || strcmp (new_hints, old_hints))
changed = TRUE;
}
else
{
if (old_hints)
changed = TRUE;
}
if (changed)
{
g_free (old_hints);
if (new_hints)
window->mutter_hints = g_strdup (new_hints);
else
window->mutter_hints = NULL;
g_object_notify (G_OBJECT (window), "mutter-hints");
}
}
else if (window->mutter_hints)
{
g_free (window->mutter_hints);
window->mutter_hints = NULL;
g_object_notify (G_OBJECT (window), "mutter-hints");
}
}
static void
set_icon_title (MetaWindow *window,
const char *title)
@@ -604,6 +647,7 @@ reload_net_wm_state (MetaWindow *window,
window->shaded = FALSE;
window->maximized_horizontally = FALSE;
window->maximized_vertically = FALSE;
window->fullscreen = FALSE;
window->wm_state_modal = FALSE;
window->wm_state_skip_taskbar = FALSE;
window->wm_state_skip_pager = FALSE;
@@ -632,13 +676,7 @@ reload_net_wm_state (MetaWindow *window,
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_SKIP_PAGER)
window->wm_state_skip_pager = TRUE;
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_FULLSCREEN)
{
if (!window->fullscreen)
{
window->fullscreen = TRUE;
g_object_notify (G_OBJECT (window), "fullscreen");
}
}
window->fullscreen_after_placement = TRUE;
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_ABOVE)
window->wm_state_above = TRUE;
else if (value->v.atom_list.atoms[i] == window->display->atom__NET_WM_STATE_BELOW)
@@ -1350,8 +1388,10 @@ reload_wm_hints (MetaWindow *window,
gboolean initial)
{
Window old_group_leader;
gboolean old_urgent;
old_group_leader = window->xgroup_leader;
old_urgent = window->wm_hints_urgent;
/* Fill in defaults */
window->input = TRUE;
@@ -1359,7 +1399,8 @@ reload_wm_hints (MetaWindow *window,
window->xgroup_leader = None;
window->wm_hints_pixmap = None;
window->wm_hints_mask = None;
window->wm_hints_urgent = FALSE;
if (value->type != META_PROP_VALUE_INVALID)
{
const XWMHints *hints = value->v.wm_hints;
@@ -1378,7 +1419,10 @@ reload_wm_hints (MetaWindow *window,
if (hints->flags & IconMaskHint)
window->wm_hints_mask = hints->icon_mask;
if (hints->flags & XUrgencyHint)
window->wm_hints_urgent = TRUE;
meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx pixmap: 0x%lx mask: 0x%lx\n",
window->input, window->initially_iconic,
window->xgroup_leader,
@@ -1394,6 +1438,21 @@ reload_wm_hints (MetaWindow *window,
meta_window_group_leader_changed (window);
}
/*
* Do not emit urgency notification on the inital property load
*/
if (!initial && (window->wm_hints_urgent != old_urgent))
g_object_notify (G_OBJECT (window), "urgent");
/*
* Do not emit signal for the initial property load, let the constructor to
* take care of it once the MetaWindow is fully constructed.
*
* Only emit if the property is both changed and set.
*/
if (!initial && window->wm_hints_urgent && !old_urgent)
g_signal_emit_by_name (window->display, "window-marked-urgent", window);
meta_icon_cache_property_changed (&window->icon_cache,
window->display,
XA_WM_HINTS);
@@ -1490,6 +1549,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
{ XA_WM_CLASS, META_PROP_VALUE_CLASS_HINT, reload_wm_class, TRUE, TRUE },
{ display->atom__NET_WM_PID, META_PROP_VALUE_CARDINAL, reload_net_wm_pid, TRUE, TRUE },
{ XA_WM_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_name, TRUE, TRUE },
{ display->atom__MUTTER_HINTS, META_PROP_VALUE_TEXT_PROPERTY, reload_mutter_hints, TRUE, TRUE },
{ display->atom__NET_WM_ICON_NAME, META_PROP_VALUE_UTF8, reload_net_wm_icon_name, TRUE, FALSE },
{ XA_WM_ICON_NAME, META_PROP_VALUE_TEXT_PROPERTY, reload_wm_icon_name, TRUE, FALSE },
{ display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop, TRUE, FALSE },

File diff suppressed because it is too large Load Diff

View File

@@ -33,6 +33,9 @@
#include <X11/Xatom.h>
#include <string.h>
#ifdef HAVE_LIBCANBERRA
#include <canberra-gtk.h>
#endif
enum {
PROP_0,
@@ -439,6 +442,69 @@ meta_workspace_queue_calc_showing (MetaWorkspace *workspace)
}
}
static void
workspace_switch_sound(MetaWorkspace *from,
MetaWorkspace *to)
{
#ifdef HAVE_LIBCANBERRA
MetaWorkspaceLayout layout;
int i, nw, x, y, fi, ti;
const char *e;
nw = meta_screen_get_n_workspaces(from->screen);
fi = meta_workspace_index(from);
ti = meta_workspace_index(to);
meta_screen_calc_workspace_layout(from->screen,
nw,
fi,
&layout);
for (i = 0; i < nw; i++)
if (layout.grid[i] == ti)
break;
if (i >= nw)
{
meta_bug("Failed to find destination workspace in layout\n");
goto finish;
}
y = i / layout.cols;
x = i % layout.cols;
/* We priorize horizontal over vertical movements here. The
rationale for this is that horizontal movements are probably more
interesting for sound effects because speakers are usually
positioned on a horizontal and not a vertical axis. i.e. your
spatial "Woosh!" effects will easily be able to encode horizontal
movement but not such much vertical movement. */
if (x < layout.current_col)
e = "desktop-switch-left";
else if (x > layout.current_col)
e = "desktop-switch-right";
else if (y < layout.current_row)
e = "desktop-switch-up";
else if (y > layout.current_row)
e = "desktop-switch-down";
else
{
meta_bug("Uh, origin and destination workspace at same logic position!\n");
goto finish;
}
ca_context_play(ca_gtk_context_get(), 1,
CA_PROP_EVENT_ID, e,
CA_PROP_EVENT_DESCRIPTION, "Desktop switched",
CA_PROP_CANBERRA_CACHE_CONTROL, "permanent",
NULL);
finish:
meta_screen_free_workspace_layout (&layout);
#endif /* HAVE_LIBCANBERRA */
}
/**
* meta_workspace_activate_with_focus:
* @workspace: a #MetaWorkspace
@@ -478,6 +544,13 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
if (workspace->screen->active_workspace == workspace)
return;
/* Free any cached pointers to the workspaces's edges from
* a current resize or move operation */
meta_display_cleanup_edges (workspace->screen->display);
if (workspace->screen->active_workspace)
workspace_switch_sound (workspace->screen->active_workspace, workspace);
/* Note that old can be NULL; e.g. when starting up */
old = workspace->screen->active_workspace;
@@ -633,12 +706,12 @@ meta_workspace_update_window_hints (MetaWorkspace *workspace)
/**
* meta_workspace_list_windows:
* @display: a #MetaDisplay
* @workspace: a #MetaWorkspace
*
* Gets windows contained on the workspace, including workspace->windows
* and also sticky windows. Override-redirect windows are not included.
*
* Return value: (transfer container): the list of windows.
* Return value: (transfer container) (element-type MetaWindow): the list of windows.
*/
GList*
meta_workspace_list_windows (MetaWorkspace *workspace)
@@ -713,6 +786,11 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
"Invalidating work area for workspace %d\n",
meta_workspace_index (workspace));
/* If we are in the middle of a resize or move operation, we
* might have cached pointers to the workspace's edges */
if (workspace == workspace->screen->active_workspace)
meta_display_cleanup_edges (workspace->screen->display);
g_free (workspace->work_area_monitor);
workspace->work_area_monitor = NULL;
@@ -950,6 +1028,23 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
}
}
static gboolean
strut_lists_equal (GSList *l,
GSList *m)
{
for (; l && m; l = l->next, m = m->next)
{
MetaStrut *a = l->data;
MetaStrut *b = m->data;
if (a->side != b->side ||
!meta_rectangle_equal (&a->rect, &b->rect))
return FALSE;
}
return l == NULL && m == NULL;
}
/**
* meta_workspace_set_builtin_struts:
* @workspace: a #MetaWorkspace
@@ -963,6 +1058,12 @@ void
meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
GSList *struts)
{
/* Reordering doesn't actually matter, so we don't catch all
* no-impact changes, but this is just a (possibly unnecessary
* anyways) optimization */
if (strut_lists_equal (struts, workspace->builtin_struts))
return;
workspace_free_builtin_struts (workspace);
workspace->builtin_struts = copy_strut_list (struts);
@@ -1202,7 +1303,10 @@ focus_ancestor_or_mru_window (MetaWorkspace *workspace,
MetaWindow *ancestor;
ancestor = NULL;
meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor);
if (ancestor != NULL)
if (ancestor != NULL &&
(ancestor->on_all_workspaces ||
ancestor->workspace == workspace) &&
meta_window_showing_on_its_workspace (ancestor))
{
meta_topic (META_DEBUG_FOCUS,
"Focusing %s, ancestor of %s\n",

View File

@@ -264,6 +264,16 @@ cardinal_list_from_results (GetPropertyResults *results,
*n_cardinals_p = results->n_items;
results->prop = NULL;
#if GLIB_SIZEOF_LONG == 8
/* Xlib sign-extends format=32 items, but we want them unsigned */
{
int i;
for (i = 0; i < *n_cardinals_p; i++)
(*cardinals_p)[i] = (*cardinals_p)[i] & 0xffffffff;
}
#endif
return TRUE;
}
@@ -608,6 +618,10 @@ cardinal_with_atom_type_from_results (GetPropertyResults *results,
return FALSE;
*cardinal_p = *(gulong*) results->prop;
#if GLIB_SIZEOF_LONG == 8
/* Xlib sign-extends format=32 items, but we want them unsigned */
*cardinal_p &= 0xffffffff;
#endif
XFree (results->prop);
results->prop = NULL;

80
src/gdk-compat.h Normal file
View File

@@ -0,0 +1,80 @@
#ifndef __GDK_COMPAT_H__
#define __GDK_COMPAT_H__
#include <gdk/gdk.h>
#include <math.h>
/* Provide a compatibility layer for accessor function introduced
* in GTK+ 2.22 which we need to build without deprecated GDK symbols.
* That way it is still possible to build with GTK+ 2.18 when not
* using GDK_DISABLE_DEPRECATED.
*/
#if !GTK_CHECK_VERSION (2, 21, 1)
#define gdk_visual_get_depth(v) GDK_VISUAL(v)->depth
#endif /* GTK_CHECK_VERSION (2, 21, 1) */
#if !GTK_CHECK_VERSION (2, 90, 8)
#define gdk_window_get_screen gdk_drawable_get_screen
#define gdk_pixbuf_get_from_window(window, src_x, src_y, width, height) \
gdk_pixbuf_get_from_drawable(NULL, window, NULL, src_x, src_y, 0, 0, width, height)
static inline int
gdk_window_get_width (GdkWindow *window)
{
int width;
gdk_drawable_get_size (window, &width, NULL);
return width;
}
static inline int
gdk_window_get_height (GdkWindow *window)
{
int height;
gdk_drawable_get_size (window, NULL, &height);
return height;
}
static inline gboolean
gdk_cairo_get_clip_rectangle (cairo_t *cr,
GdkRectangle *rect)
{
double x1, y1, x2, y2;
gboolean clip_exists;
cairo_clip_extents (cr, &x1, &y1, &x2, &y2);
clip_exists = x1 < x2 && y1 < y2;
if (rect)
{
x1 = floor (x1);
y1 = floor (y1);
x2 = ceil (x2);
y2 = ceil (y2);
rect->x = CLAMP (x1, G_MININT, G_MAXINT);
rect->y = CLAMP (y1, G_MININT, G_MAXINT);
rect->width = CLAMP (x2 - x1, G_MININT, G_MAXINT);
rect->height = CLAMP (y2 - y1, G_MININT, G_MAXINT);
}
return clip_exists;
}
#endif /* GTK_CHECK_VERSION (2, 90, 8) */
/* Compatibility with old GDK key symbols */
#ifndef GDK_KEY_Escape
#define GDK_KEY_Escape GDK_Escape
#endif /* GDK_KEY_Escape */
#endif /* __GDK_COMPAT_H__ */

177
src/gdk2-drawing-utils.c Normal file
View File

@@ -0,0 +1,177 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2010 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.
*/
#include <config.h>
#include "gdk2-drawing-utils.h"
#include <math.h>
#include "gdk-compat.h"
#ifndef USE_GTK3
static const cairo_user_data_key_t context_key;
cairo_t *
meta_cairo_create (GdkDrawable *drawable)
{
cairo_t *cr;
cr = gdk_cairo_create (drawable);
cairo_set_user_data (cr, &context_key, drawable, NULL);
return cr;
}
static GdkWindow *
extract_window (cairo_t *cr,
int *dx,
int *dy,
GdkRectangle *clip_area)
{
GdkWindow *window = cairo_get_user_data (cr, &context_key);
cairo_matrix_t matrix;
g_assert (dx != NULL);
g_assert (dy != NULL);
g_assert (clip_area != NULL);
/* lots of stuff that mustn't happen because we can't cope with it. */
if (window == NULL)
{
g_error ("Could not get the GdkWindow from the cairo context passed to\n"
"theme drawing functions. A GdkWindow must be set on all cairo\n"
"context passed to theme drawing functions when using GTK2.\n"
"Please use meta_cairo_create() to create the Cairo context.\n");
}
cairo_get_matrix (cr, &matrix);
if (matrix.xx != 1.0 || matrix.yy != 1.0 ||
matrix.xy != 0.0 || matrix.yx != 0.0 ||
floor (matrix.x0) != matrix.x0 ||
floor (matrix.y0) != matrix.y0)
{
g_error ("GTK2 drawing requires that the matrix set on the cairo context\n"
"is an integer translation, however that is not the case.\n");
}
gdk_cairo_get_clip_rectangle (cr, clip_area);
clip_area->x += matrix.x0;
clip_area->y += matrix.y0;
*dx = matrix.x0;
*dy = matrix.y0;
return window;
}
void
meta_paint_vline (GtkStyle *style,
cairo_t *cr,
GtkStateType state_type,
GtkWidget *widget,
const gchar *detail,
gint y1_,
gint y2_,
gint x)
{
int dx, dy;
GdkWindow *window;
GdkRectangle area;
window = extract_window (cr, &dx, &dy, &area);
gtk_paint_vline (style, window, state_type, &area,
widget, detail, y1_ + dy, y2_ + dy, x + dx);
}
void
meta_paint_arrow (GtkStyle *style,
cairo_t *cr,
GtkStateType state_type,
GtkShadowType shadow_type,
GtkWidget *widget,
const gchar *detail,
GtkArrowType arrow_type,
gboolean fill,
gint x,
gint y,
gint width,
gint height)
{
int dx, dy;
GdkWindow *window;
GdkRectangle area;
window = extract_window (cr, &dx, &dy, &area);
gtk_paint_arrow (style, window, state_type, shadow_type,
&area, widget, detail, arrow_type,
fill, x + dx, y + dy, width, height);
}
void
meta_paint_box (GtkStyle *style,
cairo_t *cr,
GtkStateType state_type,
GtkShadowType shadow_type,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
int dx, dy;
GdkWindow *window;
GdkRectangle area;
window = extract_window (cr, &dx, &dy, &area);
gtk_paint_box (style, window, state_type, shadow_type,
&area, widget, detail,
x + dx, y + dy, width, height);
}
void
meta_paint_flat_box (GtkStyle *style,
cairo_t *cr,
GtkStateType state_type,
GtkShadowType shadow_type,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height)
{
int dx, dy;
GdkWindow *window;
GdkRectangle area;
window = extract_window (cr, &dx, &dy, &area);
gtk_paint_flat_box (style, window, state_type, shadow_type,
&area, widget, detail,
x + dx, y + dy, width, height);
}
#endif /* USE_GTK3 */

100
src/gdk2-drawing-utils.h Normal file
View File

@@ -0,0 +1,100 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2010 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 __GTK3_COMPAT_H__
#define __GTK3_COMPAT_H__
#include <gtk/gtk.h>
#if GTK_CHECK_VERSION (2, 90, 8)
#define USE_GTK3 1
#define MetaPixmap cairo_surface_t
#define meta_pixmap_new(window, w, h) gdk_window_create_similar_surface (window, CAIRO_CONTENT_COLOR, w, h)
#define meta_pixmap_free(pixmap) cairo_surface_destroy (pixmap)
#define meta_pixmap_cairo_create(pixmap) cairo_create (pixmap)
#define meta_cairo_set_source_pixmap(cr, pixmap, x, y) cairo_set_source_surface (cr, pixmap, x, y)
#define meta_paint_vline gtk_paint_vline
#define meta_paint_box gtk_paint_box
#define meta_paint_arrow gtk_paint_arrow
#define meta_paint_flat_box gtk_paint_flat_box
#else /* GTK_VERSION < 2.90.8 */
#undef USE_GTK3
#define MetaPixmap GdkPixmap
#define meta_pixmap_new(window, w, h) gdk_pixmap_new (window, w, h, -1)
#define meta_pixmap_free(pixmap) g_object_unref (pixmap)
#define meta_pixmap_cairo_create(pixmap) meta_cairo_create (pixmap)
#define meta_cairo_set_source_pixmap(cr, pixmap, x, y) gdk_cairo_set_source_pixmap (cr, pixmap, x, y)
/* This function only exists for GTK2 code. */
cairo_t * meta_cairo_create (GdkDrawable *drawable);
void meta_paint_vline (GtkStyle *style,
cairo_t *cr,
GtkStateType state_type,
GtkWidget *widget,
const gchar *detail,
gint y1_,
gint y2_,
gint x);
void meta_paint_arrow (GtkStyle *style,
cairo_t *cr,
GtkStateType state_type,
GtkShadowType shadow_type,
GtkWidget *widget,
const gchar *detail,
GtkArrowType arrow_type,
gboolean fill,
gint x,
gint y,
gint width,
gint height);
void meta_paint_box (GtkStyle *style,
cairo_t *cr,
GtkStateType state_type,
GtkShadowType shadow_type,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height);
void meta_paint_flat_box (GtkStyle *style,
cairo_t *cr,
GtkStateType state_type,
GtkShadowType shadow_type,
GtkWidget *widget,
const gchar *detail,
gint x,
gint y,
gint width,
gint height);
#endif /* GTK_VERSION < 2.90.8 */
#endif /* __GTK3_COMPAT_H__ */

26
src/gtk-compat.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef __GTK_COMPAT_H__
#define __GTK_COMPAT_H__
#include <gtk/gtk.h>
/* Provide a compatibility layer for accessor function introduces
* in GTK+ 2.20 which we need to build with GSEAL_ENABLE.
* That way it is still possible to build with GTK+ 2.18 when not
* using GSEAL_ENABLE
*/
#if !GTK_CHECK_VERSION (2, 20, 0)
#define gtk_widget_get_realized(w) GTK_WIDGET_REALIZED (w)
#define gtk_widget_get_requisition(w,r) (*r = GTK_WIDGET (w)->requisition)
#define gtk_widget_set_mapped(w,m) \
G_STMT_START { \
if (m) \
GTK_WIDGET_SET_FLAGS (w, GTK_MAPPED); \
else \
GTK_WIDGET_UNSET_FLAGS (w, GTK_MAPPED); \
} G_STMT_END
#endif /* GTK_CHECK_VERSION */
#endif /* __GTK_COMPAT_H__ */

View File

@@ -167,7 +167,7 @@ keybind (switch_panels_backward, handle_switch, META_TAB_LIST_DOCKS,
"using a popup window"))
keybind (cycle_group, handle_cycle, META_TAB_LIST_GROUP,
BINDING_REVERSES, "<Alt>F6",
BINDING_REVERSES, "<Alt>grave",
_("Move between windows of an application immediately"))
keybind (cycle_group_backward, handle_cycle, META_TAB_LIST_GROUP,
REVERSES_AND_REVERSED, NULL,

View File

@@ -1,73 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Metacity Alt-Tab abstraction */
/*
* Copyright (C) 2009 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_ALT_TAB_HANDLER_H
#define META_ALT_TAB_HANDLER_H
#include <glib-object.h>
#include "types.h"
#define META_TYPE_ALT_TAB_HANDLER (meta_alt_tab_handler_get_type ())
#define META_ALT_TAB_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_ALT_TAB_HANDLER, MetaAltTabHandler))
#define META_ALT_TAB_HANDLER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), META_TYPE_ALT_TAB_HANDLER, MetaAltTabHandlerInterface))
typedef struct _MetaAltTabHandler MetaAltTabHandler;
typedef struct _MetaAltTabHandlerInterface MetaAltTabHandlerInterface;
struct _MetaAltTabHandlerInterface {
GTypeInterface g_iface;
void (*add_window) (MetaAltTabHandler *handler,
MetaWindow *window);
void (*show) (MetaAltTabHandler *handler,
MetaWindow *initial_selection);
void (*destroy) (MetaAltTabHandler *handler);
void (*forward) (MetaAltTabHandler *handler);
void (*backward) (MetaAltTabHandler *handler);
MetaWindow * (*get_selected) (MetaAltTabHandler *handler);
};
GType meta_alt_tab_handler_get_type (void);
void meta_alt_tab_handler_register (GType type);
MetaAltTabHandler *meta_alt_tab_handler_new (MetaScreen *screen,
gboolean immediate);
void meta_alt_tab_handler_add_window (MetaAltTabHandler *handler,
MetaWindow *window);
void meta_alt_tab_handler_show (MetaAltTabHandler *handler,
MetaWindow *initial_selection);
void meta_alt_tab_handler_destroy (MetaAltTabHandler *handler);
void meta_alt_tab_handler_forward (MetaAltTabHandler *handler);
void meta_alt_tab_handler_backward (MetaAltTabHandler *handler);
MetaWindow *meta_alt_tab_handler_get_selected (MetaAltTabHandler *handler);
#endif

View File

@@ -1,55 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Metacity Alt-Tab abstraction: default implementation */
/*
* Copyright (C) 2009 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_ALT_TAB_HANDLER_DEFAULT_H
#define META_ALT_TAB_HANDLER_DEFAULT_H
#include "alttabhandler.h"
#include "tabpopup.h"
#define META_TYPE_ALT_TAB_HANDLER_DEFAULT (meta_alt_tab_handler_default_get_type ())
#define META_ALT_TAB_HANDLER_DEFAULT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_ALT_TAB_HANDLER_DEFAULT, MetaAltTabHandlerDefault))
typedef struct _MetaAltTabHandlerDefault MetaAltTabHandlerDefault;
typedef struct _MetaAltTabHandlerDefaultClass MetaAltTabHandlerDefaultClass;
struct _MetaAltTabHandlerDefault {
GObject parent_instance;
MetaScreen *screen;
GArray *entries;
gboolean immediate_mode;
MetaTabPopup *tab_popup;
};
struct _MetaAltTabHandlerDefaultClass {
GObjectClass parent_class;
};
GType meta_alt_tab_handler_default_get_type (void);
#endif

View File

@@ -58,6 +58,7 @@ item(_MUTTER_RESTART_MESSAGE)
item(_MUTTER_RELOAD_THEME_MESSAGE)
item(_MUTTER_SET_KEYBINDINGS_MESSAGE)
item(_MUTTER_TOGGLE_VERBOSE)
item(_MUTTER_HINTS)
item(_GNOME_WM_KEYBINDINGS)
item(_GNOME_PANEL_ACTION)
item(_GNOME_PANEL_ACTION_MAIN_MENU)

View File

@@ -24,9 +24,11 @@
#ifndef META_BOXES_H
#define META_BOXES_H
#include <glib.h>
#include <glib-object.h>
#include "common.h"
#define META_TYPE_RECTANGLE (meta_rectangle_get_type ())
typedef struct _MetaRectangle MetaRectangle;
struct _MetaRectangle
{
@@ -70,6 +72,11 @@ struct _MetaEdge
MetaEdgeType edge_type;
};
GType meta_rectangle_get_type (void);
MetaRectangle *meta_rectangle_copy (const MetaRectangle *rect);
void meta_rectangle_free (MetaRectangle *rect);
/* Output functions -- note that the output buffer had better be big enough:
* rect_to_string: RECT_LENGTH
* region_to_string: (RECT_LENGTH+strlen(separator_string)) *

View File

@@ -52,6 +52,7 @@ typedef enum
typedef enum
{
META_MENU_OP_NONE = 0,
META_MENU_OP_DELETE = 1 << 0,
META_MENU_OP_MINIMIZE = 1 << 1,
META_MENU_OP_UNMAXIMIZE = 1 << 2,
@@ -317,8 +318,10 @@ struct _MetaButtonLayout
* coelesce multiple things together, the appropriate place to
* do it is usually META_PRIORITY_BEFORE_REDRAW.
*
* (FIXME: Use a Clutter paint() function instead, to prevent
* starving the repaints)
* Note that its usually better to use meta_later_add() rather
* than calling g_idle_add() directly; this will make sure things
* get run when added from a clutter event handler without
* waiting for another repaint cycle.
*
* If something has a priority lower than the redraw priority
* (such as a default priority idle), then it may be arbitrarily

View File

@@ -30,29 +30,6 @@
#include "window.h"
#include "workspace.h"
typedef enum _MetaCompWindowType
{
META_COMP_WINDOW_NORMAL = META_WINDOW_NORMAL,
META_COMP_WINDOW_DESKTOP = META_WINDOW_DESKTOP,
META_COMP_WINDOW_DOCK = META_WINDOW_DOCK,
META_COMP_WINDOW_DIALOG = META_WINDOW_DIALOG,
META_COMP_WINDOW_MODAL_DIALOG = META_WINDOW_MODAL_DIALOG,
META_COMP_WINDOW_TOOLBAR = META_WINDOW_TOOLBAR,
META_COMP_WINDOW_MENU = META_WINDOW_MENU,
META_COMP_WINDOW_UTILITY = META_WINDOW_UTILITY,
META_COMP_WINDOW_SPLASHSCREEN = META_WINDOW_SPLASHSCREEN,
/* override redirect window types, */
META_COMP_WINDOW_DROPDOWN_MENU = META_WINDOW_DROPDOWN_MENU,
META_COMP_WINDOW_POPUP_MENU = META_WINDOW_POPUP_MENU,
META_COMP_WINDOW_TOOLTIP = META_WINDOW_TOOLTIP,
META_COMP_WINDOW_NOTIFICATION = META_WINDOW_NOTIFICATION,
META_COMP_WINDOW_COMBO = META_WINDOW_COMBO,
META_COMP_WINDOW_DND = META_WINDOW_DND,
META_COMP_WINDOW_OVERRIDE_OTHER = META_WINDOW_OVERRIDE_OTHER
} MetaCompWindowType;
/**
* MetaCompEffect:
* @META_COMP_EFFECT_CREATE: The window is newly created

View File

@@ -116,6 +116,10 @@ void meta_core_user_focus (Display *xdisplay,
Window frame_xwindow,
guint32 timestamp);
void meta_core_lower_beneath_focus_window (Display *xdisplay,
Window xwindow,
guint32 timestamp);
void meta_core_minimize (Display *xdisplay,
Window frame_xwindow);
void meta_core_toggle_maximize (Display *xdisplay,

View File

@@ -26,6 +26,7 @@
#include <X11/Xlib.h>
#include "types.h"
#include "prefs.h"
#include "common.h"
typedef enum
@@ -81,6 +82,12 @@ gboolean meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
int meta_display_get_damage_event_base (MetaDisplay *display);
int meta_display_get_shape_event_base (MetaDisplay *display);
Atom meta_display_get_atom (MetaDisplay *display, MetaAtom meta_atom);
gboolean meta_display_xserver_time_is_before (MetaDisplay *display,
guint32 time1,
guint32 time2);
guint32 meta_display_get_last_user_time (MetaDisplay *display);
guint32 meta_display_get_current_time (MetaDisplay *display);
guint32 meta_display_get_current_time_roundtrip (MetaDisplay *display);
@@ -117,6 +124,10 @@ void meta_display_end_grab_op (MetaDisplay *display,
MetaGrabOp meta_display_get_grab_op (MetaDisplay *display);
MetaKeyBindingAction meta_display_get_keybinding_action (MetaDisplay *display,
unsigned int keysym,
unsigned int keycode,
unsigned long mask);
/* meta_display_set_input_focus_window is like XSetInputFocus, except
* that (a) it can't detect timestamps later than the current time,
@@ -140,4 +151,9 @@ void meta_display_focus_the_no_focus_window (MetaDisplay *display,
MetaScreen *screen,
guint32 timestamp);
GSList *meta_display_sort_windows_by_stacking (MetaDisplay *display,
GSList *windows);
Window meta_display_get_leader_window (MetaDisplay *display);
#endif

View File

@@ -23,6 +23,10 @@
#include "display.h"
#include "common.h"
/**
* MetaKeyHandlerFunc: (skip)
*
*/
typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
MetaScreen *screen,
MetaWindow *window,

View File

@@ -32,19 +32,6 @@
#include <X11/extensions/Xfixes.h>
#include <gmodule.h>
/*
* FIXME -- move these to a private include
* Required by plugin manager.
*/
#define MUTTER_PLUGIN_MINIMIZE (1<<0)
#define MUTTER_PLUGIN_MAXIMIZE (1<<1)
#define MUTTER_PLUGIN_UNMAXIMIZE (1<<2)
#define MUTTER_PLUGIN_MAP (1<<3)
#define MUTTER_PLUGIN_DESTROY (1<<4)
#define MUTTER_PLUGIN_SWITCH_WORKSPACE (1<<5)
#define MUTTER_PLUGIN_ALL_EFFECTS (~0)
#define MUTTER_TYPE_PLUGIN (mutter_plugin_get_type ())
#define MUTTER_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_PLUGIN, MutterPlugin))
#define MUTTER_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_PLUGIN, MutterPluginClass))
@@ -52,7 +39,15 @@
#define MUTTER_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_PLUGIN))
#define MUTTER_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_PLUGIN, MutterPluginClass))
/**
* MutterPlugin: (skip)
*
*/
typedef struct _MutterPlugin MutterPlugin;
/**
* MutterPluginClass: (skip)
*
*/
typedef struct _MutterPluginClass MutterPluginClass;
typedef struct _MutterPluginVersion MutterPluginVersion;
typedef struct _MutterPluginInfo MutterPluginInfo;
@@ -69,6 +64,8 @@ struct _MutterPluginClass
{
GObjectClass parent_class;
void (*start) (MutterPlugin *plugin);
void (*minimize) (MutterPlugin *plugin,
MutterWindow *actor);
@@ -93,20 +90,18 @@ struct _MutterPluginClass
MutterWindow *actor);
void (*switch_workspace) (MutterPlugin *plugin,
const GList **actors,
gint from,
gint to,
MetaMotionDirection direction);
/*
* Called if an effect should be killed prematurely; the plugin must
* Called if an effects should be killed prematurely; the plugin must
* call the completed() callback as if the effect terminated naturally.
* The events parameter is a bitmask indicating which effects are to be
* killed.
*/
void (*kill_effect) (MutterPlugin *plugin,
MutterWindow *actor,
gulong events);
void (*kill_window_effects) (MutterPlugin *plugin,
MutterWindow *actor);
void (*kill_switch_workspace) (MutterPlugin *plugin);
/* General XEvent filter. This is fired *before* mutter itself handles
* an event. Return TRUE to block any further processing.
@@ -225,9 +220,27 @@ struct _MutterPluginVersion
} \
void
mutter_plugin_effect_completed (MutterPlugin *plugin,
MutterWindow *actor,
unsigned long event);
mutter_plugin_switch_workspace_completed (MutterPlugin *plugin);
void
mutter_plugin_minimize_completed (MutterPlugin *plugin,
MutterWindow *actor);
void
mutter_plugin_maximize_completed (MutterPlugin *plugin,
MutterWindow *actor);
void
mutter_plugin_unmaximize_completed (MutterPlugin *plugin,
MutterWindow *actor);
void
mutter_plugin_map_completed (MutterPlugin *plugin,
MutterWindow *actor);
void
mutter_plugin_destroy_completed (MutterPlugin *plugin,
MutterWindow *actor);
ClutterActor *
mutter_plugin_get_overlay_group (MutterPlugin *plugin);

View File

@@ -59,7 +59,6 @@ struct _MutterWindow
GType mutter_window_get_type (void);
Window mutter_window_get_x_window (MutterWindow *mcw);
MetaCompWindowType mutter_window_get_window_type (MutterWindow *mcw);
gint mutter_window_get_workspace (MutterWindow *mcw);
gboolean mutter_window_is_hidden (MutterWindow *mcw);
MetaWindow * mutter_window_get_meta_window (MutterWindow *mcw);

View File

@@ -34,6 +34,7 @@ typedef enum
META_PREF_MOUSE_BUTTON_MODS,
META_PREF_FOCUS_MODE,
META_PREF_FOCUS_NEW_WINDOWS,
META_PREF_ATTACH_MODAL_DIALOGS,
META_PREF_RAISE_ON_CLICK,
META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
@@ -59,9 +60,11 @@ typedef enum
META_PREF_CURSOR_SIZE,
META_PREF_COMPOSITING_MANAGER,
META_PREF_RESIZE_WITH_RIGHT_BUTTON,
META_PREF_SIDE_BY_SIDE_TILING,
META_PREF_FORCE_FULLSCREEN,
META_PREF_CLUTTER_PLUGINS,
META_PREF_LIVE_HIDDEN_WINDOWS,
META_PREF_NO_TAB_POPUP,
META_PREF_NO_TAB_POPUP
} MetaPreference;
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@@ -73,6 +76,10 @@ void meta_prefs_remove_listener (MetaPrefsChangedFunc func,
gpointer data);
void meta_prefs_init (void);
void meta_prefs_override_preference_location (const char *original_key,
const char *new_key);
const char* meta_preference_to_string (MetaPreference pref);
MetaVirtualModifier meta_prefs_get_mouse_button_mods (void);
@@ -80,6 +87,7 @@ guint meta_prefs_get_mouse_button_resize (void);
guint meta_prefs_get_mouse_button_menu (void);
MetaFocusMode meta_prefs_get_focus_mode (void);
MetaFocusNewWindows meta_prefs_get_focus_new_windows (void);
gboolean meta_prefs_get_attach_modal_dialogs (void);
gboolean meta_prefs_get_raise_on_click (void);
const char* meta_prefs_get_theme (void);
/* returns NULL if GTK default should be used */
@@ -91,6 +99,7 @@ gboolean meta_prefs_get_auto_raise (void);
int meta_prefs_get_auto_raise_delay (void);
gboolean meta_prefs_get_gnome_accessibility (void);
gboolean meta_prefs_get_gnome_animations (void);
gboolean meta_prefs_get_side_by_side_tiling (void);
const char* meta_prefs_get_command (int i);
@@ -115,6 +124,7 @@ void meta_prefs_change_workspace_name (int i,
const char* meta_prefs_get_cursor_theme (void);
int meta_prefs_get_cursor_size (void);
gboolean meta_prefs_get_compositing_manager (void);
gboolean meta_prefs_get_force_fullscreen (void);
/**
* Sets whether the compositor is turned on.
@@ -123,6 +133,8 @@ gboolean meta_prefs_get_compositing_manager (void);
*/
void meta_prefs_set_compositing_manager (gboolean whether);
void meta_prefs_set_force_fullscreen (gboolean whether);
GSList * meta_prefs_get_clutter_plugins (void);
/**

60
src/include/region.h Normal file
View File

@@ -0,0 +1,60 @@
#ifndef META_REGION_H
#define META_REGION_H
#ifndef PACKAGE_NAME
#error "<config.h> must be included before region.h"
#endif
#include <gdk/gdk.h>
#ifdef USE_CAIRO_REGION
#include <cairo.h>
#define MetaRegion cairo_region_t
typedef enum {
META_REGION_OVERLAP_IN = CAIRO_REGION_OVERLAP_IN,
META_REGION_OVERLAP_OUT = CAIRO_REGION_OVERLAP_OUT,
META_REGION_OVERLAP_PART = CAIRO_REGION_OVERLAP_PART
} MetaOverlapType;
#define meta_region_new() cairo_region_create()
#define meta_region_new_from_rectangle(rect) cairo_region_create_rectangle(rect)
#define meta_region_copy(r) cairo_region_copy(r)
#define meta_region_destroy(r) cairo_region_destroy(r)
#define meta_region_is_empty(r) cairo_region_is_empty(r)
#define meta_region_union_rectangle(r, rect) cairo_region_union_rectangle(r, rect)
#define meta_region_subtract(r, other) cairo_region_subtract(r, other)
#define meta_region_translate(r, x, y) cairo_region_translate(r, x, y)
#define meta_region_intersect(r, other) cairo_region_intersect(r, other)
#define meta_region_contains_rectangle(r, rect) cairo_region_contains_rectangle(r, rect)
void meta_region_get_rectangles (MetaRegion *region,
GdkRectangle **rectangles,
int *n_rectangles);
#else
#define MetaRegion GdkRegion
typedef enum {
META_REGION_OVERLAP_IN = GDK_OVERLAP_RECTANGLE_IN,
META_REGION_OVERLAP_OUT = GDK_OVERLAP_RECTANGLE_OUT,
META_REGION_OVERLAP_PART = GDK_OVERLAP_RECTANGLE_PART
} MetaOverlapType;
#define meta_region_new() gdk_region_new()
#define meta_region_new_from_rectangle(rect) gdk_region_rectangle(rect)
#define meta_region_copy(r) gdk_region_copy(r)
#define meta_region_destroy(r) gdk_region_destroy(r)
#define meta_region_is_empty(r) gdk_region_empty(r)
#define meta_region_union_rectangle(r, rect) gdk_region_union_with_rect(r, rect)
#define meta_region_subtract(r, other) gdk_region_subtract(r, other)
#define meta_region_translate(r, x, y) gdk_region_offset(r, x, y)
#define meta_region_intersect(r, other) gdk_region_intersect(r, other)
#define meta_region_contains_rectangle(r, rect) gdk_region_rect_in(r, rect)
#define meta_region_get_rectangles(r, rects, num) gdk_region_get_rectangles(r, rects, num)
#endif /* HAVE_CAIRO_REGION */
#endif /* META_REGION_H */

View File

@@ -0,0 +1,39 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Meta tile preview */
/*
* Copyright (C) 2010 Florian Müllner
*
* 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_TILE_PREVIEW_H
#define META_TILE_PREVIEW_H
#include "boxes.h"
typedef struct _MetaTilePreview MetaTilePreview;
MetaTilePreview *meta_tile_preview_new (int screen_number,
gboolean composited);
void meta_tile_preview_free (MetaTilePreview *preview);
void meta_tile_preview_show (MetaTilePreview *preview,
MetaRectangle *rect);
void meta_tile_preview_hide (MetaTilePreview *preview);
Window meta_tile_preview_get_xwindow (MetaTilePreview *preview,
gulong *create_serial);
#endif /* META_TILE_PREVIEW_H */

View File

@@ -22,12 +22,20 @@
#ifndef META_TYPES_H
#define META_TYPES_H
/**
* MetaCompositor: (skip)
*
*/
typedef struct _MetaCompositor MetaCompositor;
typedef struct _MetaDisplay MetaDisplay;
typedef struct _MetaFrame MetaFrame;
typedef struct _MetaScreen MetaScreen;
typedef struct _MetaWindow MetaWindow;
typedef struct _MetaWorkspace MetaWorkspace;
/**
* MetaGroup: (skip)
*
*/
typedef struct _MetaGroup MetaGroup;
typedef struct _MetaKeyBinding MetaKeyBinding;

View File

@@ -33,8 +33,6 @@
typedef struct _MetaUI MetaUI;
typedef struct _MetaImageWindow MetaImageWindow;
typedef gboolean (* MetaEventFunc) (XEvent *xevent, gpointer data);
typedef enum
@@ -132,34 +130,10 @@ void meta_ui_window_menu_popup (MetaWindowMenu *menu,
void meta_ui_window_menu_free (MetaWindowMenu *menu);
MetaImageWindow* meta_image_window_new (Display *xdisplay,
int screen_number,
int max_width,
int max_height);
void meta_image_window_free (MetaImageWindow *iw);
void meta_image_window_set_showing (MetaImageWindow *iw,
gboolean showing);
void meta_image_window_set (MetaImageWindow *iw,
GdkPixbuf *pixbuf,
int x,
int y);
/* FIXME these lack a display arg */
GdkPixbuf* meta_gdk_pixbuf_get_from_window (GdkPixbuf *dest,
Window xwindow,
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
int src_x,
int src_y,
int dest_x,
int dest_y,
int width,
int height);
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (GdkPixbuf *dest,
Pixmap xpixmap,
int src_x,
int src_y,
int dest_x,
int dest_y,
int width,
int height);
@@ -200,8 +174,7 @@ int meta_ui_get_drag_threshold (MetaUI *ui);
MetaUIDirection meta_ui_get_direction (void);
GdkPixbuf *meta_ui_get_pixbuf_from_pixmap (Pixmap pmap);
#include "tabpopup.h"
#include "tile-preview.h"
#endif

View File

@@ -51,6 +51,7 @@ void meta_fatal (const char *format,
typedef enum
{
META_DEBUG_VERBOSE = -1,
META_DEBUG_FOCUS = 1 << 0,
META_DEBUG_WORKAREA = 1 << 1,
META_DEBUG_STACK = 1 << 2,
@@ -78,6 +79,8 @@ typedef enum
void meta_topic_real (MetaDebugTopic topic,
const char *format,
...) G_GNUC_PRINTF (2, 3);
void meta_add_verbose_topic (MetaDebugTopic topic);
void meta_remove_verbose_topic (MetaDebugTopic topic);
void meta_push_no_msg_prefix (void);
void meta_pop_no_msg_prefix (void);
@@ -131,35 +134,25 @@ GPid meta_show_dialog (const char *type,
#endif /* !WITH_VERBOSE_MODE */
#include <glib-object.h>
#define META_TYPE_NEXUS (meta_nexus_get_type ())
#define META_NEXUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_NEXUS, MetaNexus))
#define META_NEXUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_NEXUS, MetaNexusClass))
#define META_IS_NEXUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_NEXUS))
#define META_IS_NEXUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_NEXUS))
#define META_NEXUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_NEXUS, MetaNexusClass))
typedef struct _MetaNexus
{
GObject parent_instance;
} MetaNexus;
typedef struct _MetaNexusClass
{
GObjectClass parent_class;
} MetaNexusClass;
GType meta_nexus_get_type (void) G_GNUC_CONST;
MetaNexus *meta_nexus_new ();
/**
* An object which exists purely to attach signals to; this is to receive
* signals when a child process exits. The signal is "sigchld" with no detail.
*
* \bug Eventually we should have a specialised type for objects like these.
*/
extern MetaNexus *sigchld_nexus;
* MetaLaterType:
* @META_LATER_RESIZE: call in a resize processing phase that is done
* before GTK+ repainting (including window borders) is done.
* @META_LATER_BEFORE_REDRAW: call before the stage is redrawn
* @META_LATER_IDLE: call at a very low priority (can be blocked
* by running animations or redrawing applications)
**/
typedef enum {
META_LATER_RESIZE,
META_LATER_BEFORE_REDRAW,
META_LATER_IDLE
} MetaLaterType;
guint meta_later_add (MetaLaterType when,
GSourceFunc func,
gpointer data,
GDestroyNotify notify);
void meta_later_remove (guint later_id);
#endif /* META_UTIL_H */

View File

@@ -88,9 +88,13 @@ void meta_window_activate_with_workspace (MetaWindow *window,
MetaWorkspace *workspace);
const char * meta_window_get_description (MetaWindow *window);
const char * meta_window_get_wm_class (MetaWindow *window);
const char * meta_window_get_wm_class_instance (MetaWindow *window);
/* Return whether the window would be showing if we were on its workspace */
gboolean meta_window_showing_on_its_workspace (MetaWindow *window);
void meta_window_set_demands_attention (MetaWindow *window);
void meta_window_unset_demands_attention (MetaWindow *window);
const char* meta_window_get_startup_id (MetaWindow *window);
void meta_window_change_workspace_by_index (MetaWindow *window,
gint space_index,
@@ -104,6 +108,17 @@ MetaStackLayer meta_window_get_layer (MetaWindow *window);
MetaWindow* meta_window_find_root_ancestor (MetaWindow *window);
gboolean meta_window_is_ancestor_of_transient (MetaWindow *window,
MetaWindow *transient);
typedef gboolean (*MetaWindowForeachFunc) (MetaWindow *window,
void *data);
void meta_window_foreach_transient (MetaWindow *window,
MetaWindowForeachFunc func,
void *user_data);
void meta_window_foreach_ancestor (MetaWindow *window,
MetaWindowForeachFunc func,
void *user_data);
gboolean meta_window_is_mapped (MetaWindow *window);
gboolean meta_window_toplevel_is_mapped (MetaWindow *window);
gboolean meta_window_get_icon_geometry (MetaWindow *window,
@@ -114,12 +129,18 @@ void meta_window_unmaximize (MetaWindow *window,
MetaMaximizeFlags directions);
void meta_window_minimize (MetaWindow *window);
void meta_window_unminimize (MetaWindow *window);
void meta_window_raise (MetaWindow *window);
void meta_window_lower (MetaWindow *window);
const char *meta_window_get_title (MetaWindow *window);
MetaWindow *meta_window_get_transient_for (MetaWindow *window);
Window meta_window_get_transient_for_as_xid (MetaWindow *window);
void meta_window_delete (MetaWindow *window,
guint32 timestamp);
guint meta_window_get_stable_sequence (MetaWindow *window);
guint32 meta_window_get_user_time (MetaWindow *window);
int meta_window_get_pid (MetaWindow *window);
const char *meta_window_get_client_machine (MetaWindow *window);
gboolean meta_window_is_remote (MetaWindow *window);
gboolean meta_window_is_modal (MetaWindow *window);
const char *meta_window_get_mutter_hints (MetaWindow *window);
#endif

Some files were not shown because too many files have changed in this diff Show More