mirror of
https://github.com/brl/mutter.git
synced 2024-11-12 17:27:03 -05:00
window: add an appears-focused property, redraw shadows when it changes
We need to redraw a window's shadow any time the value of meta_window_appears_focused() changes. So make that into a property so we can get notifications on it. https://bugzilla.gnome.org/show_bug.cgi?id=636904
This commit is contained in:
parent
db055c6029
commit
f464b85ffc
@ -373,6 +373,14 @@ window_decorated_notify (MetaWindow *mw,
|
|||||||
meta_window_actor_constructed (G_OBJECT (self));
|
meta_window_actor_constructed (G_OBJECT (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_appears_focused_notify (MetaWindow *mw,
|
||||||
|
GParamSpec *arg1,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (data));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_actor_constructed (GObject *object)
|
meta_window_actor_constructed (GObject *object)
|
||||||
{
|
{
|
||||||
@ -422,6 +430,8 @@ meta_window_actor_constructed (GObject *object)
|
|||||||
|
|
||||||
g_signal_connect (priv->window, "notify::decorated",
|
g_signal_connect (priv->window, "notify::decorated",
|
||||||
G_CALLBACK (window_decorated_notify), self);
|
G_CALLBACK (window_decorated_notify), self);
|
||||||
|
g_signal_connect (priv->window, "notify::appears-focused",
|
||||||
|
G_CALLBACK (window_appears_focused_notify), self);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -253,11 +253,9 @@ struct _MetaWindow
|
|||||||
/* EWHH demands attention flag */
|
/* EWHH demands attention flag */
|
||||||
guint wm_state_demands_attention : 1;
|
guint wm_state_demands_attention : 1;
|
||||||
|
|
||||||
/* this flag tracks receipt of focus_in focus_out and
|
/* this flag tracks receipt of focus_in focus_out */
|
||||||
* determines whether we draw the focus
|
|
||||||
*/
|
|
||||||
guint has_focus : 1;
|
guint has_focus : 1;
|
||||||
|
|
||||||
/* Have we placed this window? */
|
/* Have we placed this window? */
|
||||||
guint placed : 1;
|
guint placed : 1;
|
||||||
|
|
||||||
@ -389,6 +387,9 @@ struct _MetaWindow
|
|||||||
MetaGroup *group;
|
MetaGroup *group;
|
||||||
|
|
||||||
GObject *compositor_private;
|
GObject *compositor_private;
|
||||||
|
|
||||||
|
/* Focused window that is (directly or indirectly) attached to this one */
|
||||||
|
MetaWindow *attached_focus_window;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaWindowClass
|
struct _MetaWindowClass
|
||||||
@ -634,4 +635,7 @@ void meta_window_update_net_wm_type (MetaWindow *window);
|
|||||||
void meta_window_update_monitor (MetaWindow *window);
|
void meta_window_update_monitor (MetaWindow *window);
|
||||||
void meta_window_update_on_all_workspaces (MetaWindow *window);
|
void meta_window_update_on_all_workspaces (MetaWindow *window);
|
||||||
|
|
||||||
|
void meta_window_propagate_focus_appearance (MetaWindow *window,
|
||||||
|
gboolean focused);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1466,6 +1466,9 @@ reload_transient_for (MetaWindow *window,
|
|||||||
MetaPropValue *value,
|
MetaPropValue *value,
|
||||||
gboolean initial)
|
gboolean initial)
|
||||||
{
|
{
|
||||||
|
if (window->has_focus && window->xtransient_for != None)
|
||||||
|
meta_window_propagate_focus_appearance (window, FALSE);
|
||||||
|
|
||||||
window->xtransient_for = None;
|
window->xtransient_for = None;
|
||||||
|
|
||||||
if (value->type != META_PROP_VALUE_INVALID)
|
if (value->type != META_PROP_VALUE_INVALID)
|
||||||
@ -1509,6 +1512,9 @@ reload_transient_for (MetaWindow *window,
|
|||||||
|
|
||||||
if (!window->constructing && !window->override_redirect)
|
if (!window->constructing && !window->override_redirect)
|
||||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
||||||
|
|
||||||
|
if (window->has_focus && window->xtransient_for != None)
|
||||||
|
meta_window_propagate_focus_appearance (window, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,7 +154,8 @@ enum {
|
|||||||
PROP_USER_TIME,
|
PROP_USER_TIME,
|
||||||
PROP_DEMANDS_ATTENTION,
|
PROP_DEMANDS_ATTENTION,
|
||||||
PROP_URGENT,
|
PROP_URGENT,
|
||||||
PROP_MUTTER_HINTS
|
PROP_MUTTER_HINTS,
|
||||||
|
PROP_APPEARS_FOCUSED
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -239,6 +240,9 @@ meta_window_get_property(GObject *object,
|
|||||||
case PROP_MUTTER_HINTS:
|
case PROP_MUTTER_HINTS:
|
||||||
g_value_set_string (value, win->mutter_hints);
|
g_value_set_string (value, win->mutter_hints);
|
||||||
break;
|
break;
|
||||||
|
case PROP_APPEARS_FOCUSED:
|
||||||
|
g_value_set_boolean (value, meta_window_appears_focused (win));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -366,6 +370,14 @@ meta_window_class_init (MetaWindowClass *klass)
|
|||||||
"Contents of the _MUTTER_HINTS property of this window",
|
"Contents of the _MUTTER_HINTS property of this window",
|
||||||
NULL,
|
NULL,
|
||||||
G_PARAM_READABLE));
|
G_PARAM_READABLE));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_APPEARS_FOCUSED,
|
||||||
|
g_param_spec_boolean ("appears-focused",
|
||||||
|
"Appears focused",
|
||||||
|
"Whether the window is drawn as being focused",
|
||||||
|
FALSE,
|
||||||
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
window_signals[WORKSPACE_CHANGED] =
|
window_signals[WORKSPACE_CHANGED] =
|
||||||
g_signal_new ("workspace-changed",
|
g_signal_new ("workspace-changed",
|
||||||
G_TYPE_FROM_CLASS (object_class),
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
@ -856,6 +868,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
|
|||||||
|
|
||||||
window->frame = NULL;
|
window->frame = NULL;
|
||||||
window->has_focus = FALSE;
|
window->has_focus = FALSE;
|
||||||
|
window->attached_focus_window = NULL;
|
||||||
|
|
||||||
window->maximized_horizontally = FALSE;
|
window->maximized_horizontally = FALSE;
|
||||||
window->maximized_vertically = FALSE;
|
window->maximized_vertically = FALSE;
|
||||||
@ -1488,6 +1501,7 @@ meta_window_unmanage (MetaWindow *window,
|
|||||||
meta_workspace_focus_default_window (window->screen->active_workspace,
|
meta_workspace_focus_default_window (window->screen->active_workspace,
|
||||||
window,
|
window,
|
||||||
timestamp);
|
timestamp);
|
||||||
|
meta_window_propagate_focus_appearance (window, FALSE);
|
||||||
}
|
}
|
||||||
else if (window->display->expected_focus_window == window)
|
else if (window->display->expected_focus_window == window)
|
||||||
{
|
{
|
||||||
@ -6359,20 +6373,46 @@ meta_window_client_message (MetaWindow *window,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
check_ancestor_focus_appearance (MetaWindow *window)
|
meta_window_propagate_focus_appearance (MetaWindow *window,
|
||||||
|
gboolean focused)
|
||||||
{
|
{
|
||||||
MetaWindow *parent = meta_window_get_transient_for (window);
|
MetaWindow *child, *parent;
|
||||||
|
|
||||||
if (!meta_prefs_get_attach_modal_dialogs ())
|
if (!meta_prefs_get_attach_modal_dialogs ())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
|
child = window;
|
||||||
return;
|
parent = meta_window_get_transient_for (child);
|
||||||
if (parent->frame)
|
while (child->type == META_WINDOW_MODAL_DIALOG && parent)
|
||||||
meta_frame_queue_draw (parent->frame);
|
{
|
||||||
|
gboolean child_focus_state_changed;
|
||||||
|
|
||||||
check_ancestor_focus_appearance (parent);
|
if (focused)
|
||||||
|
{
|
||||||
|
if (parent->attached_focus_window == window)
|
||||||
|
break;
|
||||||
|
child_focus_state_changed = (parent->attached_focus_window == NULL);
|
||||||
|
parent->attached_focus_window = window;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (parent->attached_focus_window != window)
|
||||||
|
break;
|
||||||
|
child_focus_state_changed = (parent->attached_focus_window != NULL);
|
||||||
|
parent->attached_focus_window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child_focus_state_changed && !parent->has_focus)
|
||||||
|
{
|
||||||
|
g_object_notify (G_OBJECT (parent), "appears-focused");
|
||||||
|
if (parent->frame)
|
||||||
|
meta_frame_queue_draw (parent->frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
child = parent;
|
||||||
|
parent = meta_window_get_transient_for (child);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -6517,11 +6557,16 @@ 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");
|
||||||
|
|
||||||
|
if (!window->attached_focus_window)
|
||||||
|
{
|
||||||
|
g_object_notify (G_OBJECT (window), "appears-focused");
|
||||||
|
if (window->frame)
|
||||||
|
meta_frame_queue_draw (window->frame);
|
||||||
|
}
|
||||||
|
meta_window_propagate_focus_appearance (window, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event->type == FocusOut ||
|
else if (event->type == FocusOut ||
|
||||||
@ -6549,11 +6594,14 @@ 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->attached_focus_window)
|
||||||
meta_frame_queue_draw (window->frame);
|
{
|
||||||
|
g_object_notify (G_OBJECT (window), "appears-focused");
|
||||||
|
if (window->frame)
|
||||||
|
meta_frame_queue_draw (window->frame);
|
||||||
|
}
|
||||||
|
meta_window_propagate_focus_appearance (window, FALSE);
|
||||||
|
|
||||||
meta_error_trap_push (window->display);
|
meta_error_trap_push (window->display);
|
||||||
XUninstallColormap (window->display->xdisplay,
|
XUninstallColormap (window->display->xdisplay,
|
||||||
@ -9692,16 +9740,6 @@ 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_window_appears_focused:
|
* meta_window_appears_focused:
|
||||||
* @window: a #MetaWindow
|
* @window: a #MetaWindow
|
||||||
@ -9715,16 +9753,7 @@ transient_has_focus (MetaWindow *window,
|
|||||||
gboolean
|
gboolean
|
||||||
meta_window_appears_focused (MetaWindow *window)
|
meta_window_appears_focused (MetaWindow *window)
|
||||||
{
|
{
|
||||||
/* FIXME: meta_window_foreach_transient() iterates over all windows; we
|
return window->has_focus || (window->attached_focus_window != NULL);
|
||||||
* should eat the complexity to cache a bit for this.
|
|
||||||
*/
|
|
||||||
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
|
||||||
|
Loading…
Reference in New Issue
Block a user