Compare commits

...

37 Commits

Author SHA1 Message Date
Havoc Pennington
e8bc8e95e2 add bad hack to work with GTK 1.3.9.90 RPMs from gnomehide for now
2001-10-13  Havoc Pennington  <hp@redhat.com>

	* configure.in: add bad hack to work with GTK 1.3.9.90 RPMs from
	gnomehide for now

	* src/ui.c: another piece of bad hack in here
2001-10-13 04:15:25 +00:00
Havoc Pennington
cfd3cdd64e bump version
2001-10-13  Havoc Pennington  <hp@redhat.com>

	* configure.in: bump version
2001-10-13 04:03:56 +00:00
Havoc Pennington
ec4edcb78c hmm, fix build
2001-10-13  Havoc Pennington  <hp@pobox.com>

	* src/session.c (meta_session_init): hmm, fix build
2001-10-13 04:02:59 +00:00
Havoc Pennington
94c3b02eef makefile tweak, add a comment to frame.c 2001-10-13 04:00:08 +00:00
Havoc Pennington
f83ac8476c set the session manager priority so we start up before other apps.
2001-10-12  Havoc Pennington  <hp@pobox.com>

	* src/session.c (meta_session_init): set the session manager
	priority so we start up before other apps.
2001-10-12 04:52:53 +00:00
Mikael Hallendal
4edccc4eb5 use gdk_pixbuf_new_from_inline (meta_ui_get_default_mini_icon): use
2001-10-12  Mikael Hallendal  <micke@codefactory.se>

	* src/ui.c (meta_ui_get_default_window_icon): use
	gdk_pixbuf_new_from_inline
	(meta_ui_get_default_mini_icon): use
	gdk_pixbuf_new_from_inline
2001-10-12 00:20:02 +00:00
Christian Rose
0398a78b4a Fixed some typos. Thanks to Tomas gren <stric@ing.umu.se> for spotting
2001-10-11  Christian Rose  <menthos@menthos.com>

	* sv.po: Fixed some typos. Thanks to Tomas gren <stric@ing.umu.se>
	for spotting many of them.
2001-10-11 11:05:30 +00:00
Christian Rose
ec6a455fb0 Added "sv" to ALL_LINGUAS. Added Swedish translation. Added files. Added
2001-10-11  Christian Rose  <menthos@menthos.com>

	* configure.in: Added "sv" to ALL_LINGUAS.
	* po/sv.po: Added Swedish translation.
	* po/POTFILES.in: Added files.
	* po/.cvsignore: Added messages and *.pot.
2001-10-11 08:40:04 +00:00
Havoc Pennington
e55ead0419 fix mem leak of the MetaStack object (meta_stack_sync_to_server): try to
2001-10-10  Havoc Pennington  <hp@pobox.com>

	* src/stack.c (meta_stack_free): fix mem leak of the MetaStack
	object
	(meta_stack_sync_to_server): try to avoid the restack-flicker
	thing
2001-10-11 01:29:20 +00:00
Havoc Pennington
f22b9dfd94 set _NET_ACTIVE_WINDOW hint
2001-10-07  Havoc Pennington  <hp@pobox.com>

	* src/display.c (meta_display_update_active_window_hint):
	set _NET_ACTIVE_WINDOW hint

	* src/window.c (meta_window_client_message): support
	_NET_ACTIVE_WINDOW client message
2001-10-07 23:06:19 +00:00
Havoc Pennington
ec4dfd0cbc don't allow shade/maximize/minimize for windows that don't support those
2001-10-07  Havoc Pennington  <hp@pobox.com>

	* src/window.c (meta_window_client_message): don't allow
	shade/maximize/minimize for windows that don't support those
	operations. (minimizing the panel = bad)
2001-10-07 22:11:13 +00:00
Havoc Pennington
350ecb1dcf add code to grab all modifier combinations, so keybindings work with
2001-10-04  Havoc Pennington  <hp@pobox.com>

	* src/keybindings.c (meta_change_keygrab): add code to grab all
	modifier combinations, so keybindings work with NumLock etc.

	* src/menu.c (meta_window_menu_new): remove newlines from menu
	items

2001-09-27  Havoc Pennington  <hp@pobox.com>

	* src/session.c (save_state): when encoding text for session file,
	escape XML entities
2001-10-05 02:58:48 +00:00
Alex Graveley
38a878171a Add inlinepixbufs.h so that it gets generated.
2001-09-21  Alex Graveley  <alex@ximian.com>

	* src/Makefile.am (metacity_SOURCES): Add inlinepixbufs.h so
	that it gets generated.

	* src/frames.c (meta_frames_style_set): Update for new opaque
	PangoFontMetrics.
2001-09-21 19:20:56 +00:00
Havoc Pennington
dad1b107f5 add hackaround for the warning about gtk-menu-bar-accel
2001-09-17  Havoc Pennington  <hp@pobox.com>

	* src/ui.c (meta_ui_init): add hackaround for the warning about
	gtk-menu-bar-accel
2001-09-18 03:40:03 +00:00
Havoc Pennington
582a80f518 ref the returned icon, oops.
2001-09-17  Havoc Pennington  <hp@pobox.com>

	* src/ui.c (meta_ui_get_default_mini_icon):
	(meta_ui_get_default_window_icon): ref the returned icon, oops.

	* src/main.c (main): get the GLib warning/error output into
	the metacity logfile, set warnings to be always fatal

	* configure.in: bump version to 2.3.13

	* src/window.c (get_text_property): hrm, fix bug where we didn't
	check errors on XGetTextProperty
2001-09-17 05:50:02 +00:00
Havoc Pennington
808d21e857 tiny update 2001-09-17 04:47:36 +00:00
Havoc Pennington
0a1f2b3a47 fix srcdir != builddir glitch
2001-09-17  Havoc Pennington  <hp@pobox.com>

	* src/Makefile.am (VARIABLES): fix srcdir != builddir glitch
2001-09-17 04:45:13 +00:00
Havoc Pennington
4c104e1cb7 use the inline image data for default icon
2001-09-17  Havoc Pennington  <hp@pobox.com>

	* src/ui.c: use the inline image data for default icon

	* src/common.h (META_MINI_ICON_HEIGHT): move icon size defines
	here

	* src/Makefile.am: Create an inlinepixbufs.h header with inline
	images
2001-09-17 04:42:37 +00:00
Havoc Pennington
ecf75915c7 disconnect this callback on error
2001-09-16  Havoc Pennington  <hp@pobox.com>

	* src/session.c (process_ice_messages): disconnect this callback
	on error
2001-09-17 04:11:25 +00:00
Havoc Pennington
7be4c63ee4 new function
2001-09-16  Havoc Pennington  <hp@pobox.com>

	* src/window.c (meta_window_lower): new function

	* configure.in: bump version to 2.3.8

	* src/display.c (event_callback): raise dock on enter notify,
	lower it on leave notify (need to refine this behavior)

	* src/stack.c (compute_layer): experiment with putting the panel
	in the normal layer, and raising it on mouseover
2001-09-16 21:50:27 +00:00
Havoc Pennington
b09a781a80 remove msm from here, now in its own module 2001-09-16 20:43:45 +00:00
Havoc Pennington
52dc32031d ... 2001-09-16 03:47:05 +00:00
Havoc Pennington
a926a4a0ca ... 2001-09-16 02:52:23 +00:00
Havoc Pennington
39df21227d add support for a mini icon in the titlebar (update_icon): re-enable
2001-09-15  Havoc Pennington  <hp@pobox.com>

	* src/window.c: add support for a mini icon in the titlebar
	(update_icon): re-enable support for _NET_WM_ICON

	* src/session.c (save_state): add an ferror check when writing
	session file
2001-09-16 00:30:45 +00:00
Havoc Pennington
2830c9d748 ... 2001-09-15 02:37:02 +00:00
Havoc Pennington
3886f0ecac ... 2001-09-14 14:25:24 +00:00
Havoc Pennington
b1c7811e89 ... 2001-09-14 06:30:50 +00:00
Havoc Pennington
1385d192c5 stuff 2001-09-13 05:00:50 +00:00
Havoc Pennington
82aa7363f9 still does not work. 2001-09-13 04:50:18 +00:00
Havoc Pennington
a4346200e8 does not work. 2001-09-12 06:06:08 +00:00
Havoc Pennington
9f66f63bf5 fix up handling of text properties, so we get UTF8_STRING as that type and
2001-09-11  Havoc Pennington  <hp@pobox.com>

	* src/window.c: fix up handling of text properties, so we
	get UTF8_STRING as that type and not as text list, and so
	we properly convert from text list to UTF-8
2001-09-11 04:37:10 +00:00
Havoc Pennington
3645fef5e0 icon for unmaximize
2001-09-10  Havoc Pennington  <hp@pobox.com>

	* src/menu.c (meta_window_menu_new): icon for unmaximize

	* src/ui.c (meta_ui_init): fix call to XDisplayName

	* src/util.c: add missing header

	* src/frames.c: draw an unmaximize control if already maximized
2001-09-11 03:54:54 +00:00
Havoc Pennington
f386494ba4 Don't separate user_has_moved/user_has_resized, fixes bug in east-resizing
2001-09-10  Havoc Pennington  <hp@pobox.com>

	* src/window.c: Don't separate user_has_moved/user_has_resized,
	fixes bug in east-resizing Emacs, among other things

	* src/frame.c (meta_frame_sync_to_window): return immediately if
	nothing to do

	* src/util.c (ensure_logfile): replace rather than truncate old
	logfiles
2001-09-11 02:57:05 +00:00
Havoc Pennington
936adc6ea5 don't use gdk_display_name
2001-09-08  Havoc Pennington  <hp@pobox.com>

	* src/ui.c (meta_ui_init): don't use gdk_display_name

	* src/frame.c (meta_window_ensure_frame): create frame
	with screen default visual, rather than client window visual;
	for DRI games, the client window visual was not allowed to be
	a child of another window with the same visual, apparently.
	Anyhow now we copy twm, etc. so it must be correct.

	* src/place.c (meta_window_place): if a transient is placed and
	its parent has focus, focus the transient.
2001-09-09 03:44:42 +00:00
Havoc Pennington
bc787fc1f3 bump version 2.3.5, require newer GTK release
2001-09-06  Havoc Pennington  <hp@pobox.com>

	* configure.in: bump version 2.3.5, require newer GTK release
2001-09-06 04:40:03 +00:00
Havoc Pennington
1c6c7350e1 make test apps noinst
2001-09-04  Havoc Pennington  <hp@pobox.com>

	* src/wm-tester/Makefile.am (noinst_PROGRAMS): make test apps
	noinst

	* src/metacity.desktop: for the capplet

	* src/Makefile.am: add .desktop file
2001-09-05 03:57:45 +00:00
Havoc Pennington
2a0a5dfdf8 clean up the code, and replace GDK X error handler with one that chains up
2001-09-01  Havoc Pennington  <hp@pobox.com>

	* src/errors.c: clean up the code, and replace GDK X error handler
	with one that chains up to GDK but first logs the error to logfile.
2001-09-01 05:53:07 +00:00
34 changed files with 1672 additions and 441 deletions

193
ChangeLog
View File

