[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-compiz
Subject:    Re: [compiz] Problems with _NET_WM_FULLSCREEN_MONITORS and screen
From:       "Jason 'vanRijn' Kasper" <vr () movingparts ! net>
Date:       2009-05-26 19:28:13
Message-ID: e2a9b7d0905261228h33546f22gca4bfd83d6ca187 () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


On Tue, May 26, 2009 at 3:49 AM, Danny Baumann <dannybaumann@web.de> wrote:

> Hi,


Hey Danny! =:) Thanks for the reply!!


>  >         1) When an application requests a topology change via
> >            _NET_WM_FULLSCREEN_MONITORS, Compiz does honor the topology
> >         change, but it
> >            does not refresh any monitor that has changed since the
> >         last
> >            _NET_WM_FULLSCREEN_MONITORS topology. If the application
> >         requests to
> >            change from fullscreening monitor 1 to cover both monitors
> >         1 and 2, the
> >            window is resized and can still be interacted with, but the
> >         display still
> >            shows a frozen image of what was previously on the second
> >         monitor, for
> >            example.
>
> I can not reproduce that using your test program. I have seen a similar
> problem on rare occasion, though: Window contents, especially of larger
> windows, were stuck at that time and could be recovered only by
> unmapping and re-mapping (minimize, shade) them.
> Unfortunately I didn't find a good reproduction scenario so far, and I
> really don't know what should cause that.
> Are you using Nvidia's drivers, by any chance?
>

Yes, actually, I am.

01:00.0 VGA compatible controller: nVidia Corporation NV44 [Quadro NVS 285]
(rev a1)
05:04.0 VGA compatible controller: nVidia Corporation NV34 [GeForce FX 5200]
(rev a1)

(II) NVIDIA GLX Module  173.14.18  Mon Mar  2 12:43:12 PST 2009


> Another shot in the dark: You can try playing around with the "Force
> synchronization between X and GLX" option in the workarounds plugin.
> Perhaps it's just the sort-of-well-known redraw issue caused by race
> conditions in the X damage protocol.


Hm. Okay, I tried that and it didn't help.

If I do an explicit gtk_widget_hide() and then gtk_widget_show() after I do
the XSendEvent in the sample program (as attached), then compiz correctly
draws the window, but that's not desirable since it causes the window to
(obviously) disappear/reappear.


> >         2) When a window has fullscreened and used
> >         _NET_WM_FULLSCREEN_MONITORS, if
> >            any tooltips are used in that window (as this simple
> >         application does),
> >            Compiz will cause the screen to flash repeatedly until the
> >         user stops
> >            hovering over the originating widget and the tooltip goes
> >         away. This can
> >            be demonstrated in this simple application by hovering over
> >         the button in
> >            the window. As an interesting aside, when Compiz causes the
> >         screen to
> >            flash, it will refresh the monitors that were previously
> >         stale from #1
> >            above.
>
>
> You want to disable "Unredirect fullscreen windows" (in ccsm it's under
> General options). Ubuntu enables it by default (both settings have
> problems: enabling it causes the problem you're seeing, disabling it
> causes speed loss in fullscreen OpenGL apps, e.g. games).
>

OOH! *ding ding ding* AWESOME, thanks Danny! Okay, so disabling that fixed
not only the tooltip over a fullscreen problem, but it also fixed the first
problem I was describing! If I disable "Unredirect fullscreen windows",
switching topologies with _NET_WM_FULLSCREEN_MONITORS looks like it works
perfectly with Compiz 0.8.2.

Is there anything an application can do to detect whether this setting is in
effect and warn its users about it? This is going to cause a large amount of
community forum posts/bug reports for VMware Workstation/Player, I think. If
there's something we can do to be proactive about it, I'd like to do that,
but it feels like it may just need to be documented for our Compiz users?

Thanks again for your help Danny! You rock! =:)

