wingpanel icon indicating copy to clipboard operation
wingpanel copied to clipboard

Optionally hide wingpanel when not in use (autohide), or when active window is maximized (dodge)

Open quequotion opened this issue 7 years ago • 79 comments
trafficstars

I think it is worth reconsidering to implement autohide for the top panel as an optional feature.

Many applications do not "full-screen" when told to "maximize" and the presence of the panel enforces a 24px distinction between the two. There are also applications that attempt to draw actionable areas under the panel (ignoring struts). Users could enable autohide to have their full resolution available and work around apps that do not play well with panels or follow elementary OS's designs.

This pull request provides:

  • Four autohide modes, configurable by a gsetting: io.elementary.desktop.wingpanel.autohide (default Disabled): Autohide always hides the panel and moves windows out of its space when unhiding on mouseover. Float always hides the panel and overlays windows when unhiding on mouseover. Dodge hides the panel when the currently focused window is full-screen and moves windows out of its space when unhiding on mouseover. Dodge-Float hides the panel when the currently focused window is full-screen and overlays windows when unhiding on mouseover.

  • An {un,}hide delay, configurable by a gsetting: io.elementary.desktop.wingpanel.delay (default 200ms)

  • An animation speed for all hiding modes of 100ms.

How to install from git.

quequotion avatar Mar 04 '18 01:03 quequotion

We should probably talk about the animation speed. The initial draw for default behavior is set to 300ms, which is fine since it only happens once, but to work effectvely an autohiding panel should move faster. For autohide, I've set hide and unhide animations at 100ms. I'm not sure if adding gsetting for this would be convenience or clutter.

Edit: As a compromise, and to limit accidental {un,}hides, a customizable delay was added; the default is 200ms.

quequotion avatar Mar 04 '18 03:03 quequotion

over aggressive

It isn't intellihide, it is a dumb autohide. It's not so sexy, but the same behavior is offered for plank and I use it there as well. I think dumb autohide is what people who are going to the trouble of enabling an off-by-default authohide mode are more likely to want. Would it feel less aggressive if I added a grace period before hiding? Do you want a gsetting to specify the animation time? Edit: I did.

buggy

What do you mean by this? I just updated to fix some quirks; you might want to take another look.

UPDATE: All known behavior and performance bugs have been fixed.

quequotion avatar Mar 04 '18 03:03 quequotion

The animation speed is not the problem (though 300ms is a pretty standard value in the OS; take a look at Plank, for example). The problems as I see them:

  1. This is currently buggy. It hides seemingly randomly when my mouse is moving across the panel, or sometimes gets into a glitchy hide-unhide loop when my mouse is in certain places.

  2. I don't see the value in straight up autohide; if nothing is open or in the way, hiding the panel has no functional value and only serves to hide UI elements that have been designed to be always-present.

  3. Overlapping windows breaks the rules of things not being underneath the panel; instead, a hiding panel would need to adjust stuts and move maximized windows down when unhiding.

  4. Working around and explicitly catering to poor-behaving apps is not something we do in elementary OS; apps that are well designed (especially ones designed for elementary OS) should behave in a way that makes sense with the platform.

  5. I'm not a fan of adding hidden features. If it's a feature valuable enough to spend time developing, testing, and maintaining in perpetuity, we should be comfortable letting users select it. If we're not comfortable letting users select it, we shouldn't carry it.

cassidyjames avatar Mar 04 '18 03:03 cassidyjames

It hides seemingly randomly when my mouse is moving across the panel

Reminds me that one of the things I used to love about super-wingpanel was that it could autohide each area independently. EDIT: I looked into super-wingpanel, which additionally made use of motion_notify_event to keep track of hovering status. This has significantly improved the "buggy" behavior at the edges of indicator areas.

if nothing is open or in the way, hiding the panel has no functional value

Functional, no. It has aesthetic value. I really don't need anything being visible that isn't actively being used, and the panel will always be a mouse flick away anyway. I know that's just my personal preference, which is another reason the behavior is disalbed by default. Am I alone? Do I have OCD? Edit: Apparently not, this is one of the most requested features on r/elementaryos.

