Merge lp:~cimi/overlay-scrollbar/fix-compiz-stacking into lp:overlay-scrollbar

Proposed by Andrea Cimitan
Status: Merged
Merged at revision: 177
Proposed branch: lp:~cimi/overlay-scrollbar/fix-compiz-stacking
Merge into: lp:overlay-scrollbar
Diff against target: 107 lines (+76/-0)
1 file modified
os/os-scrollbar.c (+76/-0)
To merge this branch: bzr merge lp:~cimi/overlay-scrollbar/fix-compiz-stacking
Reviewer Review Type Date Requested Status
Loïc Molinari (community) Approve
Review via email: mp+54763@code.launchpad.net

Description of the change

this should fix the stacking issues with compiz, we still need to patch metacity to support _NET_RESTACK_WINDOW

To post a comment you must log in.
176. By Andrea Cimitan

renamed XEvent *event to xev

Revision history for this message
Loïc Molinari (loic.molinari) wrote :

Hey Cimi, I've got some question about that one.

Can you please explain why that patch is needed?

Why have you actually chosen to implement it that way?

Isn't that EWMH atom already wrapped as a simple GDK function?

review: Needs Information
Revision history for this message
Loïc Molinari (loic.molinari) wrote :

I think it would be safer to wrap all the XLib code with the GDK X11 error handler (gdk_error_trap_push and gdk_error_trap_pop).

review: Needs Fixing
Revision history for this message
Andrea Cimitan (cimi) wrote :

> Hey Cimi, I've got some question about that one.
>
> Can you please explain why that patch is needed?
>
> Why have you actually chosen to implement it that way?
>
> Isn't that EWMH atom already wrapped as a simple GDK function?

I've decided to implement it in that way, because it's the only one I got it working with compiz :-) sam spilsbury approved it.
Do you have other ideas? Another one I had was to use XQueryTree to get the real parent, but was working for metacity (with bugs) and not for compiz, and was more expensive.

Revision history for this message
Andrea Cimitan (cimi) wrote :

> Isn't that EWMH atom already wrapped as a simple GDK function?

you mean gdk_window_restack?
I've tried with
gdk_window_restack (gtk_widget_get_window (priv->thumb), gtk_widget_get_window (priv->parent), TRUE);

doesn't work with both compiz and metacity

177. By Andrea Cimitan

wrap x11 calls with gdk error trapping code (push, flush, pop)

Revision history for this message
Loïc Molinari (loic.molinari) wrote :

What's currently used in trunk in order to do that and what's the problem?

Revision history for this message
Loïc Molinari (loic.molinari) wrote :

Thanks for the error handling bits.

Note that gdk_flush() is actually a wrapper for XSync(), so that last one is useless there.

Revision history for this message
Andrea Cimitan (cimi) wrote :

> What's currently used in trunk in order to do that and what's the problem?
nothing is used in trunk: the issue is that, if your window is not the focused one (something above it), and you make the thumb appear, the thumb will be above everything.
we need to restack the thumb window so it will be on the same layer of its toplevel

178. By Andrea Cimitan

removed XSync as gdk_flush is a wrapper for it

Revision history for this message
Loïc Molinari (loic.molinari) wrote :

OK. Looking at the _NET_RESTACK_WINDOW spec¹, it seems like a hack, but I don't see another solution for now.

¹ http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2506866

Revision history for this message
Loïc Molinari (loic.molinari) wrote :

Can you add a FIXME(Cimi) in the code explaining why you do that, what it fixes and what are the remaining issues?

179. By Andrea Cimitan

Added FIXME comment

