Skip to content

Commit 37fecf4

Browse files
Zaspirevkareh
authored andcommitted
Optionally attach modal dialogs
Add a preference /apps/mutter/general/attach_modal_dialogs. When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window. https://bugzilla.gnome.org/show_bug.cgi?id=612726 NOTE: Patch copied from mutter and adapted for metacity.
1 parent 4f47c5b commit 37fecf4

File tree

8 files changed

+172
-1
lines changed

8 files changed

+172
-1
lines changed

src/core/constraints.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ typedef struct
142142
GList *usable_xinerama_region;
143143
} ConstraintInfo;
144144

145+
static gboolean constrain_modal_dialog (MetaWindow *window,
146+
ConstraintInfo *info,
147+
ConstraintPriority priority,
148+
gboolean check_only);
145149
static gboolean constrain_maximization (MetaWindow *window,
146150
ConstraintInfo *info,
147151
ConstraintPriority priority,
@@ -222,6 +226,7 @@ typedef struct {
222226
} Constraint;
223227

224228
static const Constraint all_constraints[] = {
229+
{constrain_modal_dialog, "constrain_modal_dialog"},
225230
{constrain_maximization, "constrain_maximization"},
226231
{constrain_tiling, "constrain_tiling"},
227232
{constrain_fullscreen, "constrain_fullscreen"},
@@ -783,6 +788,48 @@ get_size_limits (const MetaWindow *window,
783788
}
784789
}
785790

791+
static gboolean
792+
constrain_modal_dialog (MetaWindow *window,
793+
ConstraintInfo *info,
794+
ConstraintPriority priority,
795+
gboolean check_only)
796+
{
797+
int x, y;
798+
MetaWindow *parent = meta_window_get_transient_for (window);
799+
gboolean constraint_already_satisfied;
800+
801+
if (!meta_prefs_get_attach_modal_dialogs ())
802+
return TRUE;
803+
if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
804+
return TRUE;
805+
806+
x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2);
807+
y = 0;
808+
if (parent->frame)
809+
{
810+
MetaFrameGeometry fgeom;
811+
812+
x += parent->frame->rect.x;
813+
y += parent->frame->rect.y;
814+
815+
meta_frame_calc_geometry (parent->frame, &fgeom);
816+
y += fgeom.top_height;
817+
818+
y += info->fgeom->top_height;
819+
}
820+
else
821+
y = parent->rect.y + info->fgeom->top_height;
822+
823+
constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
824+
825+
if (check_only || constraint_already_satisfied)
826+
return constraint_already_satisfied;
827+
828+
info->current.y = y;
829+
info->current.x = x;
830+
return TRUE;
831+
}
832+
786833
static gboolean
787834
constrain_maximization (MetaWindow *window,
788835
ConstraintInfo *info,

src/core/display.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5216,6 +5216,34 @@ prefs_changed_callback (MetaPreference pref,
52165216
else
52175217
disable_compositor (display);
52185218
}
5219+
else if (pref == META_PREF_ATTACH_MODAL_DIALOGS)
5220+
{
5221+
MetaDisplay *display = data;
5222+
GSList *windows;
5223+
GSList *tmp;
5224+
5225+
windows = meta_display_list_windows (display);
5226+
5227+
for (tmp = windows; tmp != NULL; tmp = tmp->next)
5228+
{
5229+
MetaWindow *w = tmp->data;
5230+
MetaWindow *parent = meta_window_get_transient_for (w);
5231+
meta_window_recalc_features (w);
5232+
5233+
if (w->type == META_WINDOW_MODAL_DIALOG && parent && parent != w)
5234+
{
5235+
int x, y;
5236+
/* Forcing a call to move_resize() does two things: first, it handles
5237+
* resizing the dialog frame window to the correct size when we remove
5238+
* or add the decorations. Second, it will take care of positioning the
5239+
* dialog as "attached" to the parent when we turn the preference on
5240+
* via the constrain_modal_dialog() constraint.
5241+
**/
5242+
meta_window_get_position (w, &x, &y);
5243+
meta_window_move (w, FALSE, x, y);
5244+
}
5245+
}
5246+
}
52195247
}
52205248

52215249
void

src/core/frame.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ meta_frame_get_flags (MetaFrame *frame)
266266
if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
267267
flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
268268

269-
if (frame->window->has_focus)
269+
if (meta_window_appears_focused (frame->window))
270270
flags |= META_FRAME_HAS_FOCUS;
271271

