GNOME Bugzilla – Bug 676110
Classic W32 theme for GTK+
Last modified: 2015-04-29 02:05:06 UTC
Right now there is a huge problem with GTK3: On W32 it draws UI using W32 Theming API, and that API is completely non-functional when Windows Classic theme is enabled. Which makes GTK+ look bad. The solution that i propose is to implement a version of W32 Theming API function set in GTK+ itself, and use THAT set of functions when classic theme is enabled. With some custom-crafted .css files. How these functions will be implemented is an open question. GTK2 used certain W32 API calls to draw some things, and drew other things from hard-corded bitmaps, and used Cairo for other things. The alternative is to draw everything in GTK (by using Cairo, most likely). It has an added benefit of enabling W32 Classic theme on non-W32 platforms (some people seem to want this for unfathomable reasons).
Created attachment 214127 [details] [review] Dummy theme implementation
Created attachment 214128 [details] [review] Fix a warning.
Created attachment 214129 [details] [review] Basic W32 classic theme implementaiton (buttons, checkbuttons, radiobuttons, entries)
Created attachment 214130 [details] CSS file that goes along with it.
Created attachment 214131 [details] A screenshot of gtk-widget-factory with all previous patches applied.
The first two patches should be merged I guess, as the second does not fix or change anything in the current codebase.
I've been using git for the last couple of years, and i'm accustomed to NOT doing everything in one huge patch, but rather committing as i go, and submitting these commits as they are. So yes, when viewed in isolation they might seem rather silly. Anyway, this is mostly style issue (i still have the commits in my repository, it's not a problem to do `git rebase -i XXXX' and squash some of them). What about the CONTENT of the patches? Do you think the approach i took is viable? What are your thoughts on using Cairo for all drawing? Etc.
For anyone interested in this, i've also implemented drawing for scrollbars, spinbuttons (they still use their GTKish +/- button images, i was unable to change them into something different). Also had to enable transparency (otherwise it was impossible to correctly draw some of the widgets). It all ended on GtkNotebook and its tabs. Drawing tabs and the notebook with their 2-pixel-thick 3D-borders without visual artefacts requires more information about notebook state and style than it's possible to get at the moment. Also, comboboxes proved to be a had nut to crack. I was unable to make list-style comboboxes look right using the stylesheet. If anyone still wants it, i'll attach the patches i came up with to this point.
Created attachment 244393 [details] RC of the W32 classic theme Sorry for uploading an archive, but i'm not going to click "Add attachment" 17 times... Now this is not release-quality, but it does look more-or-less OK, and i haven't been able to make it look better. Anything further requires hacking on GTK itself and fixing problems with it (combobox background, for example). Real problems with this code itself are the following: 1) Incomplete defs for non-W32 building. There's a FIXME for that in the code. The code is supposed to be 100% portable, since it only draws with cairo, but it may need extra defs to compile. 2) Some functions are implemented using W32API. These will have to have alternative implementation for non-W32 OSes. These functions are: _gtk_GetThemeSysSize (GetSystemMetrics) _gtk_GetThemeSysColor (GetSysColor) and maybe some more. 3) The set of theme IDs that this code can draw is limited. This is because W32classic theme is relatively simple, and i've been able to re-use "button", "scrollbar" and "edit" for many widgets. This may not need fixing, but keep it in mind. 4) Highly inefficient cairo usage. For example, _gtk_cairo_checkerboard_create() is called every time a checkboard pattern is needed. The pattern is used, then destroyed, and later created again. I'm not sure how to fix that correctly (it uses cairo_surface_create_similar(), what if surface type changes?), but somehow it must be created once, and used everywhere. 5) Some colors are hardcoded. This is bad, colors should be user-adjustable. The easiest way to do that is to add a new css function, something like -gtk-win32-theme-set-color(). 6) Same as (5), but for prelight. Since prelight is not very classic-y, i've made it optional. But the boolean that controls its optionalness is hardcoded at the moment. It should be user-adjustable as well. 7) Redundant cairo calls. It would probably be OK to just call cairo_set_line_width() and cairo_set_antialias() once. 8) Highly redundant prelight drawing. I basically copied the same piece of code around, with adjustments. It should be made into a function. Also, a boolean check for highlight_enabled should be done earlier, not in _gtk_w32_prepare_highlight_*. Possible visual improvements (regardless of complexity): A) Fix expander to draw non-antialiased arrow. B) Fix combobox background color C) Fix menubar items to have correct prelight and active styles (right now they only have prelight, and prelight is applied when active should be) D) Fix black lines at the edge of expanded textview (no idea why they are there; probably a css problem) E) Fix separators to look w32-ish (etched gray-and-white instead of black lines; requires wide separators to be enabled in css; tried that - didn't work as expected) F) Make text antialiased (requires cairo patching, AFAIR) G) Maybe draw a different spinner (current one looks very un-w32-ously) H) Fix notebook tabs
Created attachment 244395 [details] [review] The stylesheet i've used with this code To be placed into %LOCALAPPDATA%\gtk-3.0
Created attachment 244396 [details] This is how it looks right now
Published my patches on http://lrn.no-ip.info/gitweb/?p=gtk%2B;a=shortlog , as requested. Not sure how to make a pull request...or whatever you need me to do.
With the new changes in gtk what about forcing adwaita on classic?
we default to adwaita on all platforms now
Sadly, until W8 the Classic theme means disabling desktop composition, which breaks RGBA windows (i haven't done much testing in 8; i know desktop composition stays enabled there, always, but i'm not sure whether they fixed the classic theme to work through all the same channels as normal themes do). Which is why i've stopped caring about this bug - desktop composition is just too useful (for various reasons) to give up for classic looks, and i'm still running W7. To remind about the problems this bug has: last time i took a stab at it, GTK didn't provide enough CSS selectors to draw the right thing everwhere. For example, there was no way to draw notebook tabs and, more importantly, notebook body differently depending on tab orientation.
Hi, For records. I think since we are already using Adwaita for all platforms, it would be better for us at this time to make sure things are okay there under Windows. It would be nice to have a native look-n-feel, but it's not a top priority for now, so if and when we want to come back to this, we can either re-open the bug or open up a new one, given that GTK+-3.x evolves really quickly. So, we ought to forget about this bug for the moment, at least. With blessings.