Bug 570502 - [GTK3] Readonly Combo ignored set background color
Summary: [GTK3] Readonly Combo ignored set background color
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.19   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 4.23 M1   Edit
Assignee: Alexandr Miloslavskiy CLA
QA Contact:
URL:
Whiteboard:
Keywords: usability
Depends on:
Blocks:
 
Reported: 2021-01-20 04:38 EST by Thomas Singer CLA
Modified: 2021-11-30 06:25 EST (History)
7 users (show)

See Also:


Attachments
Snippet to reproduce (922 bytes, text/plain)
2021-01-20 04:39 EST, Thomas Singer CLA
no flags Details
Screenshot from Manjaro (3.29 KB, image/png)
2021-01-20 04:39 EST, Thomas Singer CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Singer CLA 2021-01-20 04:38:40 EST
Run the attached snippet on Linux (tried with latest Manjaro). The combobox should have the same background color as the shell, but it hasn't.
Comment 1 Thomas Singer CLA 2021-01-20 04:39:17 EST
Created attachment 285320 [details]
Snippet to reproduce
Comment 2 Thomas Singer CLA 2021-01-20 04:39:42 EST
Created attachment 285321 [details]
Screenshot from Manjaro
Comment 3 Alexander Kurtakov CLA 2021-01-20 04:42:57 EST
Just tried and reproduced it. Also found that SIMPLE/DROP_DOWN combos work fine.
Comment 4 Alexandr Miloslavskiy CLA 2021-01-21 19:42:59 EST
I'll make a patch.
Comment 5 Soraphol (Paul) Damrongpiriyapong CLA 2021-01-25 17:22:12 EST
I could take over on this one if you are busy Alexandr. I'm looking to work on GTK3 bug this week. I am working on a patch on this as we speak.
Comment 6 Alexandr Miloslavskiy CLA 2021-01-25 19:04:42 EST
That's a bit unexpected. I have started working on this and identified that there's some problem related to how CSS is generated and/or applied. I replaced Combo functions to more reasonable ones and it started working fine, but I didn't have the time to figure what was wrong in the old code.

----
@Override
void setBackgroundGdkRGBA (long context, long handle, GdkRGBA rgba) {
	colorBackground = rgba;
	updateCss();
}

@Override
void setForegroundGdkRGBA (long handle, GdkRGBA rgba) {
	// TODO Why is this needed?
	OS.g_object_set(textRenderer, OS.foreground_rgba, rgba, 0);

	colorForeground = rgba;
	updateCss();
}

void updateCss() {
	if (cssProvider == 0) {
		cssProvider = GTK.gtk_css_provider_new();

		if (menuHandle != 0) {
			long context = GTK.gtk_widget_get_style_context(menuHandle);
			GTK.gtk_style_context_add_provider(context, cssProvider, GTK.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
		}

		if (buttonHandle != 0) {
			long context = GTK.gtk_widget_get_style_context(buttonHandle);
			GTK.gtk_style_context_add_provider(context, cssProvider, GTK.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
		}

		if (entryHandle != 0) {
			long context = GTK.gtk_widget_get_style_context(entryHandle);
			GTK.gtk_style_context_add_provider(context, cssProvider, GTK.GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
		}

		// TODO Why is this needed?
		OS.g_object_unref(cssProvider);
	}

	String css = "";

	// Deal with background
	{
		String clrCommonBack, clrMenuBack, clrButtonBack;
		if (colorBackground != null) {
			clrCommonBack = display.gtk_rgba_to_css_string(colorBackground);
			clrMenuBack   = display.gtk_rgba_to_css_string(colorBackground);
			clrButtonBack = display.gtk_rgba_to_css_string(colorBackground);
		} else {
			if ((style & SWT.READ_ONLY) != 0) {
				clrCommonBack = display.gtk_rgba_to_css_string(display.COLOR_WIDGET_BACKGROUND_RGBA);
			} else {
				clrCommonBack = display.gtk_rgba_to_css_string(display.COLOR_LIST_BACKGROUND_RGBA);
			}

			clrMenuBack   = display.gtk_rgba_to_css_string(display.COLOR_LIST_BACKGROUND_RGBA);
			clrButtonBack = display.gtk_rgba_to_css_string(display.COLOR_WIDGET_BACKGROUND_RGBA);
		}


		css += "* {background: " + clrCommonBack + ";}\n";
		css += "menu { background: " + clrMenuBack + ";}";

		// TODO: Fix Button
		// css += "* {background: " + clrButtonBack + ";}\n";
	}

	// Deal with foreground
	{
		String clrCommonFore;
		if (colorForeground != null) {
			clrCommonFore = display.gtk_rgba_to_css_string(colorForeground);
		} else {
			clrCommonFore = display.gtk_rgba_to_css_string(display.COLOR_WIDGET_FOREGROUND_RGBA);
		}

		css += "* {color: " + clrCommonFore + ";}\n";
	}

	// TODO Why is it needed to set selection colors?
	{
		String clrSelectionBack = display.gtk_rgba_to_css_string(display.COLOR_LIST_SELECTION_RGBA);
		String clrSelectionFore = display.gtk_rgba_to_css_string(display.COLOR_LIST_SELECTION_TEXT_RGBA);
		css += "* selection {background-color: " + clrSelectionBack + ";}\n";
		css += "* selection {color: " + clrSelectionFore + ";}";
	}

	// Update CSS provider
	if (GTK.GTK4) {
		GTK.gtk_css_provider_load_from_data (cssProvider, Converter.wcsToMbcs (css, true), -1);
	} else {
		GTK.gtk_css_provider_load_from_data (cssProvider, Converter.wcsToMbcs (css, true), -1, null);
	}
}
----
Comment 7 Alexandr Miloslavskiy CLA 2021-01-25 19:08:45 EST
I think I'd rather finish the patch myself, since I already started and spent some time on it. If you figured what was wrong in old code, I would appreciate to know, so that I don't have to spend time on this.
Comment 8 Soraphol (Paul) Damrongpiriyapong CLA 2021-01-26 10:24:19 EST
Sounds good. I haven't really figured out what is wrong with the old code either. But yeah I came to the same conclusion that it had to do with how the css was being generated and given to the GtkToggleButton.
Comment 9 Eclipse Genie CLA 2021-02-09 19:03:05 EST
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/176058
Comment 10 Alexandr Miloslavskiy CLA 2021-02-23 16:24:15 EST
I have very little time currently, but I'm still working on a patch.

The original problem was that if 'setForeground()' is called first, it eventually leads to 'gtk_css_provider_load_from_css()' being called with context for 'handle' instead of 'buttonHandle'. When 'setBackground()' is called later, it ignores correct 'context' because 'provider' is already allocated.

The code behind this is too complicated, with 5 functions, overloaded in a complicated manner where overload calls other functions with replaced parameters, etc. No wonder a mistake slipped through!

In my first version of the patch, I tried to separate css providers, and didn't notice that 'getForeground()' uses it to obtain foreground color. However, merging two variables is not straightforward, due to bug in 'gtk_css_provider_load_from_css' where provider is incorrectly unreferenced immediately and other issues.

I hope to finish the patch soon without letting it grow to gigantic size.
Comment 11 Alexandr Miloslavskiy CLA 2021-10-31 19:48:51 EDT
Just for information, I asked on GTK support if there's a better way to set colors to combo's internal widgets, but got no replies:
https://discourse.gnome.org/t/how-do-i-set-background-to-specific-gtkcombo-and-its-children/5691
Comment 12 Mickael Istria CLA 2021-11-10 09:33:50 EST
Too late for 4.22.