Record-shattering Storm of Blog Posts Sighted Off Coast of GFY Island

Upon opening Firefox today to do some extremely-corporate reporting today, I became unreasonably and irrationally infuriated with the urlbar popup. How could this happen, some might ask. Why don’t you spend time on non-trivial things, others might say. No, postulating that at least two people are talking about the release blog is too generous; it’s unlikely that anyone other than my mother reads this blog these days.

 

Here we see the bar with its popup. Yes, it may have a more technical name, but I am unaware of it at this time. So bar and popup.

The issue I have has nothing to do with the application, so fear not, Firefox developers: you are safe for now. My fury was instead directed at the E compositor and the effects that we apply to the popup when it appears. For a rectangular window like this which clearly has an origin (the urlbar), why would we pop it up as though it was unanchored? This kind of bush league compositing might work for regular windows or compositors that I’m not actively working on, but I refuse to let my workspace be contaminated by such pedestrian effects.

 

And so I set out to add features for handling this sort of thing, ideally features which would be extensible and able to be reused for other related things. The code was simple; in fact, the code for adding a configuration GUI was longer and more complex than the actual implementation for the feature. Let’s check out some code:

diff --git a/src/bin/e_comp_object.c b/src/bin/e_comp_object.c
index fa9d7ee..1a23c3b 100644
--- a/src/bin/e_comp_object.c
+++ b/src/bin/e_comp_object.c
@@ -75,6 +75,7 @@ typedef struct _E_Comp_Object

    Eina_Stringshare   *frame_theme;
    Eina_Stringshare   *frame_name;
+   Eina_Stringshare   *visibility_effect; //effect when toggling visibility

    Evas_Object         *smart_obj;  // smart object
    Evas_Object         *clip; // clipper over effect object
@@ -503,6 +504,8 @@ _e_comp_object_shadow_setup(E_Comp_Object *cw)
                        if (!ok)
                          ok = e_theme_edje_object_set(cw->shobj, "base/theme/comp", buf);
                     }
+                  if (ok && m->visibility_effect)
+                    eina_stringshare_refplace(&cw->visibility_effect, m->visibility_effect);
                   if (ok) break;
                }
           }

This is where the compositor pulls the new effect’s name out of the config. It gets saved to the canvas object for later use.

@@ -654,14 +657,16 @@ _e_comp_object_done_defer(void *data, Evas_Object *obj EINA_UNUSED, const char *
    if (cw->animating)
      {
         cw->animating--;
-        e_comp->animating--;
+        if (!cw->animating)
+          e_comp->animating--;
         /* remove ref from animation start, account for possibility of deletion from unref */
         if (!e_object_unref(E_OBJECT(cw->ec))) return;
      }
+   if (cw->animating) return;
    /* hide only after animation finishes to guarantee a full run of the animation */
-   if (cw->defer_hide && (!strcmp(emission, "e,action,hide,done")))
+   if (cw->defer_hide && ((!strcmp(emission, "e,action,hide,done")) || (!strcmp(emission, "e,action,done"))))
      evas_object_hide(cw->smart_obj);
-   else if (!cw->animating)
+   else
      e_comp_shape_queue();
 }

This callback controls animation refcounting; when the animating flag is 0, the object is no longer animating and can be used normally. Since there are now going to be two references, the appropriate logic adjustments must be made to avoid toggling visibility at the wrong time.

@@ -1291,6 +1296,14 @@ _e_comp_intercept_hide(void *data, Evas_Object *obj)
                   e_comp->animating++;
                   cw->animating++;
                   e_object_ref(E_OBJECT(cw->ec));
+                  if (cw->visibility_effect)
+                    {
+                       cw->animating++;
+                       e_object_ref(E_OBJECT(cw->ec));
+                       e_comp_object_effect_set(obj, cw->visibility_effect);
+                       e_comp_object_effect_params_set(obj, 0, (int[]){0}, 1);
+                       e_comp_object_effect_start(obj, _e_comp_object_done_defer, cw);
+                    }
                }
              cw->defer_hide = !!cw->animating;
              if (!cw->animating)

When hiding the window, the original compositor animation triggers first; this is the one which determines how the object fades in and out. After, the new effect begins, starting from the visible/default state (0) and hitting the deferred refcounting callback upon animation completion.

@@ -2026,6 +2039,14 @@ _e_comp_smart_show(Evas_Object *obj)
         e_comp->animating++;
         cw->animating++;
         e_object_ref(E_OBJECT(cw->ec));
+        if (cw->visibility_effect)
+          {
+             cw->animating++;
+             e_object_ref(E_OBJECT(cw->ec));
+             e_comp_object_effect_set(obj, cw->visibility_effect);
+             e_comp_object_effect_params_set(obj, 0, (int[]){1}, 1);
+             e_comp_object_effect_start(obj, _e_comp_object_done_defer, cw);
+          }
      }
    /* ensure some random effect doesn't lock the client offscreen */
    if (!cw->animating)

And lastly, when showing the object it’s the same as hiding, except that the object starts from the hidden state (1).

The result looks a bit nicer:

 

Anyone wanting to replicate the effect can add the highlighted entry in this image to their composite match settings:

 

Advertisements

5 thoughts on “Record-shattering Storm of Blog Posts Sighted Off Coast of GFY Island

  1. Pretty sure it’s just because I’m not smart enough, but I tried setting my compositor to use other browsers:
    Type:Utility/Name:Popup/Class: Opera developer/Style:still/Effect:visibility/vertical and
    Type:Utility/Name:Popup/Class: Vivaldi-snapshot/Style:still/Effect:visibility/vertical
    and I still get normal popup (i.e. no slide in) instead of the fancy effect. Is there something else I would need to do? Just build today (10 Sep 2015) OpenGL. Is there somewhere the speed of the transition needs to be set because it may just be moving too fast, or is there something else I missed?

    Like

      • I’m talking specifically about the URL auto-complete bar expansion (same as in the video on this article) Tooltips expand down and so do menus (from the article that just shows the tooltip composite match in front of edi ), but this specific thing I can’t figure out what I’m doing wrong.

        I guess the real question is what does the URL bar match on?

        Like

  2. It matches the X11 ICCCM name and class window properties. An easy way to see them is using ‘xwininfo -tree -root’ while they are active; the Firefox one looks like this:

    0x1c082d6 “Firefox”: (“Popup” “Firefox”) 1156×289+31+85 +31+85

    Like

Join the flame war

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s