@@ -1,3 +1,196 @@
2001-10-13 Havoc Pennington <hp@redhat.com>
* configure.in: add bad hack to work with GTK 1.3.9.90 RPMs from
gnomehide for now
* src/ui.c: another piece of bad hack in here
2001-10-13 Havoc Pennington <hp@redhat.com>
* configure.in: bump version
2001-10-13 Havoc Pennington <hp@pobox.com>
* src/session.c (meta_session_init): hmm, fix build
2001-10-12 Havoc Pennington <hp@pobox.com>
* src/session.c (meta_session_init): set the session manager
priority so we start up before other apps.
2001-10-12 Mikael Hallendal <micke@codefactory.se>
* src/ui.c (meta_ui_get_default_window_icon): use
gdk_pixbuf_new_from_inline
(meta_ui_get_default_mini_icon): use
gdk_pixbuf_new_from_inline
2001-10-11 Christian Rose <menthos@menthos.com>
* configure.in: Added "sv" to ALL_LINGUAS.
2001-10-10 Havoc Pennington <hp@pobox.com>
* src/stack.c (meta_stack_free): fix mem leak of the MetaStack
object
(meta_stack_sync_to_server): try to avoid the restack-flicker
thing
2001-10-07 Havoc Pennington <hp@pobox.com>
* src/display.c (meta_display_update_active_window_hint):
set _NET_ACTIVE_WINDOW hint
* src/window.c (meta_window_client_message): support
_NET_ACTIVE_WINDOW client message
2001-10-07 Havoc Pennington <hp@pobox.com>
* src/window.c (meta_window_client_message): don't allow
shade/maximize/minimize for windows that don't support those
operations. (minimizing the panel = bad)
2001-10-04 Havoc Pennington <hp@pobox.com>
* src/keybindings.c (meta_change_keygrab): add code to grab all
modifier combinations, so keybindings work with NumLock etc.
* src/menu.c (meta_window_menu_new): remove newlines from menu
items
2001-09-27 Havoc Pennington <hp@pobox.com>
* src/session.c (save_state): when encoding text for session file,
escape XML entities
2001-09-21 Alex Graveley <alex@ximian.com>
* src/Makefile.am (metacity_SOURCES): Add inlinepixbufs.h so
that it gets generated.
* src/frames.c (meta_frames_style_set): Update for new opaque
PangoFontMetrics.
2001-09-17 Havoc Pennington <hp@pobox.com>
* src/ui.c (meta_ui_init): add hackaround for the warning about
gtk-menu-bar-accel
2001-09-17 Havoc Pennington <hp@pobox.com>
* src/ui.c (meta_ui_get_default_mini_icon):
(meta_ui_get_default_window_icon): ref the returned icon, oops.
* src/main.c (main): get the GLib warning/error output into
the metacity logfile, set warnings to be always fatal
* configure.in: bump version to 2.3.13
* src/window.c (get_text_property): hrm, fix bug where we didn't
check errors on XGetTextProperty
2001-09-17 Havoc Pennington <hp@pobox.com>
* src/Makefile.am (VARIABLES): fix srcdir != builddir glitch
2001-09-17 Havoc Pennington <hp@pobox.com>
* src/ui.c: use the inline image data for default icon
* src/common.h (META_MINI_ICON_HEIGHT): move icon size defines
here
* src/Makefile.am: Create an inlinepixbufs.h header with inline
images
2001-09-16 Havoc Pennington <hp@pobox.com>
* src/session.c (process_ice_messages): disconnect this callback
on error
2001-09-16 Havoc Pennington <hp@pobox.com>
* src/window.c (meta_window_lower): new function
* configure.in: bump version to 2.3.8
* src/display.c (event_callback): raise dock on enter notify,
lower it on leave notify (need to refine this behavior)
* src/stack.c (compute_layer): experiment with putting the panel
in the normal layer, and raising it on mouseover
2001-09-15 Havoc Pennington <hp@pobox.com>
* src/window.c: add support for a mini icon in the titlebar
(update_icon): re-enable support for _NET_WM_ICON
* src/session.c (save_state): add an ferror check when writing
session file
2001-09-11 Havoc Pennington <hp@pobox.com>
* src/main.c (usage): exit with error code on usage() (kind of
wrong for --help, but oh well).
2001-09-11 Havoc Pennington <hp@pobox.com>
* src/window.c: fix up handling of text properties, so we
get UTF8_STRING as that type and not as text list, and so
we properly convert from text list to UTF-8
2001-09-10 Havoc Pennington <hp@pobox.com>
* src/menu.c (meta_window_menu_new): icon for unmaximize
* src/ui.c (meta_ui_init): fix call to XDisplayName
* src/util.c: add missing header
* src/frames.c: draw an unmaximize control if already maximized
2001-09-10 Havoc Pennington <hp@pobox.com>
* src/window.c: Don't separate user_has_moved/user_has_resized,
fixes bug in east-resizing Emacs, among other things
* src/frame.c (meta_frame_sync_to_window): return immediately if
nothing to do
* src/util.c (ensure_logfile): replace rather than truncate old
logfiles
2001-09-08 Havoc Pennington <hp@pobox.com>
* src/ui.c (meta_ui_init): don't use gdk_display_name
* src/frame.c (meta_window_ensure_frame): create frame
with screen default visual, rather than client window visual;
for DRI games, the client window visual was not allowed to be
a child of another window with the same visual, apparently.
Anyhow now we copy twm, etc. so it must be correct.
* src/place.c (meta_window_place): if a transient is placed and
its parent has focus, focus the transient.
2001-09-06 Havoc Pennington <hp@pobox.com>
* configure.in: bump version 2.3.5, require newer GTK release
2001-09-04 Havoc Pennington <hp@pobox.com>
* src/wm-tester/Makefile.am (noinst_PROGRAMS): make test apps
noinst
* src/metacity.desktop: for the capplet
* src/Makefile.am: add .desktop file
2001-09-01 Havoc Pennington <hp@pobox.com>
* src/errors.c: clean up the code, and replace GDK X error handler
with one that chains up to GDK but first logs the error to logfile.
2001-08-31 Havoc Pennington <hp@pobox.com>
* src/tabpopup.c (meta_ui_tab_popup_new): fix args to

31
README
View File

@@ -9,19 +9,24 @@ your petty hangups about version numbers.
COMPILING METACITY
===
You need GTK+ 1.3.x (to become 2.0). At the moment CVS HEAD is
required. Once 1.3.7 is available that will probably work. Metacity is
a fairly trivial 6000-line C program, so once you get GTK+ built it
should be no problem to build Metacity.
You need GTK+ 1.3.x (to become 2.0), at least version 1.3.9. At the
moment CVS HEAD works, but that can change. Metacity is a fairly
trivial 6000-line C program, so once you get GTK+ built it should be
no problem to build Metacity.
There are SRPMs and sometimes RPMs on the ftp site, but you'd be
pretty lucky to get them to work for now, since they are often out of
sync with GTK. You might try with the GTK from ftp.gtk.org, and also
the GTK from http://people.redhat.com/hp/gnomehide/.
REPORTING BUGS AND SUBMITTING PATCHES
===
Report new bugs to hp@redhat.com for now. Will switch to Bugzilla
sometime probably.
Report new bugs on http://bugzilla.gnome.org.
Feel free to send patches too; Metacity is really small and simple, so
if you find a bug or want to add a feature it should be pretty easy.
Send me mail, or put the patch in bugzilla.
See the HACKING file for some notes on hacking Metacity.
@@ -146,6 +151,8 @@ METACITY BUGS, NON-FEATURES, AND CAVEATS
clicking the minimize button is sort of a bad idea.
(If you had a WM-spec-compliant tasklist, it would work
for unminimization.)
(Update: you can use "test-wnck" from the libwnck CVS module to
unminimize, but it's not much of a UI ;-)
- Metacity uses the new window manager spec, but only random bits of
the old GNOME spec. It correctly advertises exactly which parts of
@@ -165,14 +172,7 @@ METACITY BUGS, NON-FEATURES, AND CAVEATS
instead of Alt as the main keybinding shortcut, if super/hyper
exist, and then keyboards with a windows key can use that for
WM functions and Alt for application shortcuts.
We'd fall back to Alt if no other suitable modifier existed.
- Cycling windows with Alt-Tab is flickery, AFAIK because
Metacity passes the entire window stack to XRestackWindows()
every time you restack. Instead it should probably only restack
windows that have changed their stacking with respect to one
another. (But sometimes I don't see the flicker, so
I'm not sure.)
We'd fall back to Alt if no other suitable modifier existed.
- I haven't even read the ICCCM section about colormaps. So if you
have an 8-bit display you are basically screwed.
@@ -251,9 +251,6 @@ METACITY BUGS, NON-FEATURES, AND CAVEATS
setting the new non-legacy type hint, but a panel with that
patch hasn't been released yet.
- If you run a GLX/DRI 3D game or application, Metacity will
crash, for reasons I do not yet understand.
FAQ
===

View File

@@ -2,7 +2,7 @@ AC_INIT(src/display.c)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(metacity, 2.3.3)
AM_INIT_AUTOMAKE(metacity, 2.3.21)
GETTEXT_PACKAGE=metacity
AC_SUBST(GETTEXT_PACKAGE)
@@ -37,11 +37,11 @@ if test "x$GCC" = "xyes"; then
fi
changequote([,])dnl
ALL_LINGUAS=""
ALL_LINGUAS="sv"
dnl AM_GNU_GETTEXT
## here we get the flags we'll actually use
PKG_CHECK_MODULES(METACITY, gtk+-2.0 >= 1.3.6)
PKG_CHECK_MODULES(METACITY, gtk+-2.0 >= 1.3.9)
CFLAGS="$METACITY_CFLAGS $CFLAGS"
@@ -62,16 +62,27 @@ if test "$found_sm" = "true"; then
AC_DEFINE(HAVE_SM)
fi
# Check for shaped window extension
AC_CHECK_LIB(Xext, XShapeCombineMask, AC_DEFINE(HAVE_SHAPE_EXT),,$METACITY_LIBS)
AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "true")
HOST_ALIAS=$host_alias
AC_SUBST(HOST_ALIAS)
AC_PATH_PROG(GDK_PIXBUF_CSOURCE, gdk-pixbuf-csource, no)
if test x"$GDK_PIXBUF_CSOURCE" = xno; then
AC_MSG_ERROR([gdk-pixbuf-csource executable not found in your path - should be installed with GTK])
fi
AC_SUBST(GDK_PIXBUF_CSOURCE)
## hack to work with old GTK versions for now
save_LDFLAGS=$LDFLAGS
LDFLAGS="$METACITY_LIBS $LDFLAGS"
AC_CHECK_FUNCS(gdk_pixbuf_new_from_stream)
LDFLAGS=$save_LDFLAGS
AC_OUTPUT([
Makefile
src/Makefile
src/wm-tester/Makefile
])

View File

@@ -4,3 +4,5 @@ Makefile.in
Makefile
stamp-cat-id
cat-id-tbl.c
messages
*.pot

11
po/ChangeLog Normal file
View File

@@ -0,0 +1,11 @@
2001-10-11 Christian Rose <menthos@menthos.com>
* sv.po: Fixed some typos. Thanks to Tomas <20>gren <stric@ing.umu.se>
for spotting many of them.
2001-10-11 Christian Rose <menthos@menthos.com>
* sv.po: Added Swedish translation.
* POTFILES.in: Added files.
* .cvsignore: Added messages and *.pot.

View File

@@ -0,0 +1,8 @@
src/display.c
src/errors.c
src/frames.c
src/keybindings.c
src/menu.c
src/screen.c
src/session.c
src/window.c

306
po/sv.po Normal file
View File

@@ -0,0 +1,306 @@
# Swedish messages for metacity.
# Copyright (C) 2001 Free Software Foundation, Inc.
# Christian Rose <menthos@menthos.com>, 2001.
#
# $Id$
#
msgid ""
msgstr ""
"Project-Id-Version: metacity\n"
"POT-Creation-Date: 2001-10-11 12:59+0200\n"
"PO-Revision-Date: 2001-10-11 13:04+0200\n"
"Last-Translator: Christian Rose <menthos@menthos.com>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/display.c:153
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Misslyckades med att <20>ppna X Window System-displayen \"%s\"\n"
#: src/errors.c:92
#, c-format
msgid ""
"Lost connection to the display '%s';\n"
"most likely the X server was shut down or you killed/destroyed\n"
"the window manager.\n"
msgstr ""
"Tappade anslutningen till displayen \"%s\";\n"
"troligtvis st<73>ngdes X-servern ner, eller s<> d<>dade/f<>rst<73>rde du\n"
"f<>nsterhanteraren.\n"
#: src/errors.c:99
#, c-format
msgid "Fatal IO error %d (%s) on display '%s'.\n"
msgstr "<22>desdigert IO-fel %d (%s) p<> display \"%s\".\n"
#: src/frames.c:229
msgid "Left edge"
msgstr "V<>nsterkant"
#: src/frames.c:229
msgid "Left window edge width"
msgstr "Bredd p<> v<>nster f<>nsterkant"
#: src/frames.c:230
msgid "Right edge"
msgstr "H<>gerkant"
#: src/frames.c:230
msgid "Right window edge width"
msgstr "Bredd p<> h<>ger f<>nsterkant"
#: src/frames.c:231
msgid "Bottom edge"
msgstr "Nederkant"
#: src/frames.c:231
msgid "Bottom window edge height"
msgstr "H<>jd p<> nedre f<>nsterkant"
#: src/frames.c:233
msgid "Title border"
msgstr "Titelkant"
#: src/frames.c:233
msgid "Border around title area"
msgstr "Ram runt titelomr<6D>det"
#: src/frames.c:234
msgid "Text border"
msgstr "Textram"
#: src/frames.c:234
msgid "Border around window title text"
msgstr "Ram runt f<>nstertiteln"
#: src/frames.c:236
msgid "Spacer padding"
msgstr "Utfyllnadsmellanrum"
#: src/frames.c:236
msgid "Padding on either side of spacer"
msgstr "Utfyllnad p<> varje sida om utfyllare"
#: src/frames.c:237
msgid "Spacer width"
msgstr "Utfyllnadsbredd"
#: src/frames.c:237
msgid "Width of spacer"
msgstr "Bredd p<> utfyllnad"
#: src/frames.c:238
msgid "Spacer height"
msgstr "Utfyllnadsh<73>jd"
#: src/frames.c:238
msgid "Height of spacer"
msgstr "H<>jd p<> utfyllnad"
#. same as right_width left_width by default
#: src/frames.c:241
msgid "Right inset"
msgstr "H<>ger inf<6E>llning"
#: src/frames.c:241
msgid "Distance of buttons from right edge of frame"
msgstr "Avst<73>nd p<> knappar fr<66>n h<>gerkanten p<> ramen"
#: src/frames.c:242
msgid "Left inset"
msgstr "V<>nster inf<6E>llning"
#: src/frames.c:242
msgid "Distance of menu button from left edge of frame"
msgstr "Avst<73>nd p<> menyknapp fr<66>n v<>nsterkanten p<> ramen"
#: src/frames.c:244
msgid "Button width"
msgstr "Knappbredd"
#: src/frames.c:244
msgid "Width of buttons"
msgstr "Bredd p<> knappar"
#: src/frames.c:245
msgid "Button height"
msgstr "Knapph<70>jd"
#: src/frames.c:245
msgid "Height of buttons"
msgstr "H<>jd p<> knappar"
#: src/frames.c:247
msgid "Button border"
msgstr "Knappram"
#: src/frames.c:247
msgid "Border around buttons"
msgstr "Ram runt knappar"
#: src/frames.c:248
msgid "Inner button border"
msgstr "Inre knappram"
#: src/frames.c:248
msgid "Border around the icon inside buttons"
msgstr "Ram runt ikonen inuti knappar"
#: src/frames.c:883
msgid "Close Window"
msgstr "St<53>ng f<>nster"
#: src/frames.c:886
msgid "Window Menu"
msgstr "F<>nstermeny"
#: src/frames.c:889
msgid "Minimize Window"
msgstr "Minimera f<>nster"
#: src/frames.c:892
msgid "Maximize Window"
msgstr "Maximera f<>nster"
#: src/frames.c:895
msgid "Unmaximize Window"
msgstr "Avmaximera f<>nster"
#: src/keybindings.c:203
#, c-format
msgid ""
"Some other program is already using the key %s with modifiers %x as a "
"binding\n"
msgstr ""
"Ett annat program anv<6E>nder redan tangenten %s med modifierarna %x som en "
"bindning\n"
#: src/menu.c:47
msgid "_Close"
msgstr "_St<53>ng"
#: src/menu.c:48
msgid "_Minimize"
msgstr "_Minimera"
#: src/menu.c:49
msgid "Ma_ximize"
msgstr "Ma_ximera"
#: src/menu.c:50
msgid "_Unmaximize"
msgstr "_Avmaximera"
#: src/menu.c:51
msgid "_Shade"
msgstr "_Skugga"
#: src/menu.c:52
msgid "U_nshade"
msgstr "A_vskugga"
#: src/menu.c:53
msgid "Mo_ve"
msgstr "Fl_ytta"
#: src/menu.c:54
msgid "_Resize"
msgstr "_<>ndra storlek"
#. separator
#: src/menu.c:56
msgid "Put on _All Workspaces"
msgstr "Placera p<> _alla arbetsytor"
#: src/menu.c:57
msgid "Only on _This Workspace"
msgstr "Endast p<> _denna arbetsyta"
#: src/menu.c:260
#, c-format
msgid "Only on workspace _%d"
msgstr "Endast p<> arbetsyta _%d"
#: src/menu.c:263
#, c-format
msgid "Move to workspace _%d"
msgstr "Flytta till arbetsyta _%d"
#: src/screen.c:168
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Sk<53>rm %d p<> display \"%s\" <20>r ogiltig\n"
#: src/screen.c:183
#, c-format
msgid "Screen %d on display '%s' already has a window manager\n"
msgstr "Sk<53>rm %d p<> display \"%s\" har redan en f<>nsterhanterare\n"
#: src/session.c:742 src/session.c:749
#, c-format
msgid "Could not create directory '%s': %s\n"
msgstr "Kunde inte skapa katalogen \"%s\": %s\n"
#: src/session.c:759
#, c-format
msgid "Could not open session file '%s' for writing: %s\n"
msgstr "Kunde inte <20>ppna sessionsfilen \"%s\" f<>r skrivning: %s\n"
#: src/session.c:891
#, c-format
msgid "Error writing session file '%s': %s\n"
msgstr "Fel vid skrivning av sessionsfilen \"%s\": %s\n"
#: src/session.c:896
#, c-format
msgid "Error closing session file '%s': %s\n"
msgstr "Fel vid st<73>ngning av sessionsfilen \"%s\": %s\n"
#: src/session.c:970
#, c-format
msgid "Failed to read saved session file %s: %s\n"
msgstr "Misslyckades med att l<>sa sparad sessionsfil %s: %s\n"
#: src/session.c:1004
#, c-format
msgid "Failed to parse saved session file: %s\n"
msgstr "Misslyckades med att tolka sparad sessionsfil: %s\n"
#: src/session.c:1042
msgid "nested <window> tag"
msgstr "n<>stlad <window>-tagg"
#: src/session.c:1092 src/session.c:1124
#, c-format
msgid "Unknown attribute %s on <window> element"
msgstr "Ok<4F>nt attribut %s p<> <window>-element"
#: src/session.c:1184
#, c-format
msgid "Unknown attribute %s on <geometry> element"
msgstr "Ok<4F>nt attribut %s p<> <geometry>-element"
#: src/session.c:1204
#, c-format
msgid "Unknown element %s"
msgstr "Ok<4F>nt element %s"
#. someone is on crack
#: src/window.c:2852
#, c-format
msgid "Window %s sets max width %d less than min width %d, disabling resize\n"
msgstr ""
"F<>nstret %s st<73>ller in st<73>rsta bredden %d mindre <20>n minsta bredden %d, "
"st<73>nger av storleks<6B>ndring\n"
#. another cracksmoker
#: src/window.c:2862
#, c-format
msgid ""
"Window %s sets max height %d less than min height %d, disabling resize\n"
msgstr ""
"F<>nstret %s st<73>ller in st<73>rsta h<>jden %d mindre <20>n minsta h<>jden %d, st<73>nger "
"av storleks<6B>ndring\n"

View File

@@ -21,6 +21,7 @@ metacity_SOURCES= \
frame.h \
frames.c \
frames.h \
inlinepixbufs.h \
keybindings.c \
keybindings.h \
main.c \
@@ -49,3 +50,17 @@ metacity_SOURCES= \
bin_PROGRAMS=metacity
metacity_LDADD= @METACITY_LIBS@
desktopfilesdir=$(datadir)/gnome/wm-properties
desktopfiles_DATA=metacity.desktop
IMAGES=default_icon.png
VARIABLES=default_icon_data $(srcdir)/default_icon.png
BUILT_SOURCES = inlinepixbufs.h
CLEANFILES += inlinepixbufs.h
inlinepixbufs.h: $(IMAGES)
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
EXTRA_DIST=$(desktopfiles_DATA) $(IMAGES)

View File

@@ -31,7 +31,7 @@ typedef enum
META_FRAME_ALLOWS_DELETE = 1 << 0,
META_FRAME_ALLOWS_MENU = 1 << 1,
META_FRAME_ALLOWS_MINIMIZE = 1 << 2,
META_FRAME_ALLOWS_MAXIMIZE = 1 << 3,
META_FRAME_ALLOWS_MAXIMIZE = 1 << 3,
META_FRAME_ALLOWS_VERTICAL_RESIZE = 1 << 4,
META_FRAME_ALLOWS_HORIZONTAL_RESIZE = 1 << 5,
META_FRAME_TRANSIENT = 1 << 6,
@@ -102,6 +102,7 @@ typedef enum
/* Frame button ops */
META_GRAB_OP_CLICKING_MINIMIZE,
META_GRAB_OP_CLICKING_MAXIMIZE,
META_GRAB_OP_CLICKING_UNMAXIMIZE,
META_GRAB_OP_CLICKING_DELETE,
META_GRAB_OP_CLICKING_MENU
} MetaGrabOp;
@@ -121,6 +122,13 @@ typedef enum
} MetaCursor;
/* should investigate changing these to whatever most apps use */
#define META_ICON_WIDTH 32
#define META_ICON_HEIGHT 32
#define META_MINI_ICON_WIDTH 16
#define META_MINI_ICON_HEIGHT 16
#endif