Revision history for this message
Loïc Molinari (loic.molinari) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'os/os-scrollbar.c'
--- os/os-scrollbar.c 2011-03-28 16:17:49 +0000
+++ os/os-scrollbar.c 2011-03-28 17:33:46 +0000
@@ -97,6 +97,7 @@
97static gboolean thumb_button_release_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data);97static gboolean thumb_button_release_event_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
98static gboolean thumb_enter_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);98static gboolean thumb_enter_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);
99static gboolean thumb_leave_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);99static gboolean thumb_leave_notify_event_cb (GtkWidget *widget, GdkEventCrossing *event, gpointer user_data);
100static void thumb_map_cb (GtkWidget *widget, gpointer user_data);
100static gboolean thumb_motion_notify_event_cb (GtkWidget *widget, GdkEventMotion *event, gpointer user_data);101static gboolean thumb_motion_notify_event_cb (GtkWidget *widget, GdkEventMotion *event, gpointer user_data);
101static void thumb_unmap_cb (GtkWidget *widget, gpointer user_data);102static void thumb_unmap_cb (GtkWidget *widget, gpointer user_data);
102static void pager_move (OsScrollbar *scrollbar);103static void pager_move (OsScrollbar *scrollbar);
@@ -578,6 +579,8 @@
578 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->thumb),579 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->thumb),
579 thumb_leave_notify_event_cb, scrollbar);580 thumb_leave_notify_event_cb, scrollbar);
580 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->thumb),581 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->thumb),
582 thumb_map_cb, scrollbar);
583 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->thumb),
581 thumb_motion_notify_event_cb, scrollbar);584 thumb_motion_notify_event_cb, scrollbar);
582 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->thumb),585 g_signal_handlers_disconnect_by_func (G_OBJECT (priv->thumb),
583 thumb_unmap_cb, scrollbar);586 thumb_unmap_cb, scrollbar);
@@ -599,6 +602,8 @@
599 G_CALLBACK (thumb_enter_notify_event_cb), scrollbar);602 G_CALLBACK (thumb_enter_notify_event_cb), scrollbar);
600 g_signal_connect (G_OBJECT (priv->thumb), "leave-notify-event",603 g_signal_connect (G_OBJECT (priv->thumb), "leave-notify-event",
601 G_CALLBACK (thumb_leave_notify_event_cb), scrollbar);604 G_CALLBACK (thumb_leave_notify_event_cb), scrollbar);
605 g_signal_connect (G_OBJECT (priv->thumb), "map",
606 G_CALLBACK (thumb_map_cb), scrollbar);
602 g_signal_connect (G_OBJECT (priv->thumb), "motion-notify-event",607 g_signal_connect (G_OBJECT (priv->thumb), "motion-notify-event",
603 G_CALLBACK (thumb_motion_notify_event_cb), scrollbar);608 G_CALLBACK (thumb_motion_notify_event_cb), scrollbar);
604 g_signal_connect (G_OBJECT (priv->thumb), "unmap",609 g_signal_connect (G_OBJECT (priv->thumb), "unmap",
@@ -729,6 +734,77 @@
729 return FALSE;734 return FALSE;
730}735}
731736
737static void
738thumb_map_cb (GtkWidget *widget,
739 gpointer user_data)
740{
741 Display *display;
742 OsScrollbar *scrollbar;
743 OsScrollbarPrivate *priv;
744 XWindowChanges changes;
745 guint32 xid, xid_parent;
746 unsigned int value_mask = CWSibling | CWStackMode;
747 int res;
748
749 scrollbar = OS_SCROLLBAR (user_data);
750 priv = scrollbar->priv;
751
752 xid = GDK_WINDOW_XID (gtk_widget_get_window (priv->thumb));
753 xid_parent = GDK_WINDOW_XID (gtk_widget_get_window (priv->parent));
754 display = GDK_WINDOW_XDISPLAY (gtk_widget_get_window (GTK_WIDGET (scrollbar)));
755
756 changes.sibling = xid_parent;
757 changes.stack_mode = Above;
758
759 gdk_error_trap_push ();
760 XConfigureWindow (display, xid, value_mask, &changes);
761
762 gdk_flush ();
763 if ((res = gdk_error_trap_pop ()))
764 {
765 /* FIXME(Cimi) this code tries to restack the window using
766 * the _NET_RESTACK_WINDOW atom. See:
767 * http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2506866
768 *
769 * Should work on window managers that supports this, like compiz.
770 * Unfortunately, metacity doesn't yet, so we might decide to implement
771 * this atom in metacity/mutter as well.
772 *
773 * We need to restack the window because the thumb window can be above
774 * every window, noticeable when you make the thumb of an unfocused window
775 * appear, and it could be above other windows (like the focused one).
776 *
777 * XConfigureWindow doesn't always work (well, should work only with
778 * compiz 0.8 or older), because it is not handling the reparenting done
779 * at the WM level (metacity and compiz >= 0.9 do reparenting). */
780 Window root = gdk_x11_get_default_root_xwindow ();
781 XEvent xev;
782
783 xev.xclient.type = ClientMessage;
784 xev.xclient.display = display;
785 xev.xclient.serial = 0;
786 xev.xclient.send_event = True;
787 xev.xclient.window = xid;
788 xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_RESTACK_WINDOW");
789 xev.xclient.format = 32;
790 xev.xclient.data.l[0] = 2;
791 xev.xclient.data.l[1] = xid_parent;
792 xev.xclient.data.l[2] = Above;
793 xev.xclient.data.l[3] = 0;
794 xev.xclient.data.l[4] = 0;
795
796 gdk_error_trap_push ();
797
798 XSendEvent (display, root, False,
799 SubstructureRedirectMask | SubstructureNotifyMask,
800 &xev);
801
802 gdk_flush ();
803
804 gdk_error_trap_pop ();
805 }
806}
807
732static gboolean808static gboolean
733thumb_motion_notify_event_cb (GtkWidget *widget,809thumb_motion_notify_event_cb (GtkWidget *widget,
734 GdkEventMotion *event,810 GdkEventMotion *event,

Subscribers

People subscribed via source and target branches