a hiding panel would need to adjust stuts

This can be done. I'm not against shipping a version with that, but I would add an aditional gsetting for "floating" mode. I can see how the unhide trigger area (top 1px of the screen) could get in the way of window decorations with sloppy mouse operation; for my preference I'd rather the decorations always stay in the same place and the windows always stay the same size and shape.

UPDATE: This was done, but I really don't like the clunky way it pushes windows down and pulls them up; it's more than a little disorientating (See 'EDIT' in 3rd paragraph).

apps that are well designed (especially ones designed for elementary OS) should behave in a way that makes sense with the platform

Because many applications will never reach that standard, the solution here is a hide mode that recognizes when a window is "maximized" and then hides the panel. Ideally I'd like to do that in a window-manager agnostic way (ie, not rely on Gala specifically to inform wingpanel of window states) but I doubt such a proposal would be accepted (because supporting alternate window managers is not in your purview). Dumb autohide is a compromise that allows having autohide with wingpanel in alternate window managers.

UPDATE: This was also done, but honestly I don't see much advantage over dumb autohide. Saves you one mouse flick per however often you need to look at the panel without interacting with it.

I'm not a fan of adding hidden features.

It might be worthwhile to add a tab for "Wingpanel" (or "Top Panel") to Switchboard's "Desktop" or "Tweaks" plugins, if additonal features like autohide/hide on maximize will be approved.

EDIT:

take a look at Plank

My behavior settings for Plank:

hide dock: on, Autohide hide delay: 0 unhide delay: 0 pressure reveal: off Like so

quequotion avatar Mar 04 '18 05:03 quequotion

The next update splits autohide into two modes: "Autohide" which will draw struts and push windows out of its space, and "Float", which will overlay the top 24px.

I've changed the gsetting (org.pantheon.desktop.wingpanel autohide) to a string with three choices: 'Autohide', 'Float', and 'Disabled', with 'Disabled' as default.

Redrawing the struts looks really clunky, but it works.

If I can find a window-manager agnostic way to implement "hide on maximize", I'll add it.

EDIT: 'Float' instead of 'Floating'; the working title for the "hide on maximize" mode is 'Dodge'.

quequotion avatar Mar 04 '18 06:03 quequotion

It has aesthetic value. I really don't need anything being visible that isn't actively being used

This is why we do a lot of smart automatic coloring to make the panel blend in, whether it's to the display bezel (when apps are maximized) or the wallpaper (where it goes transparent and the foreground changes to contrast). It's both aesthetically pleasing and always visible. We use the panel as an anchor point so users always have a way to get to the most important system functions.

I've changed the gsetting (org.pantheon.desktop.wingpanel autohide) to a string with three choices: 'Autohide', 'Floating', and 'Disabled', with 'Disabled' as default.

And now this is passing even more design decisions off to the user. :stuck_out_tongue: If any sort of hiding is to be accepted, I think we need to figure out how exactly we want it to work, then implement and test it. Adding yet-another-option is not typically the correct course.

It might be worthwhile to add a tab for "Wingpanel" (or "Top Panel") to Switchboard's "Desktop" or "Tweaks" plugins, if additonal features like autohide/hide on maximize will be approved.

Tweaks is not a first-party thing, so that's still definitely a hidden feature. I've started a branch for a Panel tab under the Desktop settings for a different feature, so that would be a natural place to put it. If we're comfortable committing to accepting and maintaining the feature (and added complexity) in perpetuity.

Redrawing the struts looks really clunky, but it works.

I took a look at this. I agree it's not perfect, but I do think it's more ideal than overlapping content. GTK windows typically resize more smoothly than I'm seeing here, so I wonder if it could be better optimized.

If I can find a window-manager agnostic way to implement "hide on maximize", I'll add it.

Check what Plank does here. Though it is likely to still be X-specific.

cassidyjames avatar Mar 04 '18 06:03 cassidyjames

It looks like clicking outside of an indicator to close it is also broken by this branch.

cassidyjames avatar Mar 04 '18 06:03 cassidyjames

It also looks like this doesn't listen to the GSetting live. Settings should apply instantly and not require a restart of the process.