View File

@@ -60,6 +60,22 @@ meta_core_get_frame_flags (Display *xdisplay,
return meta_frame_get_flags (window->frame);
}
GdkPixbuf*
meta_core_get_mini_icon (Display *xdisplay,
Window frame_xwindow)
{
MetaDisplay *display;
MetaWindow *window;
display = meta_display_for_x_display (xdisplay);
window = meta_display_lookup_x_window (display, frame_xwindow);
if (window == NULL || window->frame == NULL)
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
return window->mini_icon;
}
void
meta_core_queue_frame_resize (Display *xdisplay,
Window frame_xwindow)

View File

@@ -36,6 +36,9 @@ void meta_core_get_frame_size (Display *xdisplay,
MetaFrameFlags meta_core_get_frame_flags (Display *xdisplay,
Window frame_xwindow);
GdkPixbuf* meta_core_get_mini_icon (Display *xdisplay,
Window frame_xwindow);
void meta_core_queue_frame_resize (Display *xdisplay,
Window frame_xwindow);

BIN
src/default_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

View File

@@ -135,7 +135,8 @@ meta_display_open (const char *name)
"UTF8_STRING",
"WM_ICON_SIZE",
"_KWM_WIN_ICON",
"_NET_WM_MOVERESIZE"
"_NET_WM_MOVERESIZE",
"_NET_ACTIVE_WINDOW"
};
Atom atoms[G_N_ELEMENTS(atom_names)];
@@ -222,6 +223,7 @@ meta_display_open (const char *name)
display->atom_wm_icon_size = atoms[40];
display->atom_kwm_win_icon = atoms[41];
display->atom_net_wm_moveresize = atoms[42];
display->atom_net_active_window = atoms[43];
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
* created in screen_new
@@ -741,9 +743,18 @@ event_callback (XEvent *event,
case EnterNotify:
/* do this even if window->has_focus to avoid races */
if (window && event->xany.serial != display->last_ignored_unmap_serial)
meta_window_focus (window, event->xcrossing.time);
{
meta_window_focus (window, event->xcrossing.time);
if (window->type == META_WINDOW_DOCK)
meta_window_raise (window);
}
break;
case LeaveNotify:
if (window)
{
if (window->type == META_WINDOW_DOCK)
meta_window_lower (window);
}
break;
case FocusIn:
case FocusOut:
@@ -896,27 +907,29 @@ event_callback (XEvent *event,
screen = meta_display_screen_for_root (display,
event->xclient.window);
if (screen &&
event->xclient.message_type ==
display->atom_net_current_desktop)
if (screen)
{
int space;
MetaWorkspace *workspace;
if (event->xclient.message_type ==
display->atom_net_current_desktop)
{
int space;
MetaWorkspace *workspace;
space = event->xclient.data.l[0];
space = event->xclient.data.l[0];
meta_verbose ("Request to change current workspace to %d\n",
space);
meta_verbose ("Request to change current workspace to %d\n",
space);
workspace =
meta_display_get_workspace_by_screen_index (display,
screen,
space);
workspace =
meta_display_get_workspace_by_screen_index (display,
screen,
space);
if (workspace)
meta_workspace_activate (workspace);
else
meta_verbose ("Don't know about workspace %d\n", space);
if (workspace)
meta_workspace_activate (workspace);
else
meta_verbose ("Don't know about workspace %d\n", space);
}
}
}
break;
@@ -1526,7 +1539,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_button = button;
display->grab_root_x = root_x;
display->grab_root_y = root_y;
display->grab_initial_window_pos = window->rect;
display->grab_initial_window_pos = display->grab_window->rect;
meta_window_get_position (display->grab_window,
&display->grab_initial_window_pos.x,
&display->grab_initial_window_pos.y);
@@ -1665,3 +1678,32 @@ meta_display_increment_event_serial (MetaDisplay *display)
XDeleteProperty (display->xdisplay, display->leader_window,
display->atom_motif_wm_hints);
}
void
meta_display_update_active_window_hint (MetaDisplay *display)
{
GSList *tmp;
unsigned long data[2];
if (display->focus_window)
data[0] = display->focus_window->xwindow;
else
data[0] = None;
data[1] = None;
tmp = display->screens;
while (tmp != NULL)
{
MetaScreen *screen = tmp->data;
meta_error_trap_push (display);
XChangeProperty (display->xdisplay, screen->xroot,
display->atom_net_active_window,
XA_WINDOW,
32, PropModeReplace, (guchar*) data, 2);
meta_error_trap_pop (display);
tmp = tmp->next;
}
}

View File

@@ -100,6 +100,7 @@ struct _MetaDisplay
Atom atom_wm_icon_size;
Atom atom_kwm_win_icon;
Atom atom_net_wm_moveresize;
Atom atom_net_active_window;
/* This is the actual window from focus events,
* not the one we last set
@@ -194,4 +195,6 @@ void meta_display_ungrab_window_buttons (MetaDisplay *display,
/* make a request to ensure the event serial has changed */
void meta_display_increment_event_serial (MetaDisplay *display);
void meta_display_update_active_window_hint (MetaDisplay *display);
#endif

View File

@@ -22,14 +22,13 @@
#include "errors.h"
#include <errno.h>
#include <stdlib.h>
#include <gdk/gdk.h>
typedef struct _ErrorTrap ErrorTrap;
static int (* saved_gdk_error_handler) (Display *display,
XErrorEvent *error);
struct _ErrorTrap
{
int error_code;
};
static int (* saved_gdk_io_error_handler) (Display *display);
static int x_error_handler (Display *display,
XErrorEvent *error);
@@ -38,104 +37,44 @@ static int x_io_error_handler (Display *display);
void
meta_errors_init (void)
{
XSetErrorHandler (x_error_handler);
XSetIOErrorHandler (x_io_error_handler);
saved_gdk_error_handler = XSetErrorHandler (x_error_handler);
saved_gdk_io_error_handler = XSetIOErrorHandler (x_io_error_handler);
}
void
meta_error_trap_push (MetaDisplay *display)
{
ErrorTrap *et;
gdk_error_trap_push ();
return;
/* below here is old method */
et = g_new (ErrorTrap, 1);
et->error_code = Success;
display->error_traps = g_slist_prepend (display->error_traps, et);
}
int
meta_error_trap_pop (MetaDisplay *display)
{
int result;
ErrorTrap *et;
GSList *next;
/* just use GDK trap */
XSync (display->xdisplay, False);
return gdk_error_trap_pop ();
/* below here is old method */
if (display->error_traps == NULL)
meta_bug ("No error trap to pop\n");
XSync (display->xdisplay, False);
et = display->error_traps->data;
result = et->error_code;
next = display->error_traps->next;
g_slist_free_1 (display->error_traps);
display->error_traps = next;
g_free (et);
if (result != Success)
{
gchar buf[64];
XGetErrorText (display->xdisplay, result, buf, 63);
meta_verbose ("Popping error code %d (%s)\n",
result, buf);
}
return result;
}
static int
x_error_handler (Display *xdisplay,
XErrorEvent *error)
{
if (error->error_code)
{
MetaDisplay *display;
display = meta_display_for_x_display (xdisplay);
if (display == NULL)
meta_bug ("Error received for unknown display?\n");
if (display->error_traps == NULL)
{
gchar buf[64];
XGetErrorText (xdisplay, error->error_code, buf, 63);
meta_bug ("Received an X Window System error without handling it.\n"
"The error was '%s'.\n"
" (Details: serial %ld error_code %d request_code %d minor_code %d)\n",
buf,
error->serial,
error->error_code,
error->request_code,
error->minor_code);
}
else
{
ErrorTrap *et;
et = display->error_traps->data;
et->error_code = error->error_code;
}
}
int retval;
gchar buf[64];
return 0;
XGetErrorText (xdisplay, error->error_code, buf, 63);
meta_verbose ("X error: %s serial %ld error_code %d request_code %d minor_code %d)\n",
buf,
error->serial,
error->error_code,
error->request_code,
error->minor_code);
retval = saved_gdk_error_handler (xdisplay, error);
return retval;
}
static int
@@ -162,11 +101,8 @@ x_io_error_handler (Display *xdisplay)
display->name);
}
meta_display_close (display);
/* Xlib would force an exit anyhow */
exit (1);
/* I believe Xlib will force an exit after we return, which
* seems sort of broken to me, but if true we should probably just
* exit for ourselves. But for now I'm not doing it.
*/
return 0;
}

