Fire reparent from plugin
authorBenoit Gschwind <doth.gschwind@gmail.com>
Fri, 22 Feb 2008 19:21:34 +0000 (20:21 +0100)
committerBenoit Gschwind <doth.gschwind@gmail.com>
Fri, 22 Feb 2008 19:21:34 +0000 (20:21 +0100)
engines/default/plugin.c
openbox/client.c

index 33e5b869ffb714d6ea62d21182430baf940e3bfd..168e5f26488c557dd162056645d46e4a4f0ccc7d 100644 (file)
@@ -327,22 +327,6 @@ void frame_grab(gpointer _self, GHashTable * window_map)
      send a mapnotify or we create race conditions.
      */
 
-    /* reparent the client to the frame */
-    XReparentWindow(obp_display, self->client->w_client, self->window, 0, 0);
-
-    /*
-     When reparenting the client window, it is usually not mapped yet, since
-     this occurs from a MapRequest. However, in the case where Openbox is
-     starting up, the window is already mapped, so we'll see an unmap event
-     for it.
-     */
-    if (ob_state() == OB_STATE_STARTING)
-        ++self->client->ignore_unmaps;
-
-    /* select the event mask on the client's parent (to receive config/map
-     req's) the ButtonPress is to catch clicks on the client border */
-    XSelectInput(obp_display, self->window, FRAME_EVENTMASK);
-
     /* set all the windows for the frame in the window_map */
     g_hash_table_insert(window_map, &self->window, self->client);
     g_hash_table_insert(window_map, &self->backback, self->client);
@@ -390,34 +374,6 @@ void frame_grab(gpointer _self, GHashTable * window_map)
 void frame_ungrab(gpointer _self, GHashTable * window_map)
 {
     ObDefaultFrame * self = (ObDefaultFrame *) _self;
-    XEvent ev;
-    gboolean reparent = TRUE;
-
-    /* check if the app has already reparented its window away */
-    while (XCheckTypedWindowEvent(obp_display, self->client->w_client,
-            ReparentNotify, &ev)) {
-        /* This check makes sure we don't catch our own reparent action to
-         our frame window. This doesn't count as the app reparenting itself
-         away of course.
-
-         Reparent events that are generated by us are just discarded here.
-         They are of no consequence to us anyhow.
-         */
-        if (ev.xreparent.parent != self->window) {
-            reparent = FALSE;
-            XPutBackEvent(obp_display, &ev);
-            break;
-        }
-    }
-
-    if (reparent) {
-        /* according to the ICCCM - if the client doesn't reparent itself,
-         then we will reparent the window to root for them */
-        XReparentWindow(obp_display, self->client->w_client, RootWindow(
-                obp_display, obp_screen), self->client_area.x,
-                self->client_area.y);
-    }
-
     /* remove all the windows for the frame from the window_map */
     g_hash_table_remove(window_map, &self->window);
     g_hash_table_remove(window_map, &self->backback);
@@ -460,7 +416,7 @@ void frame_ungrab(gpointer _self, GHashTable * window_map)
     g_hash_table_remove(window_map, &self->rgripright);
     g_hash_table_remove(window_map, &self->rgriptop);
     g_hash_table_remove(window_map, &self->rgripbottom);
-
+    
     obt_main_loop_timeout_remove_data(ob_main_loop, flash_timeout, self,
             TRUE);
 }
index e462c63d130e48be71e345df3ca9f068541b25c2..af27ec9a6c2e7017833dfa785de1f65d07e1850c 100644 (file)
 #define CLIENT_NOPROPAGATEMASK (ButtonPressMask | ButtonReleaseMask | \
                                 ButtonMotionMask)
 
+#define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
+                         ButtonPressMask | ButtonReleaseMask | \
+                         SubstructureRedirectMask | FocusChangeMask)
+
 typedef struct
 {
     ObClientCallback func;
@@ -272,6 +276,22 @@ void client_manage(Window window, ObPrompt *prompt)
     self->w_frame = createWindow(RootWindow(obt_display, ob_screen), visual,
             mask, &attrib);
     self->frame = frame_engine->frame_new(self, self->w_client, self->w_frame);
+    /* reparent the client to the frame */
+    XReparentWindow(obt_display, self->w_client, self->w_frame, 0, 0);
+
+    /*
+     When reparenting the client window, it is usually not mapped yet, since
+     this occurs from a MapRequest. However, in the case where Openbox is
+     starting up, the window is already mapped, so we'll see an unmap event
+     for it.
+     */
+    if (ob_state() == OB_STATE_STARTING)
+        ++self->ignore_unmaps;
+    
+    /* select the event mask on the client's parent (to receive config/map
+     req's) the ButtonPress is to catch clicks on the client border */
+    XSelectInput(obt_display, self->w_frame, FRAME_EVENTMASK);
+    
     frame_engine->frame_grab(self->frame, window_map);
 
     /* we've grabbed everything and set everything that we need to at mapping
@@ -771,7 +791,33 @@ void client_unmanage(ObClient *self)
     }
 
     /* reparent the window out of the frame, and free the frame */
-    frame_engine->frame_ungrab(self->frame, window_map);
+    XEvent ev;
+    gboolean reparent = TRUE;
+    /* check if the app has already reparented its window away */
+    while (XCheckTypedWindowEvent(obt_display, self->w_client,
+            ReparentNotify, &ev)) {
+        /* This check makes sure we don't catch our own reparent action to
+         our frame window. This doesn't count as the app reparenting itself
+         away of course.
+
+         Reparent events that are generated by us are just discarded here.
+         They are of no consequence to us anyhow.
+         */
+        if (ev.xreparent.parent != self->w_frame) {
+            reparent = FALSE;
+            XPutBackEvent(obt_display, &ev);
+            break;
+        }
+    }
+
+    if (reparent) {
+        /* according to the ICCCM - if the client doesn't reparent itself,
+         then we will reparent the window to root for them */
+        XReparentWindow(obt_display, self->w_client, RootWindow(
+                obt_display, ob_screen), self->area.x,
+                self->area.y);
+    }
+    frame_engine->frame_ungrab(self->frame, window_map); 
     frame_engine->frame_free(self->frame);
     self->frame = NULL;