cassidyjames avatar Mar 04 '18 06:03 cassidyjames

It's both aesthetically pleasing and always visible.

I use wingpanel particularly because it can have a transparent background (actually, rgba) and blend in to any desktop. In fact, I maintain a fork that drops all those bells and whistles in favor of window-manager agnosticism and static background (default transparent). EDIT: As sexy as the blending and such are, I'd like to have some autohide modes available to choose from--some users are going to want those 24px, some may want less distractions. Plank has five autohide modes; I'm considering at most three for wingpanel: Dodge (avoid maximized windows and redraw struts), Autohide (on mouseover, redraw struts), and Float (on mouseover, do not redraw struts).

We use the panel as an anchor point so users always have a way to get to the most important system functions

My initial efforts at autohide in wingpanel allowed it to appear and stay visible until the first leave_notify_event for this reason, to give users their bearings. A few hours ago I decided this was too quirky to present as a serious proposal for merging upstream. EDIT: Let's not forget any autohide mode a user enables will be their choice, as the behavior will always be disabled by default; users who would find the feature confusing probably won't be going out of their way to enable it.

And now this is passing even more design decisions off to the user.

I get that you don't want a lot of settings for people to fiddle with. If drawing the struts weren't so clunky I might be comfortable giving up "Float" mode (and maintaining it in my fork), but for the time being my proposal includes both. EDIT: On second thought, after working with "Autohide" (which redraws struts) I find it quite a bit more disorienting than "Float"; although both are vulnerable to accidential unhide triggering, redrawing the struts causes targets in window decorations to shift down and up 24px--this can make for quite the annoying hunt if a user gives in to the temptation to try to click a moving button. With "Float", when the user moves the mouse down to get out of an accidentally unhidden panel, the button's position has never changed--they can try again without searching for it.

EDIT: Now that there is an autohide delay and the struts are redrawn after the animation, this is much less of an issue.

If/When I am able to implement "Dodge", we'll have to decide what kind of unhide behavior is most appropriate: If the panel doesn't unhide on mouseover, then users would have to minimize or resize their windows to recover the panel--is that more or less annoying than the risk of accidental unhides? If it does resize on mouse over, and redraws the struts, it will cause the same disorientation as "Autohide", while if it does not redraw the struts and behaves like "Float", it will be in violation of the "nothing under the panel" design policy.

X-specific

One massive undertaking at a time. First I'll try to get it working in X.

EDIT: Plank employs a mix of X and libwnck functions in its various hide modes. I am trying to make heads and tails of this code, to see if could boil it down to something as simple (read, 'brief') as the dumb autohide code. Super Wingpanel's "hide manager" looks somewhat less intimidating.

clicking outside of an indicator to close it is broken

Edit: Figured this out too.

this doesn't listen to the GSetting live

Edit: Figured that out.

quequotion avatar Mar 04 '18 08:03 quequotion

The next step is to implement a hide on maximized (active window). This seems like it will be a big step.

  • It's going to require another library, libwnck.
  • This will add a lot of complexity to src/PanelWindow.vala in particular

I think I can whittle down what was done with super-wingpanel, but there's no getting out of libwnck. It's already a dependency of plank? I think a pull request that includes a new dependency is a bit of a long shot.

I see the trend of having a "HideManager" to do this for other components. I had in mind to implement the autohide directly in PanelWindow, because it was easy. Should I port to the common approach?

I would also like to take this opportunity to further extol the virtues of dumb autohide:

  • requires no additional dependencies
  • display server protocol agnostic
  • Only +135/-6 lines.
  • Have you tried 'Float'?

By the way, these settings for plank are just about as fast as 'Float' for the same behavior in both panels.

I also recommend Theme: Transparent for Plank, but that's just my opinion :)

quequotion avatar Mar 10 '18 13:03 quequotion

@quequotion: you don't need libwnck. Also we try to stay from X dependent libraries right now to not introduce code that will not work when we move to Wayland.

Wingpanel already knows about the current window state, just think about it, how does it go black when a window is maximized?

