IgnorantGuru / spacefm

SpaceFM File Manager
http://ignorantguru.github.com/spacefm/
GNU General Public License v3.0
489 stars 73 forks source link

[desktop] Transparent background option #269

Closed kanyck closed 9 years ago

kanyck commented 11 years ago

Is it possible to make SpaceFM to draw icons only on a specific desktop, or have transparent background, or both? I use different wallpapers to differentiate compiz desktops (and find it very convenient) but it comes at cost of yielding desktop icons. It would be nice to have both...

IgnorantGuru commented 11 years ago

Is it possible to make SpaceFM to draw icons only on a specific desktop

Currently, not without hacking the sources. The icons which appear on the desktop(s) are derived from the contents of ~/Desktop/, and are placed on all workspaces ("desktops"). You could probably easily limit this by hacking fm_turn_on_desktop_icons() in desktop.c.

SpaceFM's DM doesn't use any transparency. I'm not sure what the meaning of having a transparent desktop background would be, as the desktop image is generally beneath all other windows (but feel free to educate me - not an area I've worked with much). You can use transparency on top of the SpaceFM desktop in something like conky. (Note that conky has been reported to have a transparency issue with GTK3 - likely something which will have to be addressed in conky.)

BwackNinja commented 11 years ago

IgnorantGuru: kanyck is probably talking about having Compiz draw the backgrounds with its wallpaper plugin. When doing this drawing composited, the background set for X becomes irrelevant and whatever the window draws by itself is all that matters (unless you've got conky or something using fake transparency, but nowadays conky supports real transparency). This just requires an RGBA colormap/visual and clearing the background to transparent rather than to an image.

Its completely doable, and there was even a patch to nautilus back in the day that did this because it was the only way to get different backgrounds for different workspaces in a way that didn't look terrible when using Compiz with its various workspace-switching effects.

kanyck commented 11 years ago

Sorry for not replying at once. @IgnorantGuru. I don't think I can educate you in something like programming -- I haven't been writing any code for almost 20 years now)) However, BwackNinja got it just right - that's what I meant. I did suppose it may be hard to implement, so it's up to you guys to decide if it's worthy or not. Personally I find Compiz to be the only sane option if one wants nice-looking yet lightweight environment, but I don't think there's a lot of users like me - who are ready to spend time collecting their systems piece by piece. Moreover, the Compiz development apparently ceased in favor of Wayland (at least announced to) - so this only option may go in a while as well...

IgnorantGuru commented 11 years ago

Now that I'm working in the desktop code more (I haven't done much in there since it was forked from legacy pcmanfm), I see that SpaceFM uses a single background (desktop) window for all workspaces on a given screen. So all workspaces on a screen share the same background, icons, etc. So per-desktop wallpapers would not happen easily, nor would being able to control whether icons appear on a given desktop. Perhaps this is why it's done in Compiz.

Perhaps a 'Transparent' option could be added for the wallpaper/colors as BwackNinja suggests. Any sample code on that BwackNinja for desktop-window.c's desktop_window_set_background()? If you know the code for just adding "an RGBA colormap/visual and clearing the background to transparent rather than to an image" maybe I can work it into the settings. Thanks.

IgnorantGuru commented 11 years ago

Maybe the color chooser dialog opened by the Background color button in Preferences|Desktop could have a 'Use transparent background ' checkbox or button in lieu of a color? (This would affect all desktops.)

Of course that will probably depend on BwackNinja providing the code for drawing the background that way, as I'm not familiar with the visuals and I don't have Compiz to test on atm.

BwackNinja commented 11 years ago

