mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 12:02:04 +00:00
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
This commit is contained in:
parent
bb1ab0afd9
commit
66105c6e7e
@ -140,7 +140,10 @@ typedef struct
|
|||||||
GList *usable_screen_region;
|
GList *usable_screen_region;
|
||||||
GList *usable_monitor_region;
|
GList *usable_monitor_region;
|
||||||
} ConstraintInfo;
|
} ConstraintInfo;
|
||||||
|
static gboolean constrain_modal_dialog (MetaWindow *window,
|
||||||
|
ConstraintInfo *info,
|
||||||
|
ConstraintPriority priority,
|
||||||
|
gboolean check_only);
|
||||||
static gboolean constrain_maximization (MetaWindow *window,
|
static gboolean constrain_maximization (MetaWindow *window,
|
||||||
ConstraintInfo *info,
|
ConstraintInfo *info,
|
||||||
ConstraintPriority priority,
|
ConstraintPriority priority,
|
||||||
@ -210,6 +213,7 @@ typedef struct {
|
|||||||
} Constraint;
|
} Constraint;
|
||||||
|
|
||||||
static const Constraint all_constraints[] = {
|
static const Constraint all_constraints[] = {
|
||||||
|
{constrain_modal_dialog, "constrain_modal_dialog"},
|
||||||
{constrain_maximization, "constrain_maximization"},
|
{constrain_maximization, "constrain_maximization"},
|
||||||
{constrain_fullscreen, "constrain_fullscreen"},
|
{constrain_fullscreen, "constrain_fullscreen"},
|
||||||
{constrain_size_increments, "constrain_size_increments"},
|
{constrain_size_increments, "constrain_size_increments"},
|
||||||
@ -726,6 +730,48 @@ get_size_limits (const MetaWindow *window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
constrain_modal_dialog (MetaWindow *window,
|
||||||
|
ConstraintInfo *info,
|
||||||
|
ConstraintPriority priority,
|
||||||
|
gboolean check_only)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||||
|
gboolean constraint_already_satisfied;
|
||||||
|
|
||||||
|
if (!meta_prefs_get_attach_modal_dialogs ())
|
||||||
|
return TRUE;
|
||||||
|
if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
x = parent->rect.x + (parent->rect.width / 2 - info->current.width / 2);
|
||||||
|
y = 0;
|
||||||
|
if (parent->frame)
|
||||||
|
{
|
||||||
|
MetaFrameGeometry fgeom;
|
||||||
|
|
||||||
|
x += parent->frame->rect.x;
|
||||||
|
y += parent->frame->rect.y;
|
||||||
|
|
||||||
|
meta_frame_calc_geometry (parent->frame, &fgeom);
|
||||||
|
y += fgeom.top_height;
|
||||||
|
|
||||||
|
y += info->fgeom->top_height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
y = parent->rect.y + info->fgeom->top_height;
|
||||||
|
|
||||||
|
constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
|
||||||
|
|
||||||
|
if (check_only || constraint_already_satisfied)
|
||||||
|
return constraint_already_satisfied;
|
||||||
|
|
||||||
|
info->current.y = y;
|
||||||
|
info->current.x = x;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
constrain_maximization (MetaWindow *window,
|
constrain_maximization (MetaWindow *window,
|
||||||
ConstraintInfo *info,
|
ConstraintInfo *info,
|
||||||
|
@ -5192,6 +5192,34 @@ prefs_changed_callback (MetaPreference pref,
|
|||||||
else
|
else
|
||||||
disable_compositor (display);
|
disable_compositor (display);
|
||||||
}
|
}
|
||||||
|
else if (pref == META_PREF_ATTACH_MODAL_DIALOGS)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = data;
|
||||||
|
GSList *windows;
|
||||||
|
GSList *tmp;
|
||||||
|
|
||||||
|
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
||||||
|
|
||||||
|
for (tmp = windows; tmp != NULL; tmp = tmp->next)
|
||||||
|
{
|
||||||
|
MetaWindow *w = tmp->data;
|
||||||
|
MetaWindow *parent = meta_window_get_transient_for (w);
|
||||||
|
meta_window_recalc_features (w);
|
||||||
|
|
||||||
|
if (w->type == META_WINDOW_MODAL_DIALOG && parent && parent != w)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
/* Forcing a call to move_resize() does two things: first, it handles
|
||||||
|
* resizing the dialog frame window to the correct size when we remove
|
||||||
|
* or add the decorations. Second, it will take care of positioning the
|
||||||
|
* dialog as "attached" to the parent when we turn the preference on
|
||||||
|
* via the constrain_modal_dialog() constraint.
|
||||||
|
**/
|
||||||
|
meta_window_get_position (w, &x, &y);
|
||||||
|
meta_window_move (w, FALSE, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -276,7 +276,7 @@ meta_frame_get_flags (MetaFrame *frame)
|
|||||||
if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
|
if (META_WINDOW_ALLOWS_VERTICAL_RESIZE (frame->window))
|
||||||
flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
|
flags |= META_FRAME_ALLOWS_VERTICAL_RESIZE;
|
||||||
|
|
||||||
if (frame->window->has_focus)
|
if (meta_window_appears_focused (frame->window))
|
||||||
flags |= META_FRAME_HAS_FOCUS;
|
flags |= META_FRAME_HAS_FOCUS;
|
||||||
|
|
||||||
if (frame->window->shaded)
|
if (frame->window->shaded)
|
||||||
|
@ -86,6 +86,7 @@ static MetaVirtualModifier mouse_button_mods = Mod1Mask;
|
|||||||
static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
|
static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
|
||||||
static MetaFocusNewWindows focus_new_windows = META_FOCUS_NEW_WINDOWS_SMART;
|
static MetaFocusNewWindows focus_new_windows = META_FOCUS_NEW_WINDOWS_SMART;
|
||||||
static gboolean raise_on_click = TRUE;
|
static gboolean raise_on_click = TRUE;
|
||||||
|
static gboolean attach_modal_dialogs = FALSE;
|
||||||
static char* current_theme = NULL;
|
static char* current_theme = NULL;
|
||||||
static int num_workspaces = 4;
|
static int num_workspaces = 4;
|
||||||
static MetaActionTitlebar action_double_click_titlebar = META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE;
|
static MetaActionTitlebar action_double_click_titlebar = META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE;
|
||||||
@ -361,6 +362,11 @@ static MetaEnumPreference preferences_enum[] =
|
|||||||
|
|
||||||
static MetaBoolPreference preferences_bool[] =
|
static MetaBoolPreference preferences_bool[] =
|
||||||
{
|
{
|
||||||
|
{ "/apps/mutter/general/attach_modal_dialogs",
|
||||||
|
META_PREF_ATTACH_MODAL_DIALOGS,
|
||||||
|
&attach_modal_dialogs,
|
||||||
|
TRUE,
|
||||||
|
},
|
||||||
{ "/apps/metacity/general/raise_on_click",
|
{ "/apps/metacity/general/raise_on_click",
|
||||||
META_PREF_RAISE_ON_CLICK,
|
META_PREF_RAISE_ON_CLICK,
|
||||||
&raise_on_click,
|
&raise_on_click,
|
||||||
@ -1493,6 +1499,12 @@ meta_prefs_get_focus_new_windows (void)
|
|||||||
return focus_new_windows;
|
return focus_new_windows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_prefs_get_attach_modal_dialogs (void)
|
||||||
|
{
|
||||||
|
return attach_modal_dialogs;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_prefs_get_raise_on_click (void)
|
meta_prefs_get_raise_on_click (void)
|
||||||
{
|
{
|
||||||
@ -1914,6 +1926,9 @@ meta_preference_to_string (MetaPreference pref)
|
|||||||
case META_PREF_FOCUS_NEW_WINDOWS:
|
case META_PREF_FOCUS_NEW_WINDOWS:
|
||||||
return "FOCUS_NEW_WINDOWS";
|
return "FOCUS_NEW_WINDOWS";
|
||||||
|
|
||||||
|
case META_PREF_ATTACH_MODAL_DIALOGS:
|
||||||
|
return "ATTACH_MODAL_DIALOGS";
|
||||||
|
|
||||||
case META_PREF_RAISE_ON_CLICK:
|
case META_PREF_RAISE_ON_CLICK:
|
||||||
return "RAISE_ON_CLICK";
|
return "RAISE_ON_CLICK";
|
||||||
|
|
||||||
|
@ -442,6 +442,8 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
|
|||||||
unsigned long left,
|
unsigned long left,
|
||||||
unsigned long right);
|
unsigned long right);
|
||||||
|
|
||||||
|
gboolean meta_window_appears_focused (MetaWindow *window);
|
||||||
|
|
||||||
/* args to move are window pos, not frame pos */
|
/* args to move are window pos, not frame pos */
|
||||||
void meta_window_move (MetaWindow *window,
|
void meta_window_move (MetaWindow *window,
|
||||||
gboolean user_op,
|
gboolean user_op,
|
||||||
|
@ -3779,6 +3779,19 @@ send_sync_request (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
move_attached_dialog (MetaWindow *window,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||||
|
|
||||||
|
if (window->type == META_WINDOW_MODAL_DIALOG && parent && parent != window)
|
||||||
|
/* It ignores x,y for such a dialog */
|
||||||
|
meta_window_move (window, FALSE, 0, 0);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_move_resize_internal (MetaWindow *window,
|
meta_window_move_resize_internal (MetaWindow *window,
|
||||||
MetaMoveResizeFlags flags,
|
MetaMoveResizeFlags flags,
|
||||||
@ -4235,6 +4248,9 @@ meta_window_move_resize_internal (MetaWindow *window,
|
|||||||
* server-side size/pos of window->xwindow and frame->xwindow
|
* server-side size/pos of window->xwindow and frame->xwindow
|
||||||
* b) all constraints are obeyed by window->rect and frame->rect
|
* b) all constraints are obeyed by window->rect and frame->rect
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (meta_prefs_get_attach_modal_dialogs ())
|
||||||
|
meta_window_foreach_transient (window, move_attached_dialog, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -5839,6 +5855,22 @@ meta_window_client_message (MetaWindow *window,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_ancestor_focus_appearance (MetaWindow *window)
|
||||||
|
{
|
||||||
|
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||||
|
|
||||||
|
if (!meta_prefs_get_attach_modal_dialogs ())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
|
||||||
|
return;
|
||||||
|
if (parent->frame)
|
||||||
|
meta_frame_queue_draw (parent->frame);
|
||||||
|
|
||||||
|
check_ancestor_focus_appearance (parent);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_window_notify_focus (MetaWindow *window,
|
meta_window_notify_focus (MetaWindow *window,
|
||||||
XEvent *event)
|
XEvent *event)
|
||||||
@ -5981,6 +6013,9 @@ meta_window_notify_focus (MetaWindow *window,
|
|||||||
!meta_prefs_get_raise_on_click())
|
!meta_prefs_get_raise_on_click())
|
||||||
meta_display_ungrab_focus_window_button (window->display, window);
|
meta_display_ungrab_focus_window_button (window->display, window);
|
||||||
|
|
||||||
|
/* parent window become active. */
|
||||||
|
check_ancestor_focus_appearance (window);
|
||||||
|
|
||||||
g_signal_emit (window, window_signals[FOCUS], 0);
|
g_signal_emit (window, window_signals[FOCUS], 0);
|
||||||
g_object_notify (G_OBJECT (window->display), "focus-window");
|
g_object_notify (G_OBJECT (window->display), "focus-window");
|
||||||
}
|
}
|
||||||
@ -6010,6 +6045,9 @@ meta_window_notify_focus (MetaWindow *window,
|
|||||||
window->display->focus_window = NULL;
|
window->display->focus_window = NULL;
|
||||||
g_object_notify (G_OBJECT (window->display), "focus-window");
|
g_object_notify (G_OBJECT (window->display), "focus-window");
|
||||||
window->has_focus = FALSE;
|
window->has_focus = FALSE;
|
||||||
|
/* parent window become inactive. */
|
||||||
|
check_ancestor_focus_appearance (window);
|
||||||
|
|
||||||
if (window->frame)
|
if (window->frame)
|
||||||
meta_frame_queue_draw (window->frame);
|
meta_frame_queue_draw (window->frame);
|
||||||
|
|
||||||
@ -6930,6 +6968,16 @@ recalc_window_features (MetaWindow *window)
|
|||||||
if (window->type == META_WINDOW_TOOLBAR)
|
if (window->type == META_WINDOW_TOOLBAR)
|
||||||
window->decorated = FALSE;
|
window->decorated = FALSE;
|
||||||
|
|
||||||
|
if (window->type == META_WINDOW_MODAL_DIALOG && meta_prefs_get_attach_modal_dialogs ())
|
||||||
|
{
|
||||||
|
MetaWindow *parent = meta_window_get_transient_for (window);
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
window->has_resize_func = FALSE;
|
||||||
|
window->border_only = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (window->type == META_WINDOW_DESKTOP ||
|
if (window->type == META_WINDOW_DESKTOP ||
|
||||||
window->type == META_WINDOW_DOCK ||
|
window->type == META_WINDOW_DOCK ||
|
||||||
window->override_redirect)
|
window->override_redirect)
|
||||||
@ -8854,6 +8902,28 @@ meta_window_get_frame (MetaWindow *window)
|
|||||||
return window->frame;
|
return window->frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
transient_has_focus (MetaWindow *window,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
if (window->type == META_WINDOW_MODAL_DIALOG && meta_window_appears_focused (window))
|
||||||
|
*((gboolean *)data) = TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_window_appears_focused (MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (!window->has_focus && meta_prefs_get_attach_modal_dialogs ())
|
||||||
|
{
|
||||||
|
gboolean focus = FALSE;
|
||||||
|
meta_window_foreach_transient (window, transient_has_focus, &focus);
|
||||||
|
return focus;
|
||||||
|
}
|
||||||
|
return window->has_focus;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_window_has_focus (MetaWindow *window)
|
meta_window_has_focus (MetaWindow *window)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,7 @@ typedef enum
|
|||||||
META_PREF_MOUSE_BUTTON_MODS,
|
META_PREF_MOUSE_BUTTON_MODS,
|
||||||
META_PREF_FOCUS_MODE,
|
META_PREF_FOCUS_MODE,
|
||||||
META_PREF_FOCUS_NEW_WINDOWS,
|
META_PREF_FOCUS_NEW_WINDOWS,
|
||||||
|
META_PREF_ATTACH_MODAL_DIALOGS,
|
||||||
META_PREF_RAISE_ON_CLICK,
|
META_PREF_RAISE_ON_CLICK,
|
||||||
META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
|
META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
|
||||||
META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
|
META_PREF_ACTION_MIDDLE_CLICK_TITLEBAR,
|
||||||
@ -85,6 +86,7 @@ guint meta_prefs_get_mouse_button_resize (void);
|
|||||||
guint meta_prefs_get_mouse_button_menu (void);
|
guint meta_prefs_get_mouse_button_menu (void);
|
||||||
MetaFocusMode meta_prefs_get_focus_mode (void);
|
MetaFocusMode meta_prefs_get_focus_mode (void);
|
||||||
MetaFocusNewWindows meta_prefs_get_focus_new_windows (void);
|
MetaFocusNewWindows meta_prefs_get_focus_new_windows (void);
|
||||||
|
gboolean meta_prefs_get_attach_modal_dialogs (void);
|
||||||
gboolean meta_prefs_get_raise_on_click (void);
|
gboolean meta_prefs_get_raise_on_click (void);
|
||||||
const char* meta_prefs_get_theme (void);
|
const char* meta_prefs_get_theme (void);
|
||||||
/* returns NULL if GTK default should be used */
|
/* returns NULL if GTK default should be used */
|
||||||
|
@ -37,6 +37,22 @@
|
|||||||
</locale>
|
</locale>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
||||||
|
<schema>
|
||||||
|
<key>/schemas/apps/mutter/general/attach_modal_dialogs</key>
|
||||||
|
<applyto>/apps/mutter/general/attach_modal_dialogs</applyto>
|
||||||
|
<owner>mutter</owner>
|
||||||
|
<type>bool</type>
|
||||||
|
<default>false</default>
|
||||||
|
<locale name="C">
|
||||||
|
<short>Attach modal dialogs</short>
|
||||||
|
<long>
|
||||||
|
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.
|
||||||
|
</long>
|
||||||
|
</locale>
|
||||||
|
</schema>
|
||||||
|
|
||||||
<schema>
|
<schema>
|
||||||
<key>/schemas/apps/mutter/general/live_hidden_windows</key>
|
<key>/schemas/apps/mutter/general/live_hidden_windows</key>
|
||||||
<applyto>/apps/mutter/general/live_hidden_windows</applyto>
|
<applyto>/apps/mutter/general/live_hidden_windows</applyto>
|
||||||
|
Loading…
Reference in New Issue
Block a user