If you need more control over the events that happen inside the compositor, you should look at the "wingpanel-interface" which is a gala plugin specifically made to exchange useful data between the wm and the panel. It is also contained within this repository.

As for hiding logic: ideally, all the show and hide logic should be in another class, throwing everything into the PanelWindow class means that the code will become less maintainable in the future.

donadigo avatar Mar 10 '18 14:03 donadigo

Well you guys might not appreciate the auto-hide feature as a design feature but as a user who is using 1366x768 window resolution (which most of the older laptops do run on) it really helps when you're trying to use all the space you can get. Also remember that plank doesn't appear when hovering the bottom edges while full-screen (win+f) which makes multitasking hard while full-screen.

surajmandalcell avatar Jun 03 '18 14:06 surajmandalcell

@surajmandalcell we do and we are not opposed to implement that, but it's kind of hard to achieve a good working implementation with the panel, there are some blockers which make the feature laggy or random to use. I haven't looked at this branch in detail yet but guessing by the commit history it would be worth to take another look at how it works in a real world.

I've already attempted to implement such thing and it's not trivial to do this properly.

donadigo avatar Jun 03 '18 14:06 donadigo

@surajmandalcell

Thank you for your support! Just to let you know, I'm not giving up on this. I tend to work in spurts and it seems like I'm on my own, so it may take a while, but I will try to get the "dodge" type of autohide implemented eventually. I also need to move the autohiding into its own class, but to do so I need to learn more Vala.

@donadigo

I would appreciate if you would look at it again; It has been while since I fixed some of the issues cassidyjames brought up. I don't think this is actually such a difficult thing to implement, except that my programming skills are very rusty. That said, as far as "Float" (strutless) and "Autohide" (strutted) modes' functionality, they are complete--not lagging or randomly bouncing around (there's a very, very slight flicker as the mouse moves between each indicator area), the panel stays visible while indicators are open, and I haven't noticed any memory or cpu leaks.

quequotion avatar Jun 03 '18 14:06 quequotion

@quequotion I can actually work on this if you want but the thing is i don't know vala more than changing little frontend parts so i need to learn vala too. My first semester just ended so i have a month of holiday in which i can work on these stuff. Do tell if i can help you out on some repetitive tasks or something similar.

And

Do you use the default valadoc.org to learn vala through something else?

surajmandalcell avatar Jun 03 '18 14:06 surajmandalcell

@surajmandalcell

Thanks for the offer! I don't have a more detailed tasklist than the discussion here; the next steps will be difficult ones. Yes, I use Valadoc and also I spent a lot of time looking over the code of various Pantheon components. The elementary OS devs build their applications in a fairly consistent style, so it's easy to follow what goes where. Another useful resource is the GTK+ 3 Reference Manual.

quequotion avatar Jun 03 '18 15:06 quequotion

I've added an autohide delay, which defaults to 200ms; the same delay is used for both hide and unhide. I chose this number as a compromise between the original 300ms animation speed and the 100ms I consider practical for autohide (the same speed as Plank's autohide animation). It is configurable via a gconf setting at io.elementary.desktop.wingpanel.delay (0~1000ms).

I've also modified the strut drawing behavior, so that they are drawn after the panel animates for "Autohide", "Disabled" and yet-to-be-implemented "Dodge". This changes window interaction from a clunky push down / pull up to a quick knock down / jump up; I almost like it--but I still prefer "Float" as it doesn't move windows around.

I'm using "Float" with a 10ms delay. This is quite enough for me to avoid accidentally triggering the panel when going for a window decoration.

quequotion avatar Jun 18 '18 18:06 quequotion

Imported dodge-maximize code from Keith Bailey's branch.

There are now four autohide modes available; I do not intend to get all of them into wingpanel. I'd like some reviewers to try them out and give me their opinion about which behaviors to keep. Dodge-Float is my favorite.

quequotion avatar Sep 16 '18 22:09 quequotion

Here we go again: Nice, getting close to something that could be merged! I personally like the Dodge-Float and still Float modes. The issues with Dodge and Autohide remain the same, when using these modes, the maximized window will reallocate it's size and the experience will not be a great one.

