emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 2ff5763836: Prevent crashes when embedding Emacs in a nonexistent


From: Po Lu
Subject: master 2ff5763836: Prevent crashes when embedding Emacs in a nonexistent parent
Date: Fri, 2 Sep 2022 05:20:03 -0400 (EDT)

branch: master
commit 2ff57638365411904e76979ef628534098ce3549
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Prevent crashes when embedding Emacs in a nonexistent parent
    
    * src/xfns.c (x_window, Fx_create_frame): Handle X errors while
    trying to reparent the frame onto an explicitly specified
    parent.
    * src/xterm.c (handle_one_xevent): Handle unparenting embedded
    windows correctly.  This only works if the embedder is aware of
    the fixes extension and has put the window into the right save
    set.
    (x_embed_frame): New function.
    * src/xterm.h (FRAME_X_EMBEDDED_P): Fix coding style.
---
 src/xfns.c  | 12 +++++++-----
 src/xterm.c | 39 +++++++++++++++++++++++++++++++++++++++
 src/xterm.h |  4 ++--
 3 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/src/xfns.c b/src/xfns.c
index 0b1f707e9f..2da1e7bcf8 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3955,10 +3955,6 @@ x_window (struct frame *f, long window_prompting)
   XtManageChild (pane_widget);
   XtRealizeWidget (shell_widget);
 
-  if (FRAME_X_EMBEDDED_P (f))
-    XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget),
-                    f->output_data.x->parent_desc, 0, 0);
-
   FRAME_X_WINDOW (f) = XtWindow (frame_widget);
   initial_set_up_x_back_buffer (f);
   validate_x_resource_name ();
@@ -4132,7 +4128,7 @@ x_window (struct frame *f)
   block_input ();
   FRAME_X_WINDOW (f)
     = XCreateWindow (FRAME_X_DISPLAY (f),
-                    f->output_data.x->parent_desc,
+                    FRAME_DISPLAY_INFO (f)->root_window,
                     f->left_pos,
                     f->top_pos,
                     FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
@@ -4958,6 +4954,12 @@ This function is an internal primitive--use `make-frame' 
instead.  */)
   x_window (f);
 #endif
 
+#ifndef USE_GTK
+  if (FRAME_X_EMBEDDED_P (f)
+      && !x_embed_frame (dpyinfo, f))
+    error ("The frame could not be embedded; does the embedder exist?");
+#endif
+
   x_icon (f, parms);
   x_make_gc (f);
 
diff --git a/src/xterm.c b/src/xterm.c
index 71b84f8174..138fa7ea6c 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -18416,6 +18416,20 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       f = x_top_window_to_frame (dpyinfo, event->xreparent.window);
       if (f)
         {
+#ifndef USE_GTK
+         if (FRAME_OUTPUT_DATA (f)->parent_desc
+             && FRAME_X_EMBEDDED_P (f))
+           {
+             /* The frame's embedder was destroyed; mark the frame as
+                no longer embedded, and map the frame.  An
+                UnmapNotify event must have previously been received
+                during the start of save-set processing.  */
+
+             FRAME_X_OUTPUT (f)->explicit_parent = false;
+             x_make_frame_visible (f);
+           }
+#endif
+
          /* Maybe we shouldn't set this for child frames ??  */
          f->output_data.x->parent_desc = event->xreparent.parent;
 
@@ -27456,6 +27470,31 @@ x_get_atom_name (struct x_display_info *dpyinfo, Atom 
atom,
   return value;
 }
 
+#ifndef USE_GTK
+
+/* Set up XEmbed for F, and change its save set to handle the parent
+   being destroyed.  */
+
+bool
+x_embed_frame (struct x_display_info *dpyinfo, struct frame *f)
+{
+  bool rc;
+
+  x_catch_errors (dpyinfo->display);
+  /* Catch errors; the target window might no longer exist.  */
+  XReparentWindow (dpyinfo->display, FRAME_OUTER_WINDOW (f),
+                  FRAME_OUTPUT_DATA (f)->parent_desc, 0, 0);
+  rc = x_had_errors_p (dpyinfo->display);
+  x_uncatch_errors_after_check ();
+
+  if (rc)
+    return false;
+
+  return true;
+}
+
+#endif
+
 
 /* Setting window manager hints.  */
 
diff --git a/src/xterm.h b/src/xterm.h
index a0ae3a330a..7c5a889af3 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1209,7 +1209,6 @@ enum
   FOCUS_EXPLICIT = 2
 };
 
-
 /* Return the X output data for frame F.  */
 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
 #define FRAME_OUTPUT_DATA(f) FRAME_X_OUTPUT (f)
@@ -1588,6 +1587,7 @@ extern void x_wm_set_size_hint (struct frame *, long, 
bool);
   && defined HAVE_CLOCK_GETTIME
 extern void x_sync_init_fences (struct frame *);
 #endif
+extern bool x_embed_frame (struct x_display_info *, struct frame *);
 
 extern void x_delete_terminal (struct terminal *);
 extern Cursor x_create_font_cursor (struct x_display_info *, int);
@@ -1827,7 +1827,7 @@ extern void mark_xterm (void);
 
 /* Is the frame embedded into another application? */
 
-#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT(f)->explicit_parent != 0)
+#define FRAME_X_EMBEDDED_P(f) (FRAME_X_OUTPUT (f)->explicit_parent != 0)
 
 #define STORE_NATIVE_RECT(nr,rx,ry,rwidth,rheight)     \
   ((nr).x = (rx),                                      \



reply via email to

[Prev in Thread] Current Thread [Next in Thread]