From cd4f325ee7a3a64eb986931a0575e5f1c3c587c3 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 22 Feb 2008 10:38:14 -0500 Subject: [PATCH] Let ObPrompts be modal dialogs, and when they are transient for a window, make it transient for its entire group, so it can be stacked at the highest level above other transients --- openbox/client.c | 2 +- openbox/prompt.c | 32 +++++++++++++++++++++++++++++--- openbox/prompt.h | 2 +- openbox/prop.c | 1 + openbox/prop.h | 1 + 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/openbox/client.c b/openbox/client.c index 9fa311cf..32daf663 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -3442,7 +3442,7 @@ static void client_prompt_kill(ObClient *self) g_free(m); } - prompt_show(self->kill_prompt, self); + prompt_show(self->kill_prompt, self, TRUE); } void client_kill(ObClient *self) diff --git a/openbox/prompt.c b/openbox/prompt.c index 84fe2d0d..d3a1ab7b 100644 --- a/openbox/prompt.c +++ b/openbox/prompt.c @@ -21,6 +21,7 @@ #include "screen.h" #include "openbox.h" #include "client.h" +#include "group.h" #include "prop.h" #include "modkeys.h" #include "event.h" @@ -435,7 +436,7 @@ static void render_all(ObPrompt *self) render_button(self, &self->button[i]); } -void prompt_show(ObPrompt *self, ObClient *parent) +void prompt_show(ObPrompt *self, ObClient *parent, gboolean modal) { gint i; @@ -457,8 +458,33 @@ void prompt_show(ObPrompt *self, ObClient *parent) break; } - XSetTransientForHint(ob_display, self->super.window, - (parent ? parent->window : 0)); + if (parent) { + Atom states[1]; + gint nstates; + Window p; + XWMHints h; + + if (parent->group) { + /* make it transient for the window's group */ + h.flags = WindowGroupHint; + h.window_group = parent->group->leader; + p = RootWindow(ob_display, ob_screen); + } + else { + /* make it transient for the window directly */ + h.flags = 0; + p = parent->window; + } + + XSetWMHints(ob_display, self->super.window, &h); + PROP_SET32(self->super.window, wm_transient_for, window, p); + + states[0] = prop_atoms.net_wm_state_modal; + nstates = (modal ? 1 : 0); + PROP_SETA32(self->super.window, net_wm_state, atom, states, nstates); + } + else + PROP_ERASE(self->super.window, wm_transient_for); /* set up the dialog and render it */ prompt_layout(self); diff --git a/openbox/prompt.h b/openbox/prompt.h index c24f0448..89d3d598 100644 --- a/openbox/prompt.h +++ b/openbox/prompt.h @@ -100,7 +100,7 @@ void prompt_ref(ObPrompt *self); void prompt_unref(ObPrompt *self); /*! Show the prompt. It will be centered within the given area rectangle */ -void prompt_show(ObPrompt *self, struct _ObClient *parent); +void prompt_show(ObPrompt *self, struct _ObClient *parent, gboolean modal); void prompt_hide(ObPrompt *self); gboolean prompt_key_event(ObPrompt *self, XEvent *e); diff --git a/openbox/prop.c b/openbox/prop.c index 695e441f..5dc4a2fa 100644 --- a/openbox/prop.c +++ b/openbox/prop.c @@ -51,6 +51,7 @@ void prop_startup(void) CREATE(wm_client_machine, "WM_CLIENT_MACHINE"); CREATE(wm_command, "WM_COMMAND"); CREATE(wm_client_leader, "WM_CLIENT_LEADER"); + CREATE(wm_transient_for, "WM_TRANSIENT_FOR"); CREATE(motif_wm_hints, "_MOTIF_WM_HINTS"); CREATE(sm_client_id, "SM_CLIENT_ID"); diff --git a/openbox/prop.h b/openbox/prop.h index ae423271..46c93017 100644 --- a/openbox/prop.h +++ b/openbox/prop.h @@ -53,6 +53,7 @@ typedef struct Atoms { Atom wm_client_machine; Atom wm_command; Atom wm_client_leader; + Atom wm_transient_for; Atom motif_wm_hints; /* SM atoms */ -- 2.45.2