Issues:

  • Don't use libwnck. It uses X server to gain the info about the windows while there's a much more native way - through the window manager. Wingpanel itself has a gala plugin that can expose that information to the wingpanel process.

  • I feel like the wingpanel animation is still really slow (not talking about delay timeout). I often wait with my mouse for the panel to show.

  • There's an issue with how struts currently work with notifications. If you try to use one of the float modes and try to increase / decrease volume with the scroll wheel, the volume notification appears overlaying the panel, stealing the mouse focus and in result, the panel hides. This will not be an easy one to fix.

More to come.

donadigo avatar Sep 16 '18 23:09 donadigo

  • Don't use libwnck. It uses X server to gain the info about the windows while there's a much more native way - through the window manager.

I need wingpanel and this feature to work with other window managers, so libwnck seems to be the only option. If there were a display-server agnostic method other than using Gala I would go for that, but I am not aware of any. I understand that you put your distribution first, but the very reason I fell in love with (super-)wingpanel and plank was that they were modular and worked well with most window managers. ~~Maybe later I'll make a gala-specific version of this, if that's what's required to get through this pull request, but to be honest I wouldn't feel good about contributing to walling in this garden.~~

EDIT: donadigo is working on a gala-based implementation!

  • I feel like the wingpanel animation is still really slow (not talking about delay timeout). I often wait with my mouse for the panel to show.

The animation I'm doing here comes from the original drawing animation (when wingpanel appears at startup). If this is slow, it is because the original model is slow. I'd appreciate any advice on speeding this up.

  • There's an issue with how struts currently work with notifications. If you try to use one of the float modes and try to increase / decrease volume with the scroll wheel, the volume notification appears overlaying the panel, stealing the mouse focus and in result, the panel hides. This will not be an easy one to fix.

The float modes do not draw struts (except after hiding). I use wingpanel with a different window manager and notifications daemon; the bubbles do appear over the panel but the panel retains focus, so the mousewheel can still change the volume. Why does gala allow notifications to steal focus?

By the way, apologies, I force pushed a hard reset to delete the commits I tried to get Travis CI to find libwnck. I don't know why it is having trouble; there is no problem on my end. I really hate cmake, I really really do.

EDIT: Solved(?) by adding libwnck-3-dev to .travis.yml; really wish cmake itself could competently specify required dependencies.

quequotion avatar Sep 17 '18 01:09 quequotion

The latest changes are probably the last until migrating this to its own service file, unless someone finds bugs to fix.

Responsiveness is greatly improved, as is behavior. The default 200ms delay is now quite practical: the panel will not show at all for brief, accidental contacts with the top edge of the screen and it's quite difficult to bounce the panel up and down by waggling the mouse along the top edge of the screen (it is possible with a delay less than 150ms, problematic with a delay less than 100ms). I'm tempted to hard code it at this point, but there could still be an argument for keeping the delay customizable for accessibility and it makes sense to leave it open as long as this pull request is in more of a technological demonstration form than whatever might eventually be accepted.

One significant change is that I removed animate_panel (), which was just a duplicate of update_panel_dimensions () minus the call to update_struts (). This was written at a time when my strategy was to avoid making changes to upstream code as much as possible, which led to many sub-optimal design choices. I'm thinking of a new plan for migrating the hiding code to its own service: It doesn't seem like this can be done without making some modifications to src/PanelWindow.vala anyway, so I will migrate some of its code along with the hiding logic, into something like src/Services/AnimationManager.vala.

That said, I still have a lot of vala to learn before any such thing is possible.

quequotion avatar Sep 19 '18 14:09 quequotion

@TonioGela I tend to work in spurts. Sometimes a while may pass between updates, but the work continues! Right now the to-do list is as follows:

  1. Move animation routines out of PanelWindow.vala and into their own class (to follow the coding standards of other elementary OS projects and reduce the maintenance load)
  2. Reduce the number of available hide modes (the elementary OS devs only want "Dodge"; the users mostly want "Autohide" (poll went down with Google+'s ship); I like "Dodge-Float" and "Float")
  3. Rewrite Dodge to use Gala API instead of libwnck (although I'd rather keep it DE agnostic, the elementary OS devs have in mind that this will make porting to Wayland easier and supporting window managers other than Gala isn't in their purview)

In the mean time, I could really use some help with Debian packaging. I'd like to ship this version of wingpanel in my PPA, but my last attempt failed to build for trying to compile gschemas.

quequotion avatar Oct 29 '18 18:10 quequotion

The timeframe?

n-osennij avatar Nov 06 '18 17:11 n-osennij

@n-osennij I wish I had a timeframe for you; I know there's a lot of demand for this feature. This fork is in fact already working, but has not been released for elementary OS. The remaining to-do items are to qualify for merging. It would release some of the pressure if someone could help me release a PPA package of this in the interim. I seriously have more difficulty making Debian packages than writing programs.

In the mean time, if you are comfortable using git, compiling, and installing software without a package manager (apt in elementary OS/Ubuntu/Debian), please try this out if you haven't already!

quequotion avatar Nov 24 '18 15:11 quequotion

i tried building this but i get an error when running meson build --prefix=/usr Meson encountered an error in file lib/meson.build, line 20, column 0: Custom_install_dir must be a string

InvisibleRasta avatar Nov 30 '18 18:11 InvisibleRasta

@InvisibleRasta

i tried building this but i get an error when running meson build --prefix=/usr Meson encountered an error in file lib/meson.build, line 20, column 0: Custom_install_dir must be a string

~~That file is not modified in this fork and~~ meson build --prefix=/usr works for me.

EDIT: CMake build system was removed upstream! (a good thing, really)

By the way, if you are using Archilnux you might try wingpanel-standalone-git which features these patches!

quequotion avatar Dec 02 '18 04:12 quequotion

I spent a few months getting used to "Dodge-Float" (autohide when focusing on a fullscreen or maximized window).

The mechanism works: when the focused window is fullscreen or maxmized, wingpanel hides. When the focused window is small, or no window is focused, or the cursor touches the top edge of the screen, wingpanel unhides.

  • Sometimes a fullscreen or maximized window will make a popup window (modal dialog, etc); and wingpanel unhides because focus changes to the smaller window; if you don't recognize the dialog, and close it, it seems like the panel should not be open (a maximized window is under it, and also under that dialog).*
  • Simple, mouseover autohide is a complete mechanism itself; the "Dodge" modes are a kind of "Autoshow".**

*Could be worked around by changing "hide when focused window on this desktop is fullscreen/maximized" to "hide when any window on this desktop is fullscreen/maximized", at the cost keeping the panel hidden when conciously using a smaller window on top of a maximized or fullscreen one. **"Float" still feels most natural to me.

quequotion avatar Feb 25 '19 20:02 quequotion

@lhorace Yes, the AUR pacakge has additional patches to remove features that depend on the Gala window manager, such as the adaptive background color, leaving the panel background persistently transparent.

If you are using Gala, you could rebuild the package with those features by commenting out the patching in the PKGBUILD like so:

  #Standalone patches
  #msg2 "Remove Gala dependecies"
  #rm -rf wingpanel-interface
  #rm src/Services/BackgroundManager.vala
  #patch -Np2 < ../minus-backgroundmanager.patch
  #patch -Np2 < ../minus-galaplugin.patch
  #patch -Np2 < ../minus-gala.patch

You may also set a persistent background color for wingpanel in ~/.config/gtk.css

/*********************
 * wingpanel support *
 ********************/

.panel {
/*    background-color: transparent; */
    background-color: black;
    transition: all 1s ease-in-out;
}

.panel.maximized {
    background-color: #000;
}

Note that the color set by .panel.maximized only works with Gala.

quequotion avatar Mar 08 '19 07:03 quequotion

Any news?

n-osennij avatar Mar 31 '19 12:03 n-osennij

Any news?

Nice to know there is still interest!

I'll get back to work sooner or later. For now this is working as much as I need it to be. Not distributed well though.

I think it would relieve some of the pressure if it were easy to install as a PPA package or flatpack, but I am not competent in making those kinds of packages. Could use some help there.

quequotion avatar Apr 06 '19 16:04 quequotion