-- 
-[ Jason 'vanRijn' Kasper    //  http://movingparts.net ]-
-[ KDE PIM Developer         //  http://www.kde.org  ]-
-[ bash fun -> :(){ :|:&};:  //  Numbers 6:22-26 ]-

[Attachment #5 (text/html)]

<div class="gmail_quote">On Tue, May 26, 2009 at 3:49 AM, Danny Baumann <span \
dir="ltr">&lt;<a href="mailto:dannybaumann@web.de">dannybaumann@web.de</a>&gt;</span> \
wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, \
204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> Hi,</blockquote><div><br>Hey \
Danny! =:) Thanks for the reply!!<br> <br></div><blockquote class="gmail_quote" \
style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; \
padding-left: 1ex;"> <div class="im">
&gt;         1) When an application requests a topology change via<br>
&gt;            _NET_WM_FULLSCREEN_MONITORS, Compiz does honor the topology<br>
&gt;         change, but it<br>
&gt;            does not refresh any monitor that has changed since the<br>
&gt;         last<br>
&gt;            _NET_WM_FULLSCREEN_MONITORS topology. If the application<br>
&gt;         requests to<br>
&gt;            change from fullscreening monitor 1 to cover both monitors<br>
&gt;         1 and 2, the<br>
&gt;            window is resized and can still be interacted with, but the<br>
&gt;         display still<br>
&gt;            shows a frozen image of what was previously on the second<br>
&gt;         monitor, for<br>
&gt;            example.<br>
<br>
</div>I can not reproduce that using your test program. I have seen a similar<br>
problem on rare occasion, though: Window contents, especially of larger<br>
windows, were stuck at that time and could be recovered only by<br>
unmapping and re-mapping (minimize, shade) them.<br>
Unfortunately I didn&#39;t find a good reproduction scenario so far, and I<br>
really don&#39;t know what should cause that.<br>
Are you using Nvidia&#39;s drivers, by any chance?<br>
</blockquote><div><br>Yes, actually, I am. <br><br>01:00.0 VGA compatible controller: \
nVidia Corporation NV44 [Quadro NVS 285] (rev a1)<br>05:04.0 VGA compatible \
controller: nVidia Corporation NV34 [GeForce FX 5200] (rev a1)<br> <br>(II) NVIDIA \
GLX Module  173.14.18  Mon Mar  2 12:43:12 PST 2009<br> <br></div><blockquote \
class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt \
0pt 0.8ex; padding-left: 1ex;"> Another shot in the dark: You can try playing around \
with the &quot;Force<br> synchronization between X and GLX&quot; option in the \
workarounds plugin.<br> Perhaps it&#39;s just the sort-of-well-known redraw issue \
caused by race<br> conditions in the X damage protocol.</blockquote><div><br>Hm. \
Okay, I tried that and it didn&#39;t help.<br><br>If I do an explicit \
gtk_widget_hide() and then gtk_widget_show() after I do the XSendEvent in the sample \
program (as attached), then compiz correctly draws the window, but that&#39;s not \
desirable since it causes the window to (obviously) disappear/reappear.<br>  \
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, \
204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im"> &gt;         2) \
When a window has fullscreened and used<br> &gt;         _NET_WM_FULLSCREEN_MONITORS, \
if<br> &gt;            any tooltips are used in that window (as this simple<br>
&gt;         application does),<br>
&gt;            Compiz will cause the screen to flash repeatedly until the<br>
&gt;         user stops<br>
&gt;            hovering over the originating widget and the tooltip goes<br>
&gt;         away. This can<br>
&gt;            be demonstrated in this simple application by hovering over<br>
&gt;         the button in<br>
&gt;            the window. As an interesting aside, when Compiz causes the<br>
&gt;         screen to<br>
&gt;            flash, it will refresh the monitors that were previously<br>
&gt;         stale from #1<br>
&gt;            above.<br>
<br>
</div><br>You want to disable &quot;Unredirect fullscreen windows&quot; (in ccsm \
it&#39;s under<br> General options). Ubuntu enables it by default (both settings \
                have<br>
problems: enabling it causes the problem you&#39;re seeing, disabling it<br>
causes speed loss in fullscreen OpenGL apps, e.g. \
games).<br></blockquote></div><br>OOH! *ding ding ding* AWESOME, thanks Danny! Okay, \
so disabling that fixed not only the tooltip over a fullscreen problem, but it also \
fixed the first problem I was describing! If I disable &quot;Unredirect fullscreen \
windows&quot;, switching topologies with _NET_WM_FULLSCREEN_MONITORS looks like it \
works perfectly with Compiz 0.8.2.<br> <br>Is there anything an application can do to \
detect whether this setting is in effect and warn its users about it? This is going \
to cause a large amount of community forum posts/bug reports for VMware \
Workstation/Player, I think. If there&#39;s something we can do to be proactive about \
it, I&#39;d like to do that, but it feels like it may just need to be documented for \
our Compiz users?<br> <br>Thanks again for your help Danny! You rock! =:)<br \
clear="all"><br>-- <br> -[ Jason &#39;vanRijn&#39; Kasper    //  <a \
href="http://movingparts.net">http://movingparts.net</a> ]-<br> -[ KDE PIM Developer  \
                //  <a href="http://www.kde.org">http://www.kde.org</a>  ]-<br>
 -[ bash fun -&gt; :(){ :|:&amp;};:  //  Numbers 6:22-26 ]-<br>

--0016361e86c05ad944046ad5baee--


["test_NET_WM_FULLSCREEN_MONITORS-button-clicking.c" (text/x-c++src)]

#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <string.h>

static GtkWidget* window;
static GtkWidget* button;
static GtkWidget* label;
static guint topology;

static gboolean fullscreen()
{
   gtk_window_fullscreen(GTK_WINDOW(window));
   return FALSE;
}

static gboolean unfullscreen()
{
   gtk_window_unfullscreen(GTK_WINDOW(window));
   return FALSE;
}

static gboolean switch_monitors(gpointer data)
{
   static const long monitors[6][4] = {
      {0, 0, 0, 0},
      {1, 1, 1, 1},
      {0, 1, 0, 0},
      {1, 1, 0, 0},
      {0, 0, 0, 1},
      {0, 1, 0, 1}
   };

   static const char* desc[6] = {
       "Window should be covering just the first head, height: top/bottom of first \
                head\n",
       "Window should be covering just the second head, height: top/bottom of second \
                head\n",
       "Window should be covering just the first head, height: top of first head, \
                bottom of second head\n",
       "Window should be covering just the first head, height: top of second head, \
                bottom of second head\n",
       "Window should be covering both heads 1 and 2, height: top and bottom of first \
                head\n",
       "Window should be covering both heads 1 and 2, height: top of first head, \
bottom of second head\n",  };

   guint index = GPOINTER_TO_UINT(data);

   g_debug("index: %d\n", index);

   if (index > 5) {
      unfullscreen();
      gtk_label_set_text(GTK_LABEL(label), "Unfullscreened.");
      topology = 0;
      return FALSE;
   } else {
      fullscreen();
      gtk_label_set_text(GTK_LABEL(label), desc[index]);
   }

   g_debug(desc[index]);

   GdkDisplay *display = gdk_display_get_default();
   XClientMessageEvent xclient;

   memset(&xclient, 0, sizeof(xclient));
   xclient.type = ClientMessage;
   xclient.window = GDK_WINDOW_XID(window->window);
   xclient.message_type = gdk_x11_get_xatom_by_name_for_display(display, \
"_NET_WM_FULLSCREEN_MONITORS");  xclient.format = 32;
   xclient.data.l[0] = monitors[index][0];
   xclient.data.l[1] = monitors[index][1];
   xclient.data.l[2] = monitors[index][2];
   xclient.data.l[3] = monitors[index][3];
   xclient.data.l[4] = 1;

   XSendEvent(GDK_WINDOW_XDISPLAY(window->window),
              GDK_WINDOW_XWINDOW(gdk_get_default_root_window()),
              False,
              SubstructureRedirectMask | SubstructureNotifyMask,
              (XEvent *) &xclient);

   // this does work, but causes our window to disappear and then reappear,
   // which is not desirable
   gtk_widget_hide(window);
   gtk_widget_show(window);
   // this does not work
   //gdk_window_invalidate_rect(window->window, NULL, TRUE);

   return FALSE;
}

static void close(GtkWidget *widget,
                  gpointer   data )
{
    gtk_main_quit ();
}

static void clicked(GtkWidget *widget,
		    gpointer   data )
{
   switch_monitors(GUINT_TO_POINTER(topology++));
}


int main(int argc, char** argv)
{
   gtk_init(&argc, &argv);

   GtkWidget* box;

   topology = 0;

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

   g_signal_connect(G_OBJECT(window), "delete_event",
		    G_CALLBACK(close), NULL);

   g_signal_connect(G_OBJECT (window), "destroy",
		    G_CALLBACK (close), NULL);

   gtk_container_set_border_width (GTK_CONTAINER (window), 10);

   button = gtk_button_new_with_label ("Push Me to change topologies!");
   gtk_widget_show(button);

   g_signal_connect(G_OBJECT (button), "clicked",
		    G_CALLBACK (clicked), NULL);

   label = gtk_label_new("I'll tell you what topology you're in here.");
   gtk_widget_show(label);

   box = gtk_vbox_new(FALSE, 10);
   gtk_widget_show(box);

   gtk_container_add(GTK_CONTAINER(window), box);

   gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
   gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0);

   gtk_widget_set_tooltip_text(GTK_WIDGET(label), "This is a tooltip!");

   gtk_widget_show(window);

   gtk_main();

   return 0;
}



_______________________________________________
compiz mailing list
compiz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/compiz


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic