Compare commits
37 Commits
METACITY_2
...
METACITY_2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e8bc8e95e2 | ||
![]() |
cfd3cdd64e | ||
![]() |
ec4edcb78c | ||
![]() |
94c3b02eef | ||
![]() |
f83ac8476c | ||
![]() |
4edccc4eb5 | ||
![]() |
0398a78b4a | ||
![]() |
ec6a455fb0 | ||
![]() |
e55ead0419 | ||
![]() |
f22b9dfd94 | ||
![]() |
ec4dfd0cbc | ||
![]() |
350ecb1dcf | ||
![]() |
38a878171a | ||
![]() |
dad1b107f5 | ||
![]() |
582a80f518 | ||
![]() |
808d21e857 | ||
![]() |
0a1f2b3a47 | ||
![]() |
4c104e1cb7 | ||
![]() |
ecf75915c7 | ||
![]() |
7be4c63ee4 | ||
![]() |
b09a781a80 | ||
![]() |
52dc32031d | ||
![]() |
a926a4a0ca | ||
![]() |
39df21227d | ||
![]() |
2830c9d748 | ||
![]() |
3886f0ecac | ||
![]() |
b1c7811e89 | ||
![]() |
1385d192c5 | ||
![]() |
82aa7363f9 | ||
![]() |
a4346200e8 | ||
![]() |
9f66f63bf5 | ||
![]() |
3645fef5e0 | ||
![]() |
f386494ba4 | ||
![]() |
936adc6ea5 | ||
![]() |
bc787fc1f3 | ||
![]() |
1c6c7350e1 | ||
![]() |
2a0a5dfdf8 |
193
ChangeLog
193
ChangeLog
@@ -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
31
README
@@ -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
|
||||
===
|
||||
|
||||
|
25
configure.in
25
configure.in
@@ -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
|
||||
])
|
||||
|
||||
|
||||
|
@@ -4,3 +4,5 @@ Makefile.in
|
||||
Makefile
|
||||
stamp-cat-id
|
||||
cat-id-tbl.c
|
||||
messages
|
||||
*.pot
|
||||
|
11
po/ChangeLog
Normal file
11
po/ChangeLog
Normal 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.
|
||||
|
@@ -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
306
po/sv.po
Normal 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"
|
@@ -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)
|
||||
|
10
src/common.h
10
src/common.h
@@ -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
|
||||
|
||||
|
||||
|
16
src/core.c
16
src/core.c
@@ -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)
|
||||
|
@@ -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
BIN
src/default_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 424 B |
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
112
src/errors.c
112
src/errors.c
@@ -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;
|
||||
}
|
||||
|
27
src/frame.c
27
src/frame.c
@@ -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,
|
||||
|
265
src/frames.c
265
src/frames.c
@@ -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;
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
24
src/main.c
24
src/main.c
@@ -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);
|
||||
|
10
src/menu.c
10
src/menu.c
@@ -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
6
src/metacity.desktop
Normal file
@@ -0,0 +1,6 @@
|
||||
[Desktop Entry]
|
||||
Name=Metacity
|
||||
Exec=metacity
|
||||
|
||||
[Window Manager]
|
||||
SessionManaged=true
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
112
src/stack.c
112
src/stack.c
@@ -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... */
|
||||
}
|
||||
|
||||
|
@@ -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
101
src/ui.c
@@ -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;
|
||||
}
|
||||
|
5
src/ui.h
5
src/ui.h
@@ -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
|
||||
|
@@ -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");
|
||||
|
||||
|
542
src/window.c
542
src/window.c
@@ -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);
|
||||
|
@@ -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 */
|
||||
|
@@ -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@
|
Reference in New Issue
Block a user