<div dir="ltr">Hi Pekka,<br><div><br>"It is the wrong way to fix it.<br><br>Not wl_pointer nor wl_keyboard foci are interchangeable with the concept of "active". It simply just happens that an active window will usually have the kbd focus if a kbd exists, because users expect that. >From a purely protocol-mechanical point of view there is no connection. Giving keyboard focus to an active window is compositor internal policy."<br><br>This makes sense, thank you. I am thus going to remove the call to "pointer_set_focus(.. 0, 0)". By the way, I have a WIP patch which will allow focus to switch when you minimize a surface, just as when one gets destroyed currently. This seems to be what most of the other window managers do, and is likely to address this problem in a better way :-).<br><br>"Hmm, I'm not sure if that's clever or abuse... it's certainly unexpected and requires effort to see in the code, which calls a for a big comment to explain what is happening."<br><br>Practically, it works just nice ; but I agree, I will add a multi-line comment on top of this, to explain why this is required.<br><br>Regards,<br>Manuel<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-03-30 8:59 GMT+02:00 Pekka Paalanen <span dir="ltr"><<a href="mailto:ppaalanen@gmail.com" target="_blank">ppaalanen@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Sat, 28 Mar 2015 07:29:48 +0100<br>
Manuel Bachmann <<a href="mailto:manuel.bachmann@open.eurogiciel.org">manuel.bachmann@open.eurogiciel.org</a>> wrote:<br>
<br>
> Hi Pekka, thanks a lot for getting this on the rails !<br>
><br>
> "I'm not so sure about the pointer_set_focus here. Shuffling surfaces is<br>
> supposed to trigger a repick, which will reassign the pointer focus.<br>
> However, it seems something is off."<br>
><br>
> The "pointer_set_focus(... 0, 0)" thing was added for a client (Chromium)<br>
> whch privilegies pointer focus over keyboard focus, It considers itself<br>
> still focused when minimized ; mostly because it disregards keyboard focus<br>
> and, last time I looked in desktop-shell, even xdg-shell activate() events<br>
> were mostly linked to keyboard focus. So adding this call for pointer_leave<br>
> fixed it. What is your opinon on this ?<br>
<br>
</span>It is the wrong way to fix it.<br>
<br>
Not wl_pointer nor wl_keyboard foci are interchangeable with the<br>
concept of "active". It simply just happens that an active window will<br>
usually have the kbd focus if a kbd exists, because users expect that.<br>
>From a purely protocol-mechanical point of view there is no connection.<br>
Giving keyboard focus to an active window is compositor internal policy.<br>
<br>
The app must be fixed to honour the activate events if it uses<br>
xdg_shell. In xdg_shell, window activeness is notified via configure<br>
events' flags. The spec says:<br>
      <entry name="activated" value="4"><br>
        Client window decorations should be painted as if the window is<br>
        active. Do not assume this means that the window actually has<br>
        keyboard or pointer focus.<br>
      </entry><br>