272272
if (frame->window->shaded)

src/core/prefs.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ static MetaVirtualModifier mouse_button_mods = Mod1Mask;
9696
static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
9797
static MetaFocusNewWindows focus_new_windows = META_FOCUS_NEW_WINDOWS_SMART;
9898
static gboolean raise_on_click = TRUE;
99+
static gboolean attach_modal_dialogs = FALSE;
99100
static char* current_theme = NULL;
100101
static int num_workspaces = 4;
101102
static MetaWrapStyle wrap_style = META_WRAP_NONE;
@@ -334,6 +335,12 @@ static MetaEnumPreference preferences_enum[] =
334335

335336
static MetaBoolPreference preferences_bool[] =
336337
{
338+
{ "attach-modal-dialogs",
339+
KEY_GENERAL_SCHEMA,
340+
META_PREF_ATTACH_MODAL_DIALOGS,
341+
&attach_modal_dialogs,
342+
TRUE,
343+
},
337344
{ "raise-on-click",
338345
KEY_GENERAL_SCHEMA,
339346
META_PREF_RAISE_ON_CLICK,
@@ -1074,6 +1081,12 @@ meta_prefs_get_focus_new_windows (void)
10741081
return focus_new_windows;
10751082
}
10761083

1084+
gboolean
1085+
meta_prefs_get_attach_modal_dialogs (void)
1086+
{
1087+
return attach_modal_dialogs;
1088+
}
1089+
10771090
gboolean
10781091
meta_prefs_get_raise_on_click (void)
10791092
{
@@ -1536,6 +1549,9 @@ meta_preference_to_string (MetaPreference pref)
15361549
case META_PREF_FOCUS_NEW_WINDOWS:
15371550
return "FOCUS_NEW_WINDOWS";
15381551

1552+
case META_PREF_ATTACH_MODAL_DIALOGS:
1553+
return "ATTACH_MODAL_DIALOGS";
1554+
15391555
case META_PREF_RAISE_ON_CLICK:
15401556
return "RAISE_ON_CLICK";
15411557

src/core/window-private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,8 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
474474
unsigned long left,
475475
unsigned long right);
476476

477+
gboolean meta_window_appears_focused (MetaWindow *window);
478+
477479
/* args to move are window pos, not frame pos */
478480
void meta_window_move (MetaWindow *window,
479481
gboolean user_op,

src/core/window.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3412,6 +3412,19 @@ send_sync_request (MetaWindow *window)
34123412
}
34133413
#endif
34143414

3415+
static gboolean
3416+
move_attached_dialog (MetaWindow *window,
3417+
void *data)
3418+
{
3419+
MetaWindow *parent = meta_window_get_transient_for (window);
3420+
3421+
if (window->type == META_WINDOW_MODAL_DIALOG && parent && parent != window)
3422+
/* It ignores x,y for such a dialog */
3423+
meta_window_move (window, FALSE, 0, 0);
3424+
3425+
return FALSE;
3426+
}
3427+
34153428
static void
34163429
meta_window_move_resize_internal (MetaWindow *window,
34173430
MetaMoveResizeFlags flags,
@@ -3866,6 +3879,9 @@ meta_window_move_resize_internal (MetaWindow *window,
38663879
* server-side size/pos of window->xwindow and frame->xwindow
38673880
* b) all constraints are obeyed by window->rect and frame->rect
38683881
*/
3882+
3883+
if (meta_prefs_get_attach_modal_dialogs ())
3884+
meta_window_foreach_transient (window, move_attached_dialog, NULL);
38693885
}
38703886

38713887
void
@@ -5504,6 +5520,23 @@ meta_window_appears_focused_changed (MetaWindow *window)
55045520
meta_frame_queue_draw (window->frame);
55055521
}
55065522

5523+
static void
5524+
check_ancestor_focus_appearance (MetaWindow *window)
5525+
{
5526+
MetaWindow *parent = meta_window_get_transient_for (window);
5527+
5528+
if (!meta_prefs_get_attach_modal_dialogs ())
5529+
return;
5530+
5531+
if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
5532+
return;
5533+
5534+
if (parent->frame)
5535+
meta_frame_queue_draw (parent->frame);
5536+
5537+
check_ancestor_focus_appearance (parent);
5538+
}
5539+
55075540
gboolean
55085541
meta_window_notify_focus (MetaWindow *window,
55095542
XEvent *event)
@@ -5639,6 +5672,9 @@ meta_window_notify_focus (MetaWindow *window,
56395672
if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK ||
56405673
!meta_prefs_get_raise_on_click())
56415674
meta_display_ungrab_focus_window_button (window->display, window);
5675+
5676+
/* parent window become active. */
5677+
check_ancestor_focus_appearance (window);
56425678
}
56435679
}
56445680
else if (event->type == FocusOut ||
@@ -5666,6 +5702,9 @@ meta_window_notify_focus (MetaWindow *window,
56665702
window->display->focus_window = NULL;
56675703
window->has_focus = FALSE;
56685704

5705+
/* parent window become active. */
5706+
check_ancestor_focus_appearance (window);
5707+
56695708
meta_window_appears_focused_changed (window);
56705709

56715710
meta_compositor_set_active_window (window->display->compositor,
@@ -6472,6 +6511,16 @@ recalc_window_features (MetaWindow *window)
64726511
if (window->type == META_WINDOW_TOOLBAR)
64736512
window->decorated = FALSE;
64746513

6514+
if (window->type == META_WINDOW_MODAL_DIALOG && meta_prefs_get_attach_modal_dialogs ())
6515+
{
6516+
MetaWindow *parent = meta_window_get_transient_for (window);
6517+
if (parent)
6518+
{
6519+
window->has_resize_func = FALSE;
6520+
window->border_only = TRUE;
6521+
}
6522+
}
6523+
64756524
if (window->type == META_WINDOW_DESKTOP ||
64766525
window->type == META_WINDOW_DOCK)
64776526
window->always_sticky = TRUE;
@@ -8594,6 +8643,28 @@ meta_window_get_frame (MetaWindow *window)
85948643
return window->frame;
85958644
}
85968645

8646+
static gboolean
8647+
transient_has_focus (MetaWindow *window,
8648+
void *data)
8649+
{
8650+
if (window->type == META_WINDOW_MODAL_DIALOG && meta_window_appears_focused (window))
8651+
*((gboolean *)data) = TRUE;
8652+
8653+
return FALSE;
8654+
}
8655+
8656+
gboolean
8657+
meta_window_appears_focused (MetaWindow *window)
8658+
{
8659+
if (!window->has_focus && meta_prefs_get_attach_modal_dialogs ())
8660+
{
8661+
gboolean focus = FALSE;
8662+
meta_window_foreach_transient (window, transient_has_focus, &focus);
8663+
return focus;
8664+
}
8665+
return window->has_focus;
8666+
}
8667+
85978668
gboolean
85988669
meta_window_has_focus (MetaWindow *window)
85998670
{

src/include/prefs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef enum
3434
META_PREF_MOUSE_BUTTON_MODS,
3535
META_PREF_FOCUS_MODE,
3636
META_PREF_FOCUS_NEW_WINDOWS,
37+
META_PREF_ATTACH_MODAL_DIALOGS,
3738
META_PREF_RAISE_ON_CLICK,
3839
META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
3940
META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
@@ -87,6 +88,7 @@ guint meta_prefs_get_mouse_button_resize (void);
8788
guint meta_prefs_get_mouse_button_menu (void);
8889
MetaFocusMode meta_prefs_get_focus_mode (void);
8990
MetaFocusNewWindows meta_prefs_get_focus_new_windows (void);
91+
gboolean meta_prefs_get_attach_modal_dialogs (void);
9092
gboolean meta_prefs_get_raise_on_click (void);
9193
const char* meta_prefs_get_theme (void);
9294
/* returns NULL if GTK default should be used */

src/org.mate.marco.gschema.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@
146146
<summary>Visual Bell Type</summary>
147147
<description>Tells Marco how to implement the visual indication that the system bell or another application 'bell' indicator has been rung. Currently there are two valid values, "fullscreen", which causes a fullscreen white-black flash, and "frame_flash" which causes the titlebar of the application which sent the bell signal to flash. If the application which sent the bell is unknown (as is usually the case for the default "system beep"), the currently focused window's titlebar is flashed.</description>
148148
</key>
149+
<key name="attach-modal-dialogs" type="b">
150+
<default>false</default>
151+
<summary>Attach modal dialogs</summary>
152+
<description>When true, instead of having independent titlebars, modal dialogs appear attached to the titlebar of the parent window and are moved together with the parent window.</description>
153+
</key>
149154
<key name="compositing-manager" type="b">
150155
<default>true</default>
151156
<summary>Compositing Manager</summary>

0 commit comments

Comments
 (0)