View File

@@ -56,6 +56,19 @@ meta_window_ensure_frame (MetaWindow *window)
frame->mapped = FALSE;
attrs.event_mask = EVENT_MASK;
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
window->desc,
XVisualIDFromVisual (window->xvisual) ==
XVisualIDFromVisual (window->screen->default_xvisual) ?
"is" : "is not",
window->depth, window->screen->default_depth);
/* Default depth/visual handles clients with weird visuals; they can
* always be children of the root depth/visual obviously, but
* e.g. DRI games can't be children of a parent that has the same
* visual as the client.
*/
frame->xwindow = XCreateWindow (window->display->xdisplay,
window->screen->xroot,
@@ -64,9 +77,9 @@ meta_window_ensure_frame (MetaWindow *window)
frame->rect.width,
frame->rect.height,
0,
window->depth,
InputOutput,
window->xvisual,
window->screen->default_depth,
CopyFromParent,
window->screen->default_xvisual,
CWEventMask,
&attrs);
@@ -90,15 +103,18 @@ meta_window_ensure_frame (MetaWindow *window)
* we don't want to take that as a withdraw
*/
window->unmaps_pending += 1;
/* window was reparented to this position */
window->rect.x = 0;
window->rect.y = 0;
XReparentWindow (window->display->xdisplay,
window->xwindow,
frame->xwindow,
window->rect.x,
window->rect.y);
/* FIXME handle this error */
meta_error_trap_pop (window->display);
/* stick frame to the window */
window->frame = frame;
@@ -245,6 +261,9 @@ meta_frame_sync_to_window (MetaFrame *frame,
gboolean need_move,
gboolean need_resize)
{
if (!(need_move || need_resize))
return;
meta_verbose ("Syncing frame geometry %d,%d %dx%d (SE: %d,%d)\n",
frame->rect.x, frame->rect.y,
frame->rect.width, frame->rect.height,

View File

@@ -241,8 +241,8 @@ meta_frames_class_init (MetaFramesClass *class)
INT_PROPERTY ("right_inset", 6, _("Right inset"), _("Distance of buttons from right edge of frame"));
INT_PROPERTY ("left_inset", 6, _("Left inset"), _("Distance of menu button from left edge of frame"));
INT_PROPERTY ("button_width", 15, _("Button width"), _("Width of buttons"));
INT_PROPERTY ("button_height", 15, _("Button height"), _("Height of buttons"));
INT_PROPERTY ("button_width", 17, _("Button width"), _("Width of buttons"));
INT_PROPERTY ("button_height", 17, _("Button height"), _("Height of buttons"));
BORDER_PROPERTY ("button_border", _("Button border"), _("Border around buttons"));
BORDER_PROPERTY ("inner_button_border", _("Inner button border"), _("Border around the icon inside buttons"));
@@ -381,7 +381,7 @@ meta_frames_style_set (GtkWidget *widget,
/* left, right, top, bottom */
static GtkBorder default_title_border = { 3, 4, 4, 3 };
static GtkBorder default_text_border = { 2, 2, 2, 2 };
static GtkBorder default_button_border = { 1, 1, 1, 1 };
static GtkBorder default_button_border = { 0, 0, 1, 1 };
static GtkBorder default_inner_button_border = {
DEFAULT_INNER_BUTTON_BORDER,
DEFAULT_INNER_BUTTON_BORDER,
@@ -458,18 +458,22 @@ meta_frames_style_set (GtkWidget *widget,
*(frames->props) = props;
{
PangoFontMetrics metrics;
PangoFontMetrics *metrics;
PangoFont *font;
PangoLanguage *lang;
font = pango_context_load_font (gtk_widget_get_pango_context (widget),
widget->style->font_desc);
lang = pango_context_get_language (gtk_widget_get_pango_context (widget));
pango_font_get_metrics (font, lang, &metrics);
metrics = pango_font_get_metrics (font, lang);
g_object_unref (G_OBJECT (font));
frames->text_height = PANGO_PIXELS (metrics.ascent + metrics.descent);
frames->text_height =
PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
pango_font_metrics_get_descent (metrics));
pango_font_metrics_unref (metrics);
}
/* Queue a draw/resize on all frames */
@@ -887,6 +891,9 @@ show_tip_now (MetaFrames *frames)
case META_FRAME_CONTROL_MAXIMIZE:
tiptext = _("Maximize Window");
break;
case META_FRAME_CONTROL_UNMAXIMIZE:
tiptext = _("Unmaximize Window");
break;
case META_FRAME_CONTROL_RESIZE_SE:
break;
case META_FRAME_CONTROL_RESIZE_S:
@@ -1038,6 +1045,7 @@ meta_frames_button_press_event (GtkWidget *widget,
if (event->button == 1 &&
(control == META_FRAME_CONTROL_MAXIMIZE ||
control == META_FRAME_CONTROL_UNMAXIMIZE ||
control == META_FRAME_CONTROL_MINIMIZE ||
control == META_FRAME_CONTROL_DELETE ||
control == META_FRAME_CONTROL_MENU))
@@ -1052,6 +1060,9 @@ meta_frames_button_press_event (GtkWidget *widget,
case META_FRAME_CONTROL_MAXIMIZE:
op = META_GRAB_OP_CLICKING_MAXIMIZE;
break;
case META_FRAME_CONTROL_UNMAXIMIZE:
op = META_GRAB_OP_CLICKING_UNMAXIMIZE;
break;
case META_FRAME_CONTROL_DELETE:
op = META_GRAB_OP_CLICKING_DELETE;
break;
@@ -1261,18 +1272,24 @@ meta_frames_button_release_event (GtkWidget *widget,
if (point_in_control (frames, frame,
META_FRAME_CONTROL_MAXIMIZE,
event->x, event->y))
{
if (meta_core_get_frame_flags (gdk_display, frame->xwindow) &
META_FRAME_MAXIMIZED)
meta_core_unmaximize (gdk_display, frame->xwindow);
else
meta_core_maximize (gdk_display, frame->xwindow);
}
meta_core_maximize (gdk_display, frame->xwindow);
redraw_control (frames, frame,
META_FRAME_CONTROL_MAXIMIZE);
end_grab = TRUE;
break;
case META_GRAB_OP_CLICKING_UNMAXIMIZE:
if (point_in_control (frames, frame,
META_FRAME_CONTROL_UNMAXIMIZE,
event->x, event->y))
meta_core_unmaximize (gdk_display, frame->xwindow);
redraw_control (frames, frame,
META_FRAME_CONTROL_MAXIMIZE);
end_grab = TRUE;
break;
case META_GRAB_OP_CLICKING_DELETE:
if (point_in_control (frames, frame,
META_FRAME_CONTROL_DELETE,
@@ -1323,6 +1340,7 @@ meta_frames_motion_notify_event (GtkWidget *widget,
case META_GRAB_OP_CLICKING_DELETE:
case META_GRAB_OP_CLICKING_MINIMIZE:
case META_GRAB_OP_CLICKING_MAXIMIZE:
case META_GRAB_OP_CLICKING_UNMAXIMIZE:
break;
case META_GRAB_OP_NONE:
@@ -1351,6 +1369,8 @@ meta_frames_motion_notify_event (GtkWidget *widget,
break;
case META_FRAME_CONTROL_MAXIMIZE:
break;
case META_FRAME_CONTROL_UNMAXIMIZE:
break;
case META_FRAME_CONTROL_RESIZE_SE:
cursor = META_CURSOR_SE_RESIZE;
break;
@@ -1409,75 +1429,112 @@ meta_frames_destroy_event (GtkWidget *widget,
return TRUE;
}
#define THICK_LINE_WIDTH 3
static void
draw_mini_window (MetaFrames *frames,
GdkDrawable *drawable,
GdkGC *fg_gc,
GdkGC *bg_gc,
gboolean thin_title,
int x, int y, int width, int height)
{
GdkGCValues vals;
gdk_draw_rectangle (drawable,
bg_gc,
TRUE,
x, y, width - 1, height - 1);
gdk_draw_rectangle (drawable,
fg_gc,
FALSE,
x, y, width - 1, height - 1);
vals.line_width = thin_title ? THICK_LINE_WIDTH - 1 : THICK_LINE_WIDTH;
gdk_gc_set_values (fg_gc,
&vals,
GDK_GC_LINE_WIDTH);
gdk_draw_line (drawable,
fg_gc,
x, y + 1, x + width, y + 1);
vals.line_width = 0;
gdk_gc_set_values (fg_gc,
&vals,
GDK_GC_LINE_WIDTH);
}
static void
draw_control (MetaFrames *frames,
GdkDrawable *drawable,
GdkGC *override,
GdkGC *fg_override,
GdkGC *bg_override,
MetaFrameControl control,
int x, int y, int width, int height)
{
GtkWidget *widget;
GdkGCValues vals;
GdkGC *gc;
GdkGC *fg_gc;
GdkGC *bg_gc;
widget = GTK_WIDGET (frames);
#define THICK_LINE_WIDTH 3
gc = override ? override : widget->style->fg_gc[GTK_STATE_NORMAL];
fg_gc = fg_override ? fg_override : widget->style->fg_gc[GTK_STATE_NORMAL];
bg_gc = bg_override ? bg_override : widget->style->bg_gc[GTK_STATE_NORMAL];
switch (control)
{
case META_FRAME_CONTROL_DELETE:
{
gdk_draw_line (drawable,
gc,
fg_gc,
x, y, x + width - 1, y + height - 1);
gdk_draw_line (drawable,
gc,
fg_gc,
x, y + height - 1, x + width - 1, y);
}
break;
case META_FRAME_CONTROL_MAXIMIZE:
{
gdk_draw_rectangle (drawable,
gc,
FALSE,
x, y, width - 1, height - 1);
vals.line_width = THICK_LINE_WIDTH;
gdk_gc_set_values (gc,
&vals,
GDK_GC_LINE_WIDTH);
gdk_draw_line (drawable,
gc,
x, y + 1, x + width, y + 1);
vals.line_width = 0;
gdk_gc_set_values (gc,
&vals,
GDK_GC_LINE_WIDTH);
draw_mini_window (frames, drawable, fg_gc, bg_gc, FALSE,
x, y, width, height);
}
break;
case META_FRAME_CONTROL_UNMAXIMIZE:
{
int w_delta = width * 0.3;
int h_delta = height * 0.3;
w_delta = MAX (w_delta, 3);
h_delta = MAX (h_delta, 3);
draw_mini_window (frames, drawable, fg_gc, bg_gc, TRUE,
x, y, width - w_delta, height - h_delta);
draw_mini_window (frames, drawable, fg_gc, bg_gc, TRUE,
x + w_delta, y + h_delta,
width - w_delta, height - h_delta);
}
break;
case META_FRAME_CONTROL_MINIMIZE:
{
vals.line_width = THICK_LINE_WIDTH;
gdk_gc_set_values (gc,
gdk_gc_set_values (fg_gc,
&vals,
GDK_GC_LINE_WIDTH);
gdk_draw_line (drawable,
gc,
fg_gc,
x, y + height - THICK_LINE_WIDTH + 1,
x + width, y + height - THICK_LINE_WIDTH + 1);
vals.line_width = 0;
gdk_gc_set_values (gc,
gdk_gc_set_values (fg_gc,
&vals,
GDK_GC_LINE_WIDTH);
}
@@ -1486,8 +1543,8 @@ draw_control (MetaFrames *frames,
default:
break;
}
#undef THICK_LINE_WIDTH
}
#undef THICK_LINE_WIDTH
void
meta_frames_get_pixmap_for_control (MetaFrames *frames,
@@ -1499,7 +1556,7 @@ meta_frames_get_pixmap_for_control (MetaFrames *frames,
GdkPixmap *pix;
GdkBitmap *mask;
GtkWidget *widget;
GdkGC *mgc;
GdkGC *mgc, *mgc_bg;
GdkColor color;
widget = GTK_WIDGET (frames);
@@ -1519,18 +1576,21 @@ meta_frames_get_pixmap_for_control (MetaFrames *frames,
mask = gdk_pixmap_new (NULL, w, h, 1);
mgc = gdk_gc_new (mask);
mgc_bg = gdk_gc_new (mask);
color.pixel = 0;
gdk_gc_set_foreground (mgc, &color);
gdk_draw_rectangle (mask, mgc, TRUE, 0, 0, -1, -1);
gdk_gc_set_foreground (mgc_bg, &color);
color.pixel = 1;
gdk_gc_set_foreground (mgc, &color);
draw_control (frames, mask, mgc, control, 0, 0, w, h);
gdk_draw_rectangle (mask, mgc_bg, TRUE, 0, 0, -1, -1);
draw_control (frames, mask, mgc, mgc_bg, control, 0, 0, w, h);
gdk_gc_unref (mgc);
gdk_gc_unref (mgc_bg);
draw_control (frames, pix, NULL, control, 0, 0, w, h);
draw_control (frames, pix, NULL, NULL, control, 0, 0, w, h);
*pixmapp = pix;
*maskp = mask;
@@ -1563,7 +1623,10 @@ draw_control_bg (MetaFrames *frames,
break;
case META_GRAB_OP_CLICKING_MAXIMIZE:
draw = control == META_FRAME_CONTROL_MAXIMIZE;
break;
break;
case META_GRAB_OP_CLICKING_UNMAXIMIZE:
draw = control == META_FRAME_CONTROL_UNMAXIMIZE;
break;
case META_GRAB_OP_CLICKING_MINIMIZE:
draw = control == META_FRAME_CONTROL_MINIMIZE;
break;
@@ -1681,11 +1744,78 @@ meta_frames_expose_event (GtkWidget *widget,
if (frame->layout)
{
PangoRectangle layout_rect;
int x, y, icon_x, icon_y;
GdkPixbuf *icon;
int icon_w, icon_h;
int area_w, area_h;
#define ICON_TEXT_SPACING 2
icon = meta_core_get_mini_icon (gdk_display,
frame->xwindow);
icon_w = gdk_pixbuf_get_width (icon);
icon_h = gdk_pixbuf_get_height (icon);
pango_layout_get_pixel_extents (frame->layout,
NULL,
&layout_rect);
/* corner of whole title area */
x = fgeom.title_rect.x + frames->props->text_border.left;
y = fgeom.title_rect.y + frames->props->text_border.top;
area_w = fgeom.title_rect.width -
frames->props->text_border.left -
frames->props->text_border.right;
area_h = fgeom.title_rect.height -
frames->props->text_border.top -
frames->props->text_border.bottom;
/* center icon vertically */
icon_y = y + MAX ((area_h - icon_h) / 2, 0);
/* center text vertically */
y = y + MAX ((area_h - layout_rect.height) / 2, 0);
/* Center icon + text combo */
icon_x = x + MAX ((area_w - layout_rect.width - icon_w - ICON_TEXT_SPACING) / 2, 0);
x = icon_x + icon_w + ICON_TEXT_SPACING;
gdk_gc_set_clip_rectangle (layout_gc, &clip);
{
/* grumble, render_to_drawable_alpha does not accept a clip
* mask, so we have to go through some BS
*/
GdkRectangle pixbuf_rect;
GdkRectangle draw_rect;
pixbuf_rect.x = icon_x;
pixbuf_rect.y = icon_y;
pixbuf_rect.width = icon_w;
pixbuf_rect.height = icon_h;
if (gdk_rectangle_intersect (&clip, &pixbuf_rect, &draw_rect))
{
gdk_pixbuf_render_to_drawable_alpha (icon,
frame->window,
draw_rect.x - pixbuf_rect.x,
draw_rect.y - pixbuf_rect.y,
draw_rect.x, draw_rect.y,
draw_rect.width,
draw_rect.height,
GDK_PIXBUF_ALPHA_FULL,
128,
GDK_RGB_DITHER_NORMAL,
0, 0);
}
}
gdk_draw_layout (frame->window,
layout_gc,
fgeom.title_rect.x + frames->props->text_border.left,
fgeom.title_rect.y + frames->props->text_border.top,
x, y,
frame->layout);
gdk_gc_set_clip_rectangle (layout_gc, NULL);
}
@@ -1698,7 +1828,7 @@ meta_frames_expose_event (GtkWidget *widget,
draw_control_bg (frames, frame, META_FRAME_CONTROL_DELETE, &fgeom);
draw_control (frames, frame->window,
NULL,
NULL, NULL,
META_FRAME_CONTROL_DELETE,
fgeom.close_rect.x + inner.left,
fgeom.close_rect.y + inner.top,
@@ -1708,11 +1838,18 @@ meta_frames_expose_event (GtkWidget *widget,
if (fgeom.max_rect.width > 0 && fgeom.max_rect.height > 0)
{
draw_control_bg (frames, frame, META_FRAME_CONTROL_MAXIMIZE, &fgeom);
MetaFrameControl ctrl;
if (flags & META_FRAME_MAXIMIZED)
ctrl = META_FRAME_CONTROL_UNMAXIMIZE;
else
ctrl = META_FRAME_CONTROL_MAXIMIZE;
draw_control_bg (frames, frame, ctrl, &fgeom);
draw_control (frames, frame->window,
NULL,
META_FRAME_CONTROL_MAXIMIZE,
NULL, NULL,
ctrl,
fgeom.max_rect.x + inner.left,
fgeom.max_rect.y + inner.top,
fgeom.max_rect.width - inner.left - inner.right,
@@ -1724,7 +1861,7 @@ meta_frames_expose_event (GtkWidget *widget,
draw_control_bg (frames, frame, META_FRAME_CONTROL_MINIMIZE, &fgeom);
draw_control (frames, frame->window,
NULL,
NULL, NULL,
META_FRAME_CONTROL_MINIMIZE,
fgeom.min_rect.x + inner.left,
fgeom.min_rect.y + inner.top,
@@ -1993,6 +2130,7 @@ control_rect (MetaFrameControl control,
rect = &fgeom->min_rect;
break;
case META_FRAME_CONTROL_MAXIMIZE:
case META_FRAME_CONTROL_UNMAXIMIZE:
rect = &fgeom->max_rect;
break;
case META_FRAME_CONTROL_RESIZE_SE:
@@ -2051,17 +2189,22 @@ get_control (MetaFrames *frames,
if (POINT_IN_RECT (x, y, fgeom.min_rect))
return META_FRAME_CONTROL_MINIMIZE;
if (POINT_IN_RECT (x, y, fgeom.max_rect))
return META_FRAME_CONTROL_MAXIMIZE;
if (POINT_IN_RECT (x, y, fgeom.menu_rect))
return META_FRAME_CONTROL_MENU;
if (POINT_IN_RECT (x, y, fgeom.title_rect))
return META_FRAME_CONTROL_TITLE;
flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
if (POINT_IN_RECT (x, y, fgeom.max_rect))
{
if (flags & META_FRAME_MAXIMIZED)
return META_FRAME_CONTROL_UNMAXIMIZE;
else
return META_FRAME_CONTROL_MAXIMIZE;
}
has_vert = (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) != 0;
has_horiz = (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) != 0;

View File

@@ -34,6 +34,7 @@ typedef enum
META_FRAME_CONTROL_MENU,
META_FRAME_CONTROL_MINIMIZE,
META_FRAME_CONTROL_MAXIMIZE,
META_FRAME_CONTROL_UNMAXIMIZE,
META_FRAME_CONTROL_RESIZE_SE,
META_FRAME_CONTROL_RESIZE_S,
META_FRAME_CONTROL_RESIZE_SW,

View File

@@ -88,7 +88,8 @@ struct _MetaKeyBinding
int keycode;
};
#define INTERESTING_MODIFIERS (ShiftMask | ControlMask | Mod1Mask)
#define IGNORED_MODIFIERS (LockMask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)
#define INTERESTING_MODIFIERS (~IGNORED_MODIFIERS)
static MetaKeyBinding screen_bindings[] = {
{ XK_F1, Mod1Mask, KeyPress, handle_activate_workspace, GINT_TO_POINTER (0), 0 },
@@ -144,6 +145,88 @@ meta_display_init_keys (MetaDisplay *display)
init_bindings (display, window_bindings);
}
/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
static void
meta_change_keygrab (MetaDisplay *display,
Window xwindow,
gboolean grab,
int keysym,
int keycode,
int modmask)
{
int result;
int ignored_mask;
/* Grab keycode/modmask, together with
* all combinations of IGNORED_MODIFIERS.
* X provides no better way to do this.
*/
/* modmask can't contain any non-interesting modifiers */
g_return_if_fail ((modmask & INTERESTING_MODIFIERS) == modmask);
ignored_mask = 0;
while (ignored_mask < IGNORED_MODIFIERS)
{
if (ignored_mask & INTERESTING_MODIFIERS)
{
/* Not a combination of IGNORED_MODIFIERS
* (it contains some non-ignored modifiers)
*/
++ignored_mask;
continue;
}
meta_error_trap_push (display);
if (grab)
XGrabKey (display->xdisplay, keycode,
modmask | ignored_mask,
xwindow,
True,
GrabModeAsync, GrabModeAsync);
else
XUngrabKey (display->xdisplay, keycode,
modmask | ignored_mask,
xwindow);
result = meta_error_trap_pop (display);
if (grab && result != Success)
{
const char *name;
name = XKeysymToString (keysym);
if (name == NULL)
name = "(unknown)";
if (result == BadAccess)
meta_warning (_("Some other program is already using the key %s with modifiers %x as a binding\n"), name, modmask | ignored_mask);
}
++ignored_mask;
}
}
static void
meta_grab_key (MetaDisplay *display,
Window xwindow,
int keysym,
int keycode,
int modmask)
{
meta_change_keygrab (display, xwindow, TRUE, keysym, keycode, modmask);
}
static void
meta_ungrab_key (MetaDisplay *display,
Window xwindow,
int keysym,
int keycode,
int modmask)
{
meta_change_keygrab (display, xwindow, FALSE, keysym, keycode, modmask);
}
static void
grab_keys (MetaKeyBinding *bindings,
MetaDisplay *display,
@@ -156,24 +239,10 @@ grab_keys (MetaKeyBinding *bindings,
{
if (bindings[i].keycode != 0)
{
int result;
meta_error_trap_push (display);
XGrabKey (display->xdisplay, bindings[i].keycode,
bindings[i].mask, xwindow, True,
GrabModeAsync, GrabModeAsync);
result = meta_error_trap_pop (display);
if (result != Success)
{
const char *name;
name = XKeysymToString (bindings[i].keysym);
if (name == NULL)
name = "(unknown)";
if (result == BadAccess)
meta_warning (_("Some other program is already using the key %s as a binding\n"), name);
}
meta_grab_key (display, xwindow,
bindings[i].keysym,
bindings[i].keycode,
bindings[i].mask);
}
++i;
@@ -192,10 +261,10 @@ ungrab_keys (MetaKeyBinding *bindings,
{
if (bindings[i].keycode != 0)
{
meta_error_trap_push (display);
XUngrabKey (display->xdisplay, bindings[i].keycode,
bindings[i].mask, xwindow);
meta_error_trap_pop (display);
meta_ungrab_key (display, xwindow,
bindings[i].keysym,
bindings[i].keycode,
bindings[i].mask);
}
++i;

View File

@@ -38,11 +38,20 @@
static MetaExitCode meta_exit_code = META_EXIT_SUCCESS;
static GMainLoop *meta_main_loop = NULL;
static void
log_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
{
meta_warning ("GLib log level %d: %s\n", log_level, message);
}
static void
usage (void)
{
g_print ("metacity [--disable-sm] [--sm-client-id=ID] [--display=DISPLAY]\n");
exit (0);
exit (1);
}
int
@@ -153,10 +162,7 @@ main (int argc, char **argv)
{
putenv (display_name);
/* DO NOT FREE display_name, putenv() sucks */
}
/* gtk_init() below overrides this, so it can be removed */
meta_errors_init ();
}
g_type_init ();
@@ -164,6 +170,14 @@ main (int argc, char **argv)
meta_session_init (client_id); /* client_id == NULL is fine */
meta_ui_init (&argc, &argv);
/* must be after UI init so we can override GDK handlers */
meta_errors_init ();
g_log_set_handler (NULL,
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
log_handler, NULL);
g_log_set_always_fatal (G_LOG_LEVEL_MASK);
if (!meta_display_open (NULL))
meta_exit (META_EXIT_ERROR);

View File

@@ -168,6 +168,12 @@ meta_window_menu_new (MetaFrames *frames,
META_FRAME_CONTROL_MAXIMIZE,
&pix, &mask);
break;
case META_MENU_OP_UNMAXIMIZE:
meta_frames_get_pixmap_for_control (frames,
META_FRAME_CONTROL_UNMAXIMIZE,
&pix, &mask);
break;
case META_MENU_OP_MINIMIZE:
meta_frames_get_pixmap_for_control (frames,
@@ -251,10 +257,10 @@ meta_window_menu_new (MetaFrames *frames,
MenuData *md;
if (ops & META_MENU_OP_UNSTICK)
label = g_strdup_printf (_("Only on workspace _%d\n"),
label = g_strdup_printf (_("Only on workspace _%d"),
i + 1);
else
label = g_strdup_printf (_("Move to workspace _%d\n"),
label = g_strdup_printf (_("Move to workspace _%d"),
i + 1);
mi = gtk_menu_item_new_with_mnemonic (label);

6
src/metacity.desktop Normal file
View File

@@ -0,0 +1,6 @@
[Desktop Entry]
Name=Metacity
Exec=metacity
[Window Manager]
SessionManaged=true

View File

@@ -253,6 +253,12 @@ meta_window_place (MetaWindow *window,
meta_verbose ("Centered window %s over transient parent\n",
window->desc);
if (parent->has_focus)
{
meta_verbose ("Focusing transient window since parent had focus\n");
meta_window_focus (window, CurrentTime); /* FIXME CurrentTime */
}
goto done;
}
}

View File

@@ -195,6 +195,8 @@ meta_screen_new (MetaDisplay *display,
screen->width = WidthOfScreen (screen->xscreen);
screen->height = HeightOfScreen (screen->xscreen);
screen->current_cursor = -1; /* invalid/unset */
screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);

View File

@@ -26,11 +26,6 @@
#include <X11/Xutil.h>
#include "ui.h"
/* should investigate changing these to whatever most apps use */
#define META_ICON_WIDTH 32
#define META_ICON_HEIGHT 32
typedef void (* MetaScreenWindowFunc) (MetaScreen *screen, MetaWindow *window,
gpointer user_data);
@@ -41,6 +36,8 @@ struct _MetaScreen
char *screen_name;
Screen *xscreen;
Window xroot;
int default_depth;
Visual *default_xvisual;
int width;
int height;
MetaUI *ui;

View File

@@ -77,8 +77,10 @@ process_ice_messages (GIOChannel *channel,
/* We were disconnected */
IceSetShutdownNegotiation (connection, False);
IceCloseConnection (connection);
}
return FALSE;
}
return TRUE;
}
@@ -97,8 +99,8 @@ new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
*/
GIOChannel *channel;
fcntl (IceConnectionNumber(connection),F_SETFD,
fcntl(IceConnectionNumber(connection),F_GETFD,0) | FD_CLOEXEC);
fcntl (IceConnectionNumber (connection), F_SETFD,
fcntl (IceConnectionNumber (connection), F_GETFD, 0) | FD_CLOEXEC);
channel = g_io_channel_unix_new (IceConnectionNumber (connection));
@@ -119,15 +121,15 @@ new_ice_connection (IceConn connection, IcePointer client_data, Bool opening,
}
}
static IceIOErrorHandler gnome_ice_installed_handler;
static IceIOErrorHandler ice_installed_handler;
/* We call any handler installed before (or after) gnome_ice_init but
avoid calling the default libICE handler which does an exit() */
static void
ice_io_error_handler (IceConn connection)
{
if (gnome_ice_installed_handler)
(*gnome_ice_installed_handler) (connection);
if (ice_installed_handler)
(*ice_installed_handler) (connection);
}
static void
@@ -139,11 +141,11 @@ ice_init (void)
{
IceIOErrorHandler default_handler;
gnome_ice_installed_handler = IceSetIOErrorHandler (NULL);
ice_installed_handler = IceSetIOErrorHandler (NULL);
default_handler = IceSetIOErrorHandler (ice_io_error_handler);
if (gnome_ice_installed_handler == default_handler)
gnome_ice_installed_handler = NULL;
if (ice_installed_handler == default_handler)
ice_installed_handler = NULL;
IceAddConnectionWatch (new_ice_connection, NULL);
@@ -244,10 +246,11 @@ meta_session_init (const char *previous_id)
current_state = STATE_REGISTERING;
{
SmProp prop1, prop2, prop3, prop4, prop5, *props[5];
SmPropValue prop1val, prop2val, prop3val, prop4val, prop5val;
SmProp prop1, prop2, prop3, prop4, prop5, prop6, *props[6];
SmPropValue prop1val, prop2val, prop3val, prop4val, prop5val, prop6val;
char pid[32];
char hint = SmRestartIfRunning;
char priority = 20; /* low to run before other apps */
prop1.name = SmProgram;
prop1.type = SmARRAY8;
@@ -288,14 +291,22 @@ meta_session_init (const char *previous_id)
prop5.vals = &prop5val;
prop5val.value = g_get_home_dir ();
prop5val.length = strlen (prop5val.value);
prop6.name = "_GSM_Priority";
prop6.type = SmCARD8;
prop6.num_vals = 1;
prop6.vals = &prop6val;
prop6val.value = &priority;
prop6val.length = 1;
props[0] = &prop1;
props[1] = &prop2;
props[2] = &prop3;
props[3] = &prop4;
props[4] = &prop5;
props[5] = &prop6;
SmcSetProperties (session_connection, 5, props);
SmcSetProperties (session_connection, 6, props);
}
set_clone_restart_commands ();
@@ -663,13 +674,14 @@ window_gravity_from_string (const char *str)
}
static char*
encode_text_as_utf8 (const char *text)
encode_text_as_utf8_markup (const char *text)
{
/* text can be any encoding, and is nul-terminated.
* we pretend it's Latin-1 and encode as UTF-8
*/
GString *str;
const char *p;
char *escaped;
str = g_string_new ("");
@@ -680,13 +692,16 @@ encode_text_as_utf8 (const char *text)
++p;
}
return g_string_free (str, FALSE);
escaped = g_markup_escape_text (str->str, str->len);
g_string_free (str, TRUE);
return escaped;
}
static char*
decode_text_from_utf8 (const char *text)
{
/* Convert back from the encoded UTF-8 */
/* Convert back from the encoded (but not escaped) UTF-8 */
GString *str;
const char *p;
@@ -801,13 +816,13 @@ save_state (void)
* in practice they are always ascii though.)
*/
sm_client_id = encode_text_as_utf8 (window->sm_client_id);
sm_client_id = encode_text_as_utf8_markup (window->sm_client_id);
res_class = window->res_class ?
encode_text_as_utf8 (window->res_class) : NULL;
encode_text_as_utf8_markup (window->res_class) : NULL;
res_name = window->res_name ?
encode_text_as_utf8 (window->res_name) : NULL;
encode_text_as_utf8_markup (window->res_name) : NULL;
role = window->role ?
encode_text_as_utf8 (window->role) : NULL;
encode_text_as_utf8_markup (window->role) : NULL;
meta_verbose ("Saving session managed window %s, client ID '%s'\n",
window->desc, window->sm_client_id);
@@ -879,11 +894,17 @@ save_state (void)
out:
if (outfile)
{
if (fclose (outfile) != 0)
/* FIXME need a dialog for this */
if (ferror (outfile))
{
meta_warning (_("Error writing session file '%s': %s\n"),
session_file, g_strerror (errno));
}
if (fclose (outfile))
{
meta_warning (_("Error closing session file '%s': %s\n"),
session_file, g_strerror (errno));
}
}
g_free (metacity_dir);

View File

@@ -62,6 +62,8 @@ meta_stack_new (MetaScreen *screen)
stack->pending = NULL;
stack->freeze_count = 0;
stack->n_added = 0;
stack->last_root_children_stacked = NULL;
return stack;
}
@@ -95,6 +97,10 @@ meta_stack_free (MetaStack *stack)
}
g_list_free (stack->pending);
g_array_free (stack->last_root_children_stacked, TRUE);
g_free (stack);
}
static MetaStackOp*
@@ -259,7 +265,8 @@ compute_layer (MetaWindow *window)
break;
case META_WINDOW_DOCK:
window->layer = META_LAYER_DOCK;
/* still experimenting here */
window->layer = META_LAYER_NORMAL;
break;
case META_WINDOW_FULLSCREEN:
@@ -634,9 +641,101 @@ meta_stack_sync_to_server (MetaStack *stack)
root_children_stacked->len);
meta_error_trap_push (stack->screen->display);
XRestackWindows (stack->screen->display->xdisplay,
(Window *) root_children_stacked->data,
root_children_stacked->len);
if (stack->last_root_children_stacked == NULL)
{
/* Just impose our stack, we don't know the previous state.
* This involves a ton of circulate requests and may flicker.
*/
meta_verbose ("Don't know last stack state, restacking everything\n");
if (root_children_stacked->len > 0)
XRestackWindows (stack->screen->display->xdisplay,
(Window *) root_children_stacked->data,
root_children_stacked->len);
}
else if (root_children_stacked->len > 0)
{
/* Try to do minimal window moves to get the stack in order */
/* A point of note: these arrays include frames not client windows,
* so if a client window has changed frame since last_root_children_stacked
* as saved, then we may have inefficiency, but I don't think things
* break...
*/
const Window *old_stack = (Window *) stack->last_root_children_stacked->data;
const Window *new_stack = (Window *) root_children_stacked->data;
const int old_len = stack->last_root_children_stacked->len;
const int new_len = root_children_stacked->len;
const Window *oldp = old_stack;
const Window *newp = new_stack;
const Window *old_end = old_stack + old_len;
const Window *new_end = new_stack + new_len;
Window last_window = None;
while (oldp != old_end &&
newp != new_end)
{
if (*oldp == *newp)
{
/* Stacks are the same here, move on */
++oldp;
++newp;
}
else if (meta_display_lookup_x_window (stack->screen->display,
*oldp) == NULL)
{
/* *oldp is no longer known to us (probably destroyed),
* so we can just skip it
*/
++oldp;
}
else
{
/* Move *newp below last_window */
if (last_window == None)
{
meta_verbose ("Raising window 0x%lx to the top\n", *newp);
XRaiseWindow (stack->screen->display->xdisplay,
*newp);
}
else
{
/* This means that if last_window is dead, but not
* *newp, then we fail to restack *newp; but on
* unmanaging last_window, we'll fix it up.
*/
XWindowChanges changes;
changes.sibling = last_window;
changes.stack_mode = Below;
meta_verbose ("Placing window 0x%lx below 0x%lx\n",
*newp, last_window);
XConfigureWindow (stack->screen->display->xdisplay,
*newp,
CWSibling | CWStackMode,
&changes);
}
++newp;
}
last_window = *newp;
}
if (newp != new_end)
{
/* Restack remaining windows */
meta_verbose ("Restacking remaining %d windows\n",
(int) (new_end - newp));
XRestackWindows (stack->screen->display->xdisplay,
(Window *) newp, new_end - newp);
}
}
meta_error_trap_pop (stack->screen->display);
/* on error, a window was destroyed; it should eventually
* get removed from the stacking list when we unmanage it
@@ -661,8 +760,11 @@ meta_stack_sync_to_server (MetaStack *stack)
stacked->len);
g_array_free (stacked, TRUE);
g_array_free (root_children_stacked, TRUE);
if (stack->last_root_children_stacked)
g_array_free (stack->last_root_children_stacked, TRUE);
stack->last_root_children_stacked = root_children_stacked;
/* That was scary... */
}

View File

@@ -61,6 +61,9 @@ struct _MetaStack
int freeze_count;
int n_added;
/* The last-known stack */
GArray *last_root_children_stacked;
};
MetaStack *meta_stack_new (MetaScreen *screen);

101
src/ui.c
View File

@@ -19,12 +19,15 @@
* 02111-1307, USA.
*/
#include <config.h>
#include "ui.h"
#include "frames.h"
#include "util.h"
#include "menu.h"
#include "core.h"
#include "inlinepixbufs.h"
struct _MetaUI
{
Display *xdisplay;
@@ -36,7 +39,16 @@ void
meta_ui_init (int *argc, char ***argv)
{
if (!gtk_init_check (argc, argv))
meta_fatal ("Unable to open X display %s\n", gdk_display_name);
meta_fatal ("Unable to open X display %s\n", XDisplayName (NULL));
{
/* FIXME this is a hackaround for a GTK bug with using menus without
* menubars. we have to use the get_type value since it's G_GNUC_CONST
*/
volatile GType t;
t = gtk_menu_bar_get_type ();
t += 5;
}
}
Display*
@@ -419,14 +431,64 @@ meta_ui_pop_delay_exposes (MetaUI *ui)
meta_frames_pop_delay_exposes (ui->frames);
}
#ifdef HAVE_GDK_PIXBUF_NEW_FROM_STREAM
#define gdk_pixbuf_new_from_inline gdk_pixbuf_new_from_stream
#endif
GdkPixbuf*
meta_ui_get_default_window_icon (MetaUI *ui)
{
/* FIXME */
return gtk_widget_render_icon (GTK_WIDGET (ui->frames),
GTK_STOCK_NEW,
GTK_ICON_SIZE_LARGE_TOOLBAR,
NULL);
static GdkPixbuf *default_icon = NULL;
if (default_icon == NULL)
{
GdkPixbuf *base;
base = gdk_pixbuf_new_from_inline (-1, default_icon_data,
FALSE,
NULL);
g_assert (base);
default_icon = gdk_pixbuf_scale_simple (base,
META_ICON_WIDTH,
META_ICON_HEIGHT,
GDK_INTERP_BILINEAR);
g_object_unref (G_OBJECT (base));
}
g_object_ref (G_OBJECT (default_icon));
return default_icon;
}
GdkPixbuf*
meta_ui_get_default_mini_icon (MetaUI *ui)
{
static GdkPixbuf *default_icon = NULL;
if (default_icon == NULL)
{
GdkPixbuf *base;
base = gdk_pixbuf_new_from_inline (-1, default_icon_data,
FALSE,
NULL);
g_assert (base);
default_icon = gdk_pixbuf_scale_simple (base,
META_MINI_ICON_WIDTH,
META_MINI_ICON_HEIGHT,
GDK_INTERP_BILINEAR);
g_object_unref (G_OBJECT (base));
}
g_object_ref (G_OBJECT (default_icon));
return default_icon;
}
gboolean
@@ -445,3 +507,30 @@ meta_ui_window_should_not_cause_focus (Display *xdisplay,
else
return FALSE;
}
char*
meta_text_property_to_utf8 (Display *xdisplay,
const XTextProperty *prop)
{
char **list;
int count;
char *retval;
list = NULL;
count = gdk_text_property_to_utf8_list (prop->encoding,
prop->format,
prop->value,
prop->nitems,
&list);
if (count == 0)
return NULL;
retval = list[0];
list[0] = g_strdup (""); /* something to free */
g_strfreev (list);
return retval;
}

View File

@@ -25,6 +25,7 @@
/* Don't include gtk.h or gdk.h here */
#include "common.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -128,10 +129,14 @@ void meta_ui_push_delay_exposes (MetaUI *ui);
void meta_ui_pop_delay_exposes (MetaUI *ui);
GdkPixbuf* meta_ui_get_default_window_icon (MetaUI *ui);
GdkPixbuf* meta_ui_get_default_mini_icon (MetaUI *ui);
gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
Window xwindow);
char* meta_text_property_to_utf8 (Display *xdisplay,
const XTextProperty *prop);
#include "tabpopup.h"
#endif

View File

@@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static gboolean is_verbose = FALSE;
static gboolean is_debugging = FALSE;
@@ -42,6 +43,9 @@ ensure_logfile (void)
dir = g_get_home_dir ();
str = g_strconcat (dir, "/", "metacity.log", NULL);
/* we want to replace not truncate any old logfile */
unlink (str);
logfile = fopen (str, "w");

View File

@@ -37,8 +37,7 @@ typedef enum
{
META_IS_CONFIGURE_REQUEST = 1 << 0,
META_DO_GRAVITY_ADJUST = 1 << 1,
META_USER_RESIZE = 1 << 2,
META_USER_MOVE = 1 << 3
META_USER_MOVE_RESIZE = 1 << 2
} MetaMoveResizeFlags;
static void constrain_size (MetaWindow *window,
@@ -108,6 +107,14 @@ static gboolean get_cardinal (MetaDisplay *display,
Atom atom,
gulong *val);
static char* get_text_property (MetaDisplay *display,
Window xwindow,
Atom atom);
static char* get_utf8_property (MetaDisplay *display,
Window xwindow,
Atom atom);
void meta_window_unqueue_calc_showing (MetaWindow *window);
static void meta_window_apply_session_info (MetaWindow *window,
@@ -249,6 +256,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window->rect.width = attrs.width;
window->rect.height = attrs.height;
window->size_hints.flags = 0;
/* And border width, size_hints are the "request" */
window->border_width = attrs.border_width;
window->size_hints.x = attrs.x;
@@ -266,14 +275,14 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window->title = NULL;
window->icon_name = NULL;
window->icon = NULL;
window->mini_icon = NULL;
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
window->frame = NULL;
window->has_focus = FALSE;
window->user_has_resized = FALSE;
window->user_has_moved = FALSE;
window->user_has_move_resized = FALSE;
window->maximized = FALSE;
window->on_all_workspaces = FALSE;
@@ -681,6 +690,9 @@ meta_window_free (MetaWindow *window)
if (window->icon)
g_object_unref (G_OBJECT (window->icon));
if (window->mini_icon)
g_object_unref (G_OBJECT (window->mini_icon));
g_free (window->sm_client_id);
g_free (window->role);
@@ -1311,22 +1323,19 @@ meta_window_move_resize_internal (MetaWindow *window,
int frame_size_dy;
gboolean is_configure_request;
gboolean do_gravity_adjust;
gboolean is_user_resize;
gboolean is_user_move;
gboolean is_user_action;
is_configure_request = (flags & META_IS_CONFIGURE_REQUEST) != 0;
do_gravity_adjust = (flags & META_DO_GRAVITY_ADJUST) != 0;
is_user_resize = (flags & META_USER_RESIZE) != 0;
is_user_move = (flags & META_USER_MOVE) != 0;
is_user_action = (flags & META_USER_MOVE_RESIZE) != 0;
{
int oldx, oldy;
meta_window_get_position (window, &oldx, &oldy);
meta_verbose ("Move/resize %s to %d,%d %dx%d%s%s%s from %d,%d %dx%d\n",
meta_verbose ("Move/resize %s to %d,%d %dx%d%s%s from %d,%d %dx%d\n",
window->desc, root_x_nw, root_y_nw, w, h,
is_configure_request ? " (configure request)" : "",
is_user_resize ? " (user resize)" : "",
is_user_move ? " (user move)" : "",
is_user_action ? " (user move/resize)" : "",
oldx, oldy, window->rect.width, window->rect.height);
}
@@ -1565,25 +1574,37 @@ meta_window_move_resize_internal (MetaWindow *window,
{
meta_frame_sync_to_window (window->frame, need_move_frame, need_resize_frame);
}
if (need_configure_notify)
send_configure_notify (window);
if (is_user_resize)
if (is_user_action)
{
window->user_has_resized = TRUE;
window->user_has_move_resized = TRUE;
window->user_rect.width = window->rect.width;
window->user_rect.height = window->rect.height;
}
if (is_user_move)
{
window->user_has_moved = TRUE;
meta_window_get_position (window,
&window->user_rect.x,
&window->user_rect.y);
}
if (need_move_frame || need_resize_frame ||
need_move_client || need_resize_client)
{
int newx, newy;
meta_window_get_position (window, &newx, &newy);
meta_verbose ("New size/position %d,%d %dx%d (user %d,%d %dx%d)\n",
newx, newy, window->rect.width, window->rect.height,
window->user_rect.x, window->user_rect.y,
window->user_rect.width, window->user_rect.height);
}
else
{
meta_verbose ("Size/position not modified\n");
}
/* Invariants leaving this function are:
* a) window->rect and frame->rect reflect the actual
@@ -1603,7 +1624,7 @@ meta_window_resize (MetaWindow *window,
meta_window_get_position (window, &x, &y);
meta_window_move_resize_internal (window,
user_op ? META_USER_RESIZE : 0,
user_op ? META_USER_MOVE_RESIZE : 0,
NorthWestGravity,
x, y, w, h);
}
@@ -1615,7 +1636,7 @@ meta_window_move (MetaWindow *window,
int root_y_nw)
{
meta_window_move_resize_internal (window,
user_op ? META_USER_MOVE : 0,
user_op ? META_USER_MOVE_RESIZE : 0,
NorthWestGravity,
root_x_nw, root_y_nw,
window->rect.width,
@@ -1631,7 +1652,7 @@ meta_window_move_resize (MetaWindow *window,
int h)
{
meta_window_move_resize_internal (window,
user_op ? META_USER_MOVE | META_USER_RESIZE : 0,
user_op ? META_USER_MOVE_RESIZE : 0,
NorthWestGravity,
root_x_nw, root_y_nw,
w, h);
@@ -1649,7 +1670,7 @@ meta_window_resize_with_gravity (MetaWindow *window,
meta_window_get_position (window, &x, &y);
meta_window_move_resize_internal (window,
user_op ? META_USER_RESIZE : 0,
user_op ? META_USER_MOVE_RESIZE : 0,
gravity,
x, y, w, h);
}
@@ -1665,9 +1686,9 @@ meta_window_move_resize_now (MetaWindow *window)
meta_window_get_user_position (window, &x, &y);
meta_window_move_resize (window, FALSE, x, y,
window->user_has_resized ?
window->user_has_move_resized ?
window->user_rect.width : window->rect.width,
window->user_has_resized ?
window->user_has_move_resized ?
window->user_rect.height : window->rect.height);
}
@@ -1704,7 +1725,7 @@ meta_window_get_user_position (MetaWindow *window,
int *x,
int *y)
{
if (window->user_has_moved)
if (window->user_has_move_resized)
{
if (x)
*x = window->user_rect.x;
@@ -2018,6 +2039,14 @@ meta_window_raise (MetaWindow *window)
meta_stack_raise (window->screen->stack, window);
}
void
meta_window_lower (MetaWindow *window)
{
meta_verbose ("Lowering window %s\n", window->desc);
meta_stack_lower (window->screen->stack, window);
}
void
meta_window_send_icccm_message (MetaWindow *window,
Atom atom,
@@ -2258,7 +2287,7 @@ meta_window_client_message (MetaWindow *window,
shade = (action == _NET_WM_STATE_ADD ||
(action == _NET_WM_STATE_TOGGLE && !window->shaded));
if (shade)
if (shade && window->has_shade_func)
meta_window_shade (window);
else
meta_window_unshade (window);
@@ -2273,7 +2302,7 @@ meta_window_client_message (MetaWindow *window,
max = (action == _NET_WM_STATE_ADD ||
(action == _NET_WM_STATE_TOGGLE && !window->maximized));
if (max)
if (max && window->has_maximize_func)
meta_window_maximize (window);
else
meta_window_unmaximize (window);
@@ -2317,7 +2346,8 @@ meta_window_client_message (MetaWindow *window,
{
meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
event->xclient.data.l[0]);
if (event->xclient.data.l[0] == IconicState)
if (event->xclient.data.l[0] == IconicState &&
window->has_minimize_func)
meta_window_minimize (window);
return TRUE;
@@ -2419,6 +2449,25 @@ meta_window_client_message (MetaWindow *window,
return TRUE;
}
else if (event->xclient.message_type ==
display->atom_net_active_window)
{
meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s'", window->desc);
/* Switch to window's workspace - alternatively we could move
* window back to this workspace. I don't know which is right.
*/
if (!meta_workspace_contains_window (window->screen->active_workspace,
window) &&
/* this check shouldn't actually be required, I don't think it is */
window->workspaces)
meta_workspace_activate (window->workspaces->data);
meta_window_raise (window);
meta_window_focus (window, CurrentTime); /* FIXME CurrentTime */
return TRUE;
}
return FALSE;
}
@@ -2493,6 +2542,9 @@ meta_window_notify_focus (MetaWindow *window,
meta_frame_queue_draw (window->frame);
}
/* Now set _NET_ACTIVE_WINDOW hint */
meta_display_update_active_window_hint (window->display);
return FALSE;
}
@@ -2641,13 +2693,76 @@ send_configure_notify (MetaWindow *window)
meta_error_trap_pop (window->display);
}
#define FLAG_TOGGLED_ON(old,new,flag) \
(((old)->flags & (flag)) == 0 && \
((new)->flags & (flag)) != 0)
#define FLAG_TOGGLED_OFF(old,new,flag) \
(((old)->flags & (flag)) != 0 && \
((new)->flags & (flag)) == 0)
#define FLAG_CHANGED(old,new,flag) \
(FLAG_TOGGLED_ON(old,new,flag) || FLAG_TOGGLED_OFF(old,new,flag))
static void
spew_size_hints_differences (const XSizeHints *old,
const XSizeHints *new)
{
if (FLAG_CHANGED (old, new, USPosition))
meta_verbose ("XSizeHints: USPosition now %s\n",
FLAG_TOGGLED_ON (old, new, USPosition) ? "set" : "unset");
if (FLAG_CHANGED (old, new, USSize))
meta_verbose ("XSizeHints: USSize now %s\n",
FLAG_TOGGLED_ON (old, new, USSize) ? "set" : "unset");
if (FLAG_CHANGED (old, new, PPosition))
meta_verbose ("XSizeHints: PPosition now %s\n",
FLAG_TOGGLED_ON (old, new, PPosition) ? "set" : "unset");
if (FLAG_CHANGED (old, new, PSize))
meta_verbose ("XSizeHints: PSize now %s\n",
FLAG_TOGGLED_ON (old, new, PSize) ? "set" : "unset");
if (FLAG_CHANGED (old, new, PMinSize))
meta_verbose ("XSizeHints: PMinSize now %s (%d x %d -> %d x %d)\n",
FLAG_TOGGLED_ON (old, new, PMinSize) ? "set" : "unset",
old->min_width, old->min_height,
new->min_width, new->min_height);
if (FLAG_CHANGED (old, new, PMaxSize))
meta_verbose ("XSizeHints: PMaxSize now %s (%d x %d -> %d x %d)\n",
FLAG_TOGGLED_ON (old, new, PMaxSize) ? "set" : "unset",
old->max_width, old->max_height,
new->max_width, new->max_height);
if (FLAG_CHANGED (old, new, PResizeInc))
meta_verbose ("XSizeHints: PResizeInc now %s (width_inc %d -> %d height_inc %d -> %d)\n",
FLAG_TOGGLED_ON (old, new, PResizeInc) ? "set" : "unset",
old->width_inc, new->width_inc,
old->height_inc, new->height_inc);
if (FLAG_CHANGED (old, new, PAspect))
meta_verbose ("XSizeHints: PAspect now %s (min %d/%d -> %d/%d max %d/%d -> %d/%d)\n",
FLAG_TOGGLED_ON (old, new, PAspect) ? "set" : "unset",
old->min_aspect.x, old->min_aspect.y,
new->min_aspect.x, new->min_aspect.y,
old->max_aspect.x, old->max_aspect.y,
new->max_aspect.x, new->max_aspect.y);
if (FLAG_CHANGED (old, new, PBaseSize))
meta_verbose ("XSizeHints: PBaseSize now %s (%d x %d -> %d x %d)\n",
FLAG_TOGGLED_ON (old, new, PBaseSize) ? "set" : "unset",
old->base_width, old->base_height,
new->base_width, new->base_height);
if (FLAG_CHANGED (old, new, PWinGravity))
meta_verbose ("XSizeHints: PWinGravity now %s (%d -> %d)\n",
FLAG_TOGGLED_ON (old, new, PWinGravity) ? "set" : "unset",
old->win_gravity, new->win_gravity);
}
static int
update_size_hints (MetaWindow *window)
{
int x, y, w, h;
gulong supplied;
XSizeHints old_hints;
meta_verbose ("Updating WM_NORMAL_HINTS for %s\n", window->desc);
meta_verbose ("Updating WM_NORMAL_HINTS\n");
old_hints = window->size_hints;
/* Save the last ConfigureRequest, which we put here.
* Values here set in the hints are supposed to
@@ -2814,6 +2929,8 @@ update_size_hints (MetaWindow *window)
}
recalc_window_features (window);
spew_size_hints_differences (&old_hints, &window->size_hints);
return meta_error_trap_pop (window->display);
}
@@ -2821,8 +2938,6 @@ update_size_hints (MetaWindow *window)
static int
update_title (MetaWindow *window)
{
XTextProperty text;
meta_error_trap_push (window->display);
if (window->title)
@@ -2831,62 +2946,26 @@ update_title (MetaWindow *window)
window->title = NULL;
}
XGetTextProperty (window->display->xdisplay,
window->xwindow,
&text,
window->display->atom_net_wm_name);
window->title = get_utf8_property (window->display,
window->xwindow,
window->display->atom_net_wm_name);
if (text.nitems > 0 &&
text.format == 8 &&
g_utf8_validate (text.value, text.nitems, NULL))
if (window->title)
{
meta_verbose ("Using _NET_WM_NAME for new title of %s: '%s'\n",
window->desc, text.value);
window->title = g_strdup (text.value);
window->desc, window->title);
}
if (text.nitems > 0)
XFree (text.value);
if (window->title == NULL &&
text.nitems > 0)
meta_warning ("_NET_WM_NAME property for %s contained invalid UTF-8\n",
window->desc);
if (window->title == NULL)
{
XGetTextProperty (window->display->xdisplay,
window->xwindow,
&text,
XA_WM_NAME);
window->title = get_text_property (window->display,
window->xwindow,
XA_WM_NAME);
if (text.nitems > 0)
if (window->title)
{
/* FIXME This isn't particularly correct. Need to copy the
* GDK code...
*/
char *str;
GError *err;
err = NULL;
str = g_locale_to_utf8 (text.value,
(text.format / 8) * text.nitems,
NULL, NULL,
&err);
if (err != NULL)
{
meta_warning ("WM_NAME property for %s contained stuff window manager is too dumb to figure out: %s\n", window->desc, err->message);
g_error_free (err);
}
if (str)
meta_verbose ("Using WM_NAME for new title of %s: '%s'\n",
window->desc, text.value);
window->title = str;
XFree (text.value);
meta_verbose ("Using WM_NAME for new title of %s: '%s'\n",
window->desc, window->title);
}
}
@@ -3493,7 +3572,7 @@ get_cardinal (MetaDisplay *display,
return FALSE;
if (type != XA_CARDINAL)
return FALSE;
return FALSE; /* FIXME free num ? */
*val = *num;
@@ -3502,6 +3581,93 @@ get_cardinal (MetaDisplay *display,
return TRUE;
}
static char*
get_text_property (MetaDisplay *display,
Window xwindow,
Atom atom)
{
XTextProperty text;
char *retval;
meta_error_trap_push (display);
text.nitems = 0;
if (XGetTextProperty (display->xdisplay,
xwindow,
&text,
atom))
{
retval = meta_text_property_to_utf8 (display->xdisplay, &text);
if (text.nitems > 0)
XFree (text.value);
}
else
{
retval = NULL;
meta_verbose ("XGetTextProperty() failed\n");
}
meta_error_trap_pop (display);
return retval;
}
static char*
get_utf8_property (MetaDisplay *display,
Window xwindow,
Atom atom)
{
Atom type;
int format;
gulong nitems;
gulong bytes_after;
guchar *val;
int err;
char *retval;
meta_error_trap_push (display);
type = None;
val = NULL;
XGetWindowProperty (display->xdisplay,
xwindow,
atom,
0, G_MAXLONG,
False, display->atom_utf8_string,
&type, &format, &nitems,
&bytes_after, (guchar **)&val);
err = meta_error_trap_pop (display);
if (err != Success)
return NULL;
if (type != display->atom_utf8_string ||
format != 8 ||
nitems == 0)
{
if (val)
XFree (val);
return NULL;
}
if (!g_utf8_validate (val, nitems, NULL))
{
char *name;
name = XGetAtomName (display->xdisplay, atom);
meta_warning ("Property %s contained invalid UTF-8\n",
name);
XFree (name);
XFree (val);
return NULL;
}
retval = g_strndup (val, nitems);
XFree (val);
return retval;
}
/* some legacy cruft */
typedef enum
{
@@ -3646,8 +3812,6 @@ update_initial_workspace (MetaWindow *window)
static int
update_icon_name (MetaWindow *window)
{
XTextProperty text;
meta_error_trap_push (window->display);
if (window->icon_name)
@@ -3656,62 +3820,24 @@ update_icon_name (MetaWindow *window)
window->icon_name = NULL;
}
XGetTextProperty (window->display->xdisplay,
window->xwindow,
&text,
window->display->atom_net_wm_icon_name);
window->icon_name = get_utf8_property (window->display, window->xwindow,
window->display->atom_net_wm_icon_name);
if (text.nitems > 0 &&
text.format == 8 &&
g_utf8_validate (text.value, text.nitems, NULL))
if (window->icon_name)
{
meta_verbose ("Using _NET_WM_ICON_NAME for new icon name of %s: '%s'\n",
window->desc, text.value);
window->icon_name = g_strdup (text.value);
}
if (text.nitems > 0)
XFree (text.value);
if (window->icon_name == NULL &&
text.nitems > 0)
meta_warning ("_NET_WM_ICON_NAME property for %s contained invalid UTF-8\n",
window->desc);
window->desc, window->icon_name);
}
if (window->icon_name == NULL)
{
XGetTextProperty (window->display->xdisplay,
window->xwindow,
&text,
XA_WM_ICON_NAME);
window->icon_name = get_text_property (window->display, window->xwindow,
XA_WM_ICON_NAME);
if (text.nitems > 0)
if (window->icon_name)
{
/* FIXME This isn't particularly correct. Need to copy the
* GDK code...
*/
char *str;
GError *err;
err = NULL;
str = g_locale_to_utf8 (text.value,
(text.format / 8) * text.nitems,
NULL, NULL,
&err);
if (err != NULL)
{
meta_warning ("WM_ICON_NAME property for %s contained stuff we are too dumb to figure out: %s\n", window->desc, err->message);
g_error_free (err);
}
if (str)
meta_verbose ("Using WM_ICON_NAME for new title of %s: '%s'\n",
window->desc, text.value);
window->icon_name = str;
XFree (text.value);
meta_verbose ("Using WM_ICON_NAME for new title of %s: '%s'\n",
window->desc, window->icon_name);
}
}
@@ -3724,6 +3850,8 @@ update_icon_name (MetaWindow *window)
static gboolean
find_best_size (gulong *data,
int nitems,
int ideal_width,
int ideal_height,
int *width,
int *height,
gulong **start)
@@ -3773,7 +3901,7 @@ find_best_size (gulong *data,
else
{
/* work with averages */
const int ideal_size = META_ICON_WIDTH * META_ICON_HEIGHT;
const int ideal_size = (ideal_width + ideal_height) / 2;
int best_size = (best_w + best_h) / 2;
int this_size = (w + h) / 2;
@@ -3791,7 +3919,7 @@ find_best_size (gulong *data,
else if (best_size > ideal_size &&
this_size >= ideal_size &&
this_size < best_size)
replace = TRUE;
replace = TRUE;
}
if (replace)
@@ -3816,11 +3944,46 @@ find_best_size (gulong *data,
return FALSE;
}
static void
argbdata_to_pixdata (gulong *argb_data, int len, guchar **pixdata)
{
guchar *p;
int i;
*pixdata = g_new (guchar, len * 4);
p = *pixdata;
/* One could speed this up a lot. */
i = 0;
while (i < len)
{
guint argb;
guint rgba;
argb = argb_data[i];
rgba = (argb << 8) | (argb >> 24);
*p = rgba >> 24;
++p;
*p = (rgba >> 16) & 0xff;
++p;
*p = (rgba >> 8) & 0xff;
++p;
*p = rgba & 0xff;
++p;
++i;
}
}
static gboolean
read_rgb_icon (MetaWindow *window,
int *width,
int *height,
guchar **pixdata)
guchar **pixdata,
int *mini_width,
int *mini_height,
guchar **mini_pixdata)
{
Atom type;
int format;
@@ -3829,9 +3992,9 @@ read_rgb_icon (MetaWindow *window,
int result;
gulong *data; /* FIXME should be guint? */
gulong *best;
int i;
int w, h;
guchar *p;
gulong *best_mini;
int mini_w, mini_h;
if (sizeof (gulong) != 4)
meta_warning ("%s: Whoops, I think this function may be broken on 64-bit\n",
@@ -3856,39 +4019,28 @@ read_rgb_icon (MetaWindow *window,
return FALSE;
}
if (!find_best_size (data, nitems, &w, &h, &best))
if (!find_best_size (data, nitems, META_ICON_WIDTH, META_ICON_HEIGHT,
&w, &h, &best))
{
XFree (data);
return FALSE;
}
if (!find_best_size (data, nitems, META_MINI_ICON_WIDTH, META_MINI_ICON_HEIGHT,
&mini_w, &mini_h, &best_mini))
{
XFree (data);
return FALSE;
}
*width = w;
*height = h;
*pixdata = g_new (guchar, w * h * 4);
p = *pixdata;
*mini_width = mini_w;
*mini_height = mini_h;
/* One could speed this up a lot. */
i = 0;
while (i < w * h)
{
guint argb;
guint rgba;
argb = best[i];
rgba = (argb << 8) | (argb >> 24);
*p = rgba >> 24;
++p;
*p = (rgba >> 16) & 0xff;
++p;
*p = (rgba >> 8) & 0xff;
++p;
*p = rgba & 0xff;
++p;
++i;
}
argbdata_to_pixdata (best, w * h, pixdata);
argbdata_to_pixdata (best_mini, mini_w * mini_h, mini_pixdata);
XFree (data);
@@ -3903,6 +4055,12 @@ clear_icon (MetaWindow *window)
g_object_unref (G_OBJECT (window->icon));
window->icon = NULL;
}
if (window->mini_icon)
{
g_object_unref (G_OBJECT (window->mini_icon));
window->mini_icon = NULL;
}
}
static void
@@ -3913,8 +4071,11 @@ free_pixels (guchar *pixels, gpointer data)
static void
replace_icon (MetaWindow *window,
GdkPixbuf *unscaled)
{
GdkPixbuf *unscaled,
GdkPixbuf *unscaled_mini)
{
clear_icon (window);
if (gdk_pixbuf_get_width (unscaled) != META_ICON_WIDTH ||
gdk_pixbuf_get_height (unscaled) != META_ICON_HEIGHT)
{
@@ -3931,6 +4092,23 @@ replace_icon (MetaWindow *window,
g_object_ref (G_OBJECT (unscaled));
window->icon = unscaled;
}
if (gdk_pixbuf_get_width (unscaled_mini) != META_MINI_ICON_WIDTH ||
gdk_pixbuf_get_height (unscaled_mini) != META_MINI_ICON_HEIGHT)
{
/* FIXME should keep aspect ratio, but for now assuming
* a square source icon
*/
window->mini_icon = gdk_pixbuf_scale_simple (unscaled_mini,
META_MINI_ICON_WIDTH,
META_MINI_ICON_HEIGHT,
GDK_INTERP_BILINEAR);
}
else
{
g_object_ref (G_OBJECT (unscaled_mini));
window->mini_icon = unscaled_mini;
}
}
static void
@@ -4065,7 +4243,7 @@ try_pixmap_and_mask (MetaWindow *window,
if (unscaled)
{
replace_icon (window, unscaled);
replace_icon (window, unscaled, unscaled);
g_object_unref (G_OBJECT (unscaled));
return TRUE;
}
@@ -4078,18 +4256,22 @@ update_icon (MetaWindow *window,
gboolean reload_rgb_icon)
{
if (FALSE && reload_rgb_icon)
if (reload_rgb_icon)
{
guchar *pixdata;
int w, h;
guchar *mini_pixdata;
int mini_w, mini_h;
pixdata = NULL;
if (read_rgb_icon (window, &w, &h, &pixdata))
if (read_rgb_icon (window, &w, &h, &pixdata,
&mini_w, &mini_h, &mini_pixdata))
{
GdkPixbuf *unscaled;
GdkPixbuf *unscaled_mini;
meta_verbose ("successfully read RGBA icon from _NET_WM_ICON, using w = %d h = %d\n", w, h);
meta_verbose ("successfully read RGBA icon from _NET_WM_ICON, using w = %d h = %d mini_w = %d mini_h = %d\n", w, h, mini_w, mini_h);
window->using_rgb_icon = TRUE;
@@ -4101,9 +4283,18 @@ update_icon (MetaWindow *window,
free_pixels,
NULL);
replace_icon (window, unscaled);
unscaled_mini = gdk_pixbuf_new_from_data (mini_pixdata,
GDK_COLORSPACE_RGB,
TRUE,
8,
mini_w, mini_h, mini_w * 4,
free_pixels,
NULL);
replace_icon (window, unscaled, unscaled_mini);
g_object_unref (G_OBJECT (unscaled));
g_object_unref (G_OBJECT (unscaled_mini));
return Success;
}
@@ -4137,7 +4328,6 @@ update_icon (MetaWindow *window,
{
meta_verbose ("No WM_NORMAL_HINTS icon, or failed to retrieve it\n");
}
if (try_pixmap_and_mask (window,
window->kwm_pixmap,
@@ -4154,6 +4344,12 @@ update_icon (MetaWindow *window,
/* Fallback to a default icon */
if (window->icon == NULL)
window->icon = meta_ui_get_default_window_icon (window->screen->ui);
if (window->mini_icon == NULL)
window->mini_icon = meta_ui_get_default_mini_icon (window->screen->ui);
g_assert (window->icon);
g_assert (window->mini_icon);
return Success;
}
@@ -4182,10 +4378,10 @@ update_kwm_icon (MetaWindow *window)
result = meta_error_trap_pop (window->display);
if (result != Success)
return None;
return result;
if (type != window->display->atom_kwm_win_icon)
return None;
return -1; /* FIXME mem leak? */
window->kwm_pixmap = icons[0];
window->kwm_mask = icons[1];
@@ -4348,18 +4544,14 @@ constrain_size (MetaWindow *window,
if (window->frame)
{
fullw -= fgeom->left_width + fgeom->right_width;
fullh -= fgeom->top_height + fgeom->bottom_height;
fullw -= (fgeom->left_width + fgeom->right_width);
fullh -= (fgeom->top_height + fgeom->bottom_height);
}
maxw = window->size_hints.max_width;
maxh = window->size_hints.max_height;
if (window->maximized)
/* we used to only constrain to fit inside screen for these cases,
* but now I don't remember why I did that.
*/
/* !(window->user_has_resized || window->user_has_moved) */
{
maxw = MIN (maxw, fullw);
maxh = MIN (maxh, fullh);

View File

@@ -55,6 +55,7 @@ struct _MetaWindow
char *icon_name;
GdkPixbuf *icon;
GdkPixbuf *mini_icon;
MetaWindowType type;
Atom type_atom;
@@ -158,8 +159,7 @@ struct _MetaWindow
/* Track whether the user has ever manually modified
* the window; if so, we can use the saved user size/pos
*/
guint user_has_resized : 1;
guint user_has_moved : 1;
guint user_has_move_resized : 1;
/* Have we placed this window? */
guint placed : 1;
@@ -299,6 +299,7 @@ void meta_window_delete (MetaWindow *window,
void meta_window_focus (MetaWindow *window,
Time timestamp);
void meta_window_raise (MetaWindow *window);
void meta_window_lower (MetaWindow *window);
/* Sends a client message */

View File

@@ -7,7 +7,7 @@ wm_tester_SOURCES= \
test_gravity_SOURCES= \
test-gravity.c
bin_PROGRAMS=wm-tester test-gravity
noinst_PROGRAMS=wm-tester test-gravity
wm_tester_LDADD= @METACITY_LIBS@
test_gravity_LDADD= @METACITY_LIBS@