<br>
If it uses wl_shell, then you have to rely on kbd focus, because<br>
wl_shell doesn't have anything better. This means that in a<br>
keyboard-less system, wl_shell cannot even communicate activeness. Maybe<br>
that's the reason why someone might abuse pointer focus as window<br>
activation? But when he does that, the window will switch to an<br>
inactive look by just a pointer leave, while the user could still be<br>
typing into the window. That would be confusing.<br>
<br>
If this is some tablet use case, then you wouldn't have either<br>
wl_pointer not wl_keyboard, you'd only have wl_touch. And touch "focus"<br>
disappears the moment the last finger goes up. Note, that virtual<br>
keyboards do not communicate via wl_keyboard. So in a tablet case, the<br>
window activeness is completely separated from any foci.<br>
<br>
Pointer focus is good for highlighting the widget under the pointer<br>
kind of things, but neither pointer not keyboard foci are meant to<br>
signify activeness.<br>
<span class=""><br>
> "assume the first wl_pointer.leave(nil) is for the popup surface, so<br>
> that's ok. The enter for nil looks very suspicious though. Maybe that<br>
> is caused by this patch?"<br>
><br>
> It clearly is ; I interpret this as the pointer leaving the main terminal<br>
> surface when it minimizes, which seems logical, but maybe I'm misleaded<br>
> (btw, how do you get all these logs ?).<br>
<br>
</span>You can get them with WAYLAND_DEBUG=client env var, when running the<br>
client.<br>
<br>
Entering a NULL surface makes no sense to a client, it can only ignore<br>
it. It already received a leave, which means that wl_pointer is not on<br>
any of its own surfaces. Saying "the pointer is still not on any of<br>
your surfaces" is redundant.<br>
<br>
These NULL arguments should happen only in race conditions. For<br>
instance, the compositor assigned pointer focus to a surface, that the<br>
client has already destroyed but the compositor has not processed the<br>
destruction yet. If the compositor *has* processed the destruction,<br>
there is no reason to send enter for NULL.<br>
<span class=""><br>
> "Just curious, how can the surface go off-center? Some output<br>
> hot-unplugging involved?"<br>
><br>
> The call to "unset_fullscreen()" will reposition the surface at its former<br>
> non-fullscreen position (old_x, old_y), which is good. When the surface<br>
> gets focused again later, fullscreen state gets triggered again because the<br>
> hint is stll too, which is good, too ; but the x,y is now old_x, old_y, so<br>
> off-center.<br>
<br>
</span>Hmm, I'm not sure if that's clever or abuse... it's certainly<br>
unexpected and requires effort to see in the code, which calls a for a<br>
big comment to explain what is happening.<br>
<span class=""><br>
> "When wouldn't there be a black_view?"<br>
><br>
> When you refocus a minimized surface, black_view has been destroyed by<br>
> "unset_fullscreen()". It gets created later again, but after this part,<br>
> where it is NULL and thus crashes.<br>
<br>
</span>Alright.<br>
<br>
<br>
Thanks,<br>
pq<br>
<div class="HOEnZb"><div class="h5"><br>
> 2015-03-27 15:22 GMT+01:00 Pekka Paalanen <<a href="mailto:ppaalanen@gmail.com">ppaalanen@gmail.com</a>>:<br>
><br>
> > On Mon, 16 Feb 2015 11:52:47 +0100<br>
> > Manuel Bachmann <<a href="mailto:manuel.bachmann@open.eurogiciel.org">manuel.bachmann@open.eurogiciel.org</a>> wrote:<br>
> ><br>
> > > From: Manuel Bachmann <<a href="mailto:manuel.bachmann@open.eurogiciel.org">manuel.bachmann@open.eurogiciel.org</a>><br>
> > ><br>
> > > 2 things were wrong with the minimization code :<br>
> > > - if the minimized surface was fullscreen, the shell would keep<br>
> > >   its fullscreen mode on and only display a black background ;<br>
> > > - keyboard focus was unset, but pointer focus was not.<br>
> > ><br>
> > > On the other hand, make sure a fullscreen surface gets centered<br>
> > > again when refocused with Mod+Tab.<br>
> > ><br>
> > > Author: Manuel Bachmann <<a href="mailto:manuel.bachmann@open.eurogiciel.org">manuel.bachmann@open.eurogiciel.org</a>><br>
> > > Author: Nicolas Guyomard <<a href="mailto:nicolas.guyomard@open.eurogiciel.org">nicolas.guyomard@open.eurogiciel.org</a>><br>
> > > Signed-off-by: Manuel Bachmann <<a href="mailto:manuel.bachmann@open.eurogiciel.org">manuel.bachmann@open.eurogiciel.org</a>><br>
> > > ---<br>
> > >  desktop-shell/shell.c |   16 +++++++++++++---<br>
> > >  1 file changed, 13 insertions(+), 3 deletions(-)<br>
> > ><br>
> > > diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c<br>
> > > index 5900c4d..830c25d 100644<br>
> > > --- a/desktop-shell/shell.c<br>
> > > +++ b/desktop-shell/shell.c<br>
> > > @@ -2657,13 +2657,20 @@ set_minimized(struct weston_surface *surface)<br>
> > >       weston_layer_entry_remove(&view->layer_link);<br>
> > ><br>
> >  weston_layer_entry_insert(&shsurf->shell->minimized_layer.view_list,<br>
> > &view->layer_link);<br>
> > ><br>
> > > +     if (shsurf->state.fullscreen)<br>
> > > +             unset_fullscreen(shsurf);<br>
> > > +<br>
> > >       drop_focus_state(shsurf->shell, current_ws, view->surface);<br>
> > >       wl_list_for_each(seat, &shsurf->shell->compositor->seat_list,<br>
> > link) {<br>
> > >               if (!seat->keyboard)<br>
> > >                       continue;<br>
> > >               focus =<br>
> > weston_surface_get_main_surface(seat->keyboard->focus);<br>
> > > -             if (focus == view->surface)<br>
> > > +             if (focus == view->surface) {<br>
> > >                       weston_keyboard_set_focus(seat->keyboard, NULL);<br>
> > > +                     weston_pointer_set_focus(seat->pointer, NULL,<br>
> > > +                                              wl_fixed_from_int(0),<br>
> > > +                                              wl_fixed_from_int(0));<br>
> > > +             }<br>
> > >       }<br>
> ><br>
> > Hi,<br>
> ><br>
> > I'm not so sure about the pointer_set_focus here. Shuffling surfaces is<br>
> > supposed to trigger a repick, which will reassign the pointer focus.<br>
> > However, it seems something is off. The keyboards focus is different to<br>
> > pointer focus, because keyboard focus is "sticky" and needs to be<br>
> > explicitly managed. Pointer focus generally follows picking unless the<br>
> > pointer is grabbed.<br>
> ><br>
> > With this patch applied:<br>
> ><br>
> > [2030091.702]  -> xdg_surface@15.set_minimized()<br>
> > [2030091.737]  -> xdg_popup@21.destroy()<br>
> > [2030091.768]  -> wl_surface@25.destroy()<br>
> > [2030091.805]  -> wl_buffer@29.destroy()<br>
> > [2030091.892]  -> wl_shm_pool@28.destroy()<br>
> > [2030092.413] wl_display@1.delete_id(21)<br>
> > [2030092.469] wl_display@1.delete_id(25)<br>
> > [2030092.503] wl_display@1.delete_id(29)<br>
> > [2030092.537] wl_display@1.delete_id(28)<br>
> > [2030092.570] wl_keyboard@16.leave(315, wl_surface@14)<br>
> > [2030092.633] xdg_surface@15.configure(1024, 600, array, 316)<br>
> > [2030092.722]  -> xdg_surface@15.ack_configure(316)<br>
> > [2030092.762]  -> xdg_surface@15.set_title("pq@erebos:~/git/weston")<br>
> > [2030092.798] wl_pointer@17.leave(317, nil)<br>
> > [2030092.853] wl_keyboard@16.modifiers(318, 0, 0, 0, 0)<br>
> > [2030093.019] wl_pointer@17.enter(318, nil, 69.000000, 109.000000)<br>
> > [2030093.154] xdg_shell@12.ping(319)<br>
> > [2030093.195]  -> xdg_shell@12.pong(319)<br>
> > [2030093.265] wl_pointer@17.leave(320, nil)<br>
> > [2030093.322]  -> wl_compositor@4.create_region(new id wl_region@28)<br>
> > [2030093.372]  -> xdg_surface@15.set_title("pq@erebos:~/git/weston")<br>
> > [2030093.409]  -> wl_compositor@4.create_region(new id wl_region@29)<br>
> > [2030093.455]  -> wl_region@29.add(0, 0, 1024, 600)<br>
> > [2030093.553]  -> wl_region@28.add(0, 0, 1024, 600)<br>
> > [2030093.642]  -> wl_surface@14.frame(new id wl_callback@25)<br>
> > [2030098.044]  -> wl_surface@14.set_opaque_region(wl_region@28)<br>
> > [2030098.142]  -> wl_region@28.destroy()<br>
> > [2030098.170]  -> wl_surface@14.set_input_region(wl_region@29)<br>
> > [2030098.208]  -> wl_region@29.destroy()<br>
> > [2030098.291]  -> wl_surface@14.attach(wl_buffer@24, 0, 0)<br>
> > [2030098.379]  -> wl_surface@14.damage(0, 0, 1024, 600)<br>
> > [2030098.436]  -> wl_surface@14.commit()<br>
> > [2030103.646] wl_display@1.delete_id(28)<br>
> > [2030103.727] wl_display@1.delete_id(29)<br>
> ><br>
> > This was made with weston-terminal patched to have a "minimize" option<br>
> > in the context menu. I just pushed that patch to master, btw. so<br>
> > everyone can test.<br>
> ><br>
> > I assume the first wl_pointer.leave(nil) is for the popup surface, so<br>
> > that's ok. The enter for nil looks very suspicious though. Maybe that<br>
> > is caused by this patch?<br>
> ><br>
> > My opinion is that this looks okay apart from the pointer focus.<br>
> ><br>
> > ><br>
> > >       shell_surface_update_child_surface_layers(shsurf);<br>
> > > @@ -5937,8 +5944,11 @@ switcher_next(struct switcher *switcher)<br>
> > >               view->alpha = 1.0;<br>
> > ><br>
> > >       shsurf = get_shell_surface(switcher->current);<br>
> > > -     if (shsurf && shsurf->state.fullscreen)<br>
> > > -             shsurf->fullscreen.black_view->alpha = 1.0;<br>
> > > +     if (shsurf && shsurf->state.fullscreen) {<br>
> > > +             center_on_output(shsurf->view, shsurf->fullscreen_output);<br>
> > > +             if (shsurf->fullscreen.black_view)<br>
> > > +                     shsurf->fullscreen.black_view->alpha = 1.0;<br>
> ><br>
> > Just curious, how can the surface go off-center? Some output<br>
> > hot-unplugging involved?<br>
> ><br>
> > When wouldn't there be a black_view?<br>
> ><br>
> > > +     }<br>
> > >  }<br>
> > ><br>
> > >  static void<br>
> ><br>
> > Thanks,<br>
> > pq<br>
> ><br>
> ><br>
><br>
><br>
<br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature"><div dir="ltr"><font>Regards,<br>
<br>
<i><b>Manuel BACHMANN</b><br>
Tizen Project<br>
VANNES-FR</i><br>
</font></div></div>
</div>