--- a/gdk/quartz/gdkkeys-quartz.c	2010-11-27 18:04:40.000000000 -0800
+++ b/gdk/quartz/gdkkeys-quartz.c	2010-11-28 15:46:42.000000000 -0800
@@ -182,7 +182,58 @@
   { 0x001d, GDK_Right },
   { 0x001e, GDK_Up },
   { 0x001f, GDK_Down },
-  { 0x007f, GDK_Delete }
+  { 0x007f, GDK_Delete },
+  { 0xf060, GDK_KEY_dead_grave },
+  { 0xf300, GDK_KEY_dead_grave },
+  { 0xf0b4, GDK_KEY_dead_acute },
+  { 0xf301, GDK_KEY_dead_acute },
+  { 0xf385, GDK_KEY_dead_acute },
+  { 0xf05e, GDK_KEY_dead_circumflex },
+  { 0xf2c6, GDK_KEY_dead_circumflex },
+  { 0xf302, GDK_KEY_dead_circumflex },
+  { 0xf07e, GDK_KEY_dead_tilde },
+  { 0xf303, GDK_KEY_dead_tilde },
+  { 0xf342, GDK_KEY_dead_perispomeni },
+  { 0xf0af, GDK_KEY_dead_macron },
+  { 0xf304, GDK_KEY_dead_macron },
+  { 0xf2d8, GDK_KEY_dead_breve },
+  { 0xf306, GDK_KEY_dead_breve },
+  { 0xf2d9, GDK_KEY_dead_abovedot },
+  { 0xf307, GDK_KEY_dead_abovedot },
+  { 0xf0a8, GDK_KEY_dead_diaeresis },
+  { 0xf308, GDK_KEY_dead_diaeresis },
+  { 0xf2da, GDK_KEY_dead_abovering },
+  { 0xf30A, GDK_KEY_dead_abovering },
+  { 0xf2dd, GDK_KEY_dead_doubleacute },
+  { 0xf30B, GDK_KEY_dead_doubleacute },
+  { 0xf2c7, GDK_KEY_dead_caron },
+  { 0xf30C, GDK_KEY_dead_caron },
+  { 0xf0be, GDK_KEY_dead_cedilla },
+  { 0xf327, GDK_KEY_dead_cedilla },
+  { 0xf2db, GDK_KEY_dead_ogonek },
+  { 0xf328, GDK_KEY_dead_ogonek },
+  { 0xfe5d, GDK_KEY_dead_iota },
+  { 0xf323, GDK_KEY_dead_belowdot },
+  { 0xf309, GDK_KEY_dead_hook },
+  { 0xf31B, GDK_KEY_dead_horn },
+  { 0xf02d, GDK_KEY_dead_stroke },
+  { 0xf335, GDK_KEY_dead_stroke },
+  { 0xf336, GDK_KEY_dead_stroke },
+  { 0xf313, GDK_KEY_dead_abovecomma },
+  /*  { 0xf313, GDK_KEY_dead_psili }, */
+  { 0xf314, GDK_KEY_dead_abovereversedcomma },
+  /*  { 0xf314, GDK_KEY_dead_dasia }, */
+  { 0xf30F, GDK_KEY_dead_doublegrave },
+  { 0xf325, GDK_KEY_dead_belowring },
+  { 0xf2cd, GDK_KEY_dead_belowmacron },
+  { 0xf331, GDK_KEY_dead_belowmacron },
+  { 0xf32D, GDK_KEY_dead_belowcircumflex },
+  { 0xf330, GDK_KEY_dead_belowtilde },
+  { 0xf32E, GDK_KEY_dead_belowbreve },
+  { 0xf324, GDK_KEY_dead_belowdiaeresis },
+  { 0xf311, GDK_KEY_dead_invertedbreve },
+  { 0xf02c, GDK_KEY_dead_belowcomma },
+  { 0xf326, GDK_KEY_dead_belowcomma }
 };
 
 static void
@@ -330,10 +381,10 @@
 		  UniChar uc;
 		  
 		  key_code = modifiers[j] | i;
-		  err = UCKeyTranslate (chr_data, i, kUCKeyActionDown,
+		  err = UCKeyTranslate (chr_data, i, kUCKeyActionDisplay,
 		                        (modifiers[j] >> 8) & 0xFF,
 		                        LMGetKbdType(),
-		                        kUCKeyTranslateNoDeadKeysMask,
+		                        0,
 		                        &state, 4, &nChars, chars);
 
 
@@ -346,7 +397,21 @@
 		      int k;
 		      gboolean found = FALSE;
 		      
-		      uc = chars[0];
+		      /* A few <Shift><Option>keys return two
+		       * characters, the first of which is U+00a0,
+		       * which isn't interesting; so we return the
+		       * second. More sophisticated handling is the
+		       * job of a GtkIMContext.
+		       
+		       * If state isn't zero, it means that it's a
+		       * dead key of some sort. Some of those are
+		       * enumerated in the special_ucs_table with the
+		       * high nibble set to f to push it into the
+		       * private use range. Here we do the same.
+		       */
+		      if (state != 0)
+			  chars[nChars - 1] |= 0xf000;
+		      uc = chars[nChars - 1];
 
 		      for (k = 0; k < G_N_ELEMENTS (special_ucs_table); k++) 
 			{