drawing the background like that is simply: cairo_save(cr); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0); cairo_rectangle( //all of the window ); cairo_paint(cr); cairo_restore(cr);

also needed is gtk_widget_set_default_visual() with an rgba visual and gtk_widget_set_default_colormap() with an rgba colormap is also needed, but just for gtk2

and the rest is just the same changes as in this commit: https://github.com/IgnorantGuru/spacefm/commit/b2cd4752a94adcb9d5c86227bb08b49a69bd979f

IgnorantGuru commented 11 years ago

@BwackNinja

also needed is gtk_widget_set_default_visual() with an rgba visual

gtk_widget_set_default_visual is deprecated even for GTK2 and does nothing, as is gtk_widget_set_visual. ???

I tried this in 5e4e148 (temporary 'trans' branch). I don't have the setup to test transparency, but it reveals no errors on the first run. If I then switch to wallpaper Zoom and back to Transparent, I get this crash (GTK3):

(spacefm:21211): Gdk-WARNING **: The program 'spacefm' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadDrawable (invalid Pixmap or Window parameter)'.
  (Details: serial 14762 error_code 9 request_code 62 minor_code 0)
  (Note to programmers: normally, X errors are reported asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the GDK_SYNCHRONIZE environment
   variable to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error() function.)

I don't know cairo well enough to debug this. Any suggestions? It's all set to go if you want to debug it for me. I also haven't tried GTK2 yet.

If anyone would like to test this, you can use the BUILD NEXT instructions in README, substituting branch name 'trans' for 'next' in those commands.

BwackNinja commented 11 years ago

I'll be able to get to it in a few days. On first glance though, I should've clarified some things. The transparency is really just for the window, not for the root pixmap, because the root pixmap is really only used in the non-composited case for parent-relative windows, and in the transparent and composited case doesn't make much sense. You also only put one argument for gtk_widget_set_default_colormap in the gtk2 case, but you would've noticed that if you tested GTK2.

As a sidenote, I should be able to get back to regularly contributing by this summer.

BwackNinja commented 11 years ago

All that should be necessary for gtk3 is a call to gtk_widget_override_background_color and some logic changes in paint_rubber_banding_rect so that it does not draw an opaque rubberbanding box. The cairo stuff is more useful when you're just in the expose/draw handler.

If you're going to work on this yourself, xcompmgr is enough to have compositing with whatever window manager. But as I said before, I should be able to get to this in a few days.

IgnorantGuru commented 11 years ago

Okay thanks! I'll leave this for when you have a chance to review it; I think your looking at it will be more efficient than my coming up to speed. Meanwhile I have some of the moveability to complete.

I suppose transparency is less radical/buggy now than when I last tried it - I've avoided it since moving to Openbox.

IgnorantGuru commented 11 years ago

This issue has been renamed - was "Make SpaceFM draw icons on chosen desktop(s) only".

IgnorantGuru commented 11 years ago

Noting this related request - basically a request to turn wallpaper+color off, perhaps per screen. Does transparent bg also satisfy this use case?

purpleleaf commented 11 years ago

i'm really interested to this feature... thare are any plans to implement it in spacefm in a near futute? :)

stevenhoneyman commented 10 years ago

+1 for this feature, would be useful to me so I can use a different program for setting wallpaper (multiple monitors, different wallpapers)

VastOne commented 10 years ago

^ nitrogen handles that perfectly... and since development on SpaceFM is on hold indefinitely it is a better option right now

stevenhoneyman commented 10 years ago

You mean handles setting wallpaper perfectly, even with SpaceFM desktop enabled?

I use 'feh' currently, which is perfect, apart from SpaceFM covers over it even with wallpaper not ticked in the Prefs.

It's a shame it's on hold I know. I'm still hoping a keen developer adopts it until IG returns :smile:

BwackNinja commented 10 years ago

Yeah, yeah. I'm supposed to be handling this issue, but I've been busy/slacking. I'll try to make some progress this weekend. I've done this before, and I know how to do it for both gtk2 and gtk3. If nothing else, I'll make sure to give an update after this weekend is done.

BwackNinja commented 10 years ago

I've got a preliminary version working mostly. It should be ready to test soon. I've had to reacquaint myself with the SpaceFM desktop code.

stevenhoneyman commented 10 years ago

@BwackNinja Hi, just wondering if there's any news/updates on this?

BwackNinja commented 10 years ago

Sorry for taking so long with this.

New option added: --transparent-desktop. I've tested this a bit in Compiz, but would like your feedback about any issues it has.

https://github.com/BwackNinja/spacefm/commit/cd76d4d0cd67cdcbce5996366a055515c93d750c

stevenhoneyman commented 10 years ago

Thanks for remembering in the end! I'll have a look see if I can spot what's missing (why it won't compile) tomorrow... it's nearly 3am now - I really should go to sleep!

IgnorantGuru commented 9 years ago

BwackNinja, pulled to next as-is - thanks!

I was wondering why you made it a command-line option rather than a background image style in settings (stretch, etc), which can be changed dynamically. eg is it not possible to allow the user to change the transparent state once the desktop window is created? (I don't use transparency so forgive any ignorance.)

eg could I put a "Transparent" checkbox next to the Mode setting in Prefs|Desktop instead of the command-line option? (I edit those ui files manually these days due to upstream changes so might be better for me to add that if feasible.)

Also some build warnings on this - I try to keep SpaceFM warning free:

desktop/desktop-window.c: In function ‘desktop_window_class_init’:
desktop/desktop-window.c:286:22: warning: assignment from incompatible pointer type [enabled by default]
     wc->scroll_event = on_scroll;
                      ^
desktop/desktop-window.c: In function ‘on_realize’:
desktop/desktop-window.c:2547:20: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default]
     char *wmname = gdk_x11_screen_get_window_manager_name( gtk_widget_get_screen( w ) );
BwackNinja commented 9 years ago

IgnorantGuru, a lot of setting up the transparent desktop is in desktop_window_new, and thus a new desktop window would need to be created to switch between them. This also meant that I could be sure I wasn't breaking things because the regular codepath was preserved as-is. Plus, I haven't dealt much in the preferences windows and settings infrastructure, so this was also the easiest way.

The on_scroll is an easy fix, GTK2 vs GTK3 ifdef - I had just uncommented what was already there. The lack of const was a careless mistake. I'll fix both of these issues later today.

IgnorantGuru commented 9 years ago

BwackNinja, looking it over, I don't see anything in prefdlg that completely destroys and recreates the desktop window, so no precedence for that. How feasible do you think it would be to set/unset the transparency state in eg desktop_window_set_background, rather than desktop_window_new? If you know how to do that using the gtk_widget_set_visual, gtk_widget_set_colormap, stick (unstick), etc., then I don't mind refactoring the command line option as a setting - you can just handle the those function calls in desktop_window_set_background. Anyway you can test ability this in advance? If it looks good I'll add the setting for you.

I think it would be better as a setting because people will see the feature is there, and its more accessible for testing ,etc. I do try to keep the CLI brief, but it's okay as it is too. And it does tend to be an expert feature anyway.

Also, do the background settings (wallpaper, mode) apply if transparency is enabled? eg do you still show wallpaper in transparent mode, or should we grey those? Or if we make transparency a setting, can be just list it as an option in Mode and grey the wallpaper?

For the minor fixes like warnings, if you could sync your next branch against mine and work in there, that would probably be easier for me because I'm ahead of your master. No need for a pull request if you don't want it, you can just note any new commits in your next here. Thanks.

IgnorantGuru commented 9 years ago

To make testing this easy, you might just pretend the Tile setting means transparent (just leave the actual Tile code intact but ignored). So changing to Tile should activate transparency, and changing to Stretch or any other should deactivate it. Changing the wallpaper mode automatically runs desktop_window_set_background, so you can just focus on the gtk functions you need. That will tell us if its feasible. If you get that working then I can just add a Transparent mode. See what you think.

You could probably even destroy and recreate the gtkwindow in there if really necessary, just don't destroy the data for it. Then it can just redraw the icons.

IgnorantGuru commented 9 years ago

BwackNinja, in the next branch I have removed the command-line option for transparent-desktop and added a wallpaper mode for transparent. If you turn transparency on or off it pops a message saying that you need to restart the DM.

I didn't touch any of your desktop-window code in making this change, so everything should work as before, but someone please test.

From here we can leave it as-is, offer to restart the DM, or if you can make the code change or destroy/recreate the gtk window without a restart, I can just remove that popup message.

Also, I cleared the one warning, but I don't see how to clear this one:

desktop/desktop-window.c: In function ‘desktop_window_class_init’:
desktop/desktop-window.c:286:22: warning: assignment from incompatible pointer type [enabled by default]
     wc->scroll_event = on_scroll;
                      ^

Occurs with both GTK 2 and 3.

IgnorantGuru commented 9 years ago

Thanks looks good.