X11 - How to get system colors? - x11

I'm using X11 lib. Is it possible to get system colors? I mean from current user theme like face, highlight color etc. I can't use GTK and QT libs. Exists any way to get colors by some environment variable or freedesktop?
Regards

Prepare for some serious pain and confusion and anger. It could be all so simple, weren't both Qt and GTK+/GNOME serious cases of the NIH syndrome.
In X11 there is a system called X resources database which is effectively a key → value store where key and value are both strings and contained within a property of the root window. You can access it using the xrdb tool. Any well behaved X11 program uses this X resource database to adjust its appearance to that the user set.
The traditional X11 toolkits, Motif, Tk, Athena, Xaw3 and such conformed to this. And everything was well. And because there were set a simple, unambigous set of pattern matching rules nearly every aspect and every single widget could be themed this way.
When GTK+ and Qt were born they too adhered to the Xrdb. But soon the GTK+ and Qt developers said "this is not of our design, we do it our way", so GTK+ and Qt retrieve their settings from dotfiles in the user's homedirectory. And for compatiblity reasons also respect some, but not all, and with every version a different set of Xrdb keys.
Of course desktop libraries ought work together and so a lot of settings mangement systems were born: Elektra, gconf, dconf, uconf, and specifically for X11 Xsettings. gconf, dconf, uconf don't use the X11 protocol of course but propritary IPC or DBus. DBus in itself is rather flawed.
Xsettings however is a specification that's full of contradictions, doesn't work nearly as well as Xrdb does. The main "reason" for Xsettings to be there is, so that clients could be informed about changes, because instead of a property on the root window all the settings were managed by a Xsettings deamon, informing all clients on the screen of a change. And should the daemon die things would go back to default, because clients were supposed to register for the event emitted when the Xsettings daemon's InputOnly property holder window would go away. I have only one word for Xsetting wahrrrgarrrbl.
The Xsettings creators obviously never thought of that changing a window's properties creates a X event by itself, that allows clients to listen for settings changes. Also it makes no sense to get informed about settings changes only, because this requires all clients to keep track of their local settings state, even if some of their internal settings only indirectly depend on some settings. Parsing the whole Xrdb is easier, less error prone and the theoretical overhead savings of only processing a subset of changed settings is in stark contrast that settings don't change all the time.
It's on a long TODO list of mine, to strip Qt and GTK+ of the whole gconf, dconf, uconf, Xsettings and their propriatary config dotfile mess and make them use Xrdb and nothing else.

Related

Wayland detection from root user

I have a script that must be launched as root. I need to detect the graphics system and identify it (windows X system, Wayland).
I tried using some environment vars like ${XDG_SESSION_TYPE} or ${WAYLAND_DISPLAY} which are revealing if you are using x11 or wayland, or if you are in a headless system... but, the problem is that the vars are not working from root user. As you know, the graphics environment is usually launched by a normal user and as I said at the beginning of the question, for reasons that I'm not going to explain here, the script needs to be launched as root.
Next screenshot is showing only one common element between users, the XAUTHORITY var...
I could use that but I think that could be a very dirty way to do it. It must be a better way. Any suggestion? Thanks.
The only reliable method is for you to obtain the report, from the environment by a non-root user ID, of the XDG_SESSION_TYPE variable's value.
For X-Windows, XDG_SESSION_TYPE=x11
For Wayland, XDG_SESSION_TYPE=wayland
However, as datenwolf stated, since root is specifically hindered by hard-coded security precautions, even if you customized your root's .bashrc, you won't be able to get the GUI to respond reliably, if at all, depending on the tools and elements you use.
If, on the other hand, you are attempting to build a tool for specific use by high-level security specialists, then you will likely require a customized build of the OS (removing those hard-coded security blocks) to complement those tools. That ... is a huge task, which only those with deep pockets and unlimited resources ... can allow themselves to contemplate ... unless the developers were smart enough to anticipate such a need and have all those code segments "drop-out" during compilation with the appropriate compile-time flag turned on/off. :-)

Should terminal applications guess what the user wants?

There was a small discussion about what git does and doesn't do by default for the user.
By default, colour is disabled (generally set up with git config), yet it sends its output to a pager application for certain commands (such as in git log).
One side to this would be that no flags should be enabled since it gives the user full control of the application. The contrary would state that when releasing a new application, one should try and win users over as quickly as possible with as many bells and whistles as possible.
This is probably a very subjective question, but in the year 2010 should terminal applications start making usability decisions by default or force its users to customize it.
$ rm file.txt </dev/null
Do you want to remove file.txt [y/n]
tty not connected, guessing "no"
So no; please avoid any assumptions because they can turn out to be the exact opposite of what is expected.
Color in git diff is disabled by default, because pagers may not support it — this is the case even for less, which needs to be explicitly invoked with the -R option to turn on escape sequence support.
if there are conditions when something acts differently like in the case of color when the output is a tty vs a pipe it should be clear what this condition is but git log doesn't check for this but some other programs do like ls in it's --color=auto mode
in the case of git log with --color it uses less with color escape code pass though on
if you want to override it give them a like a --color[=WHEH] option like ls has which can force color on regardless of the type of the output
--color[=WHEN] control whether color is used to distinguish file
types. WHEN may be `never', `always', or `auto'
the auto mode is what i describe in the first paragraph
the default should be the one useful to the users of the program, if there are cases where that default isn't what is wanted that's what options are for
The terminal applications are no exceptions. See oracle import (imp) it provides sensible defaults so even though it asks questions but a default selection is given a naive user would go for it unless he is really sure about that option. or even create database in oracle which has a smaller version which assumes all sensible defaults and an extended version.
One side to this would be that no
flags should be enabled since it gives
the user full control of the
application
User will learn to use full control if he actually starts using it. For instance I was evaluating workflow engines, open source ones, imagine for every workflow engine I needed to setup full infrastructure like database table structure before it even gets up and run. Instead one of the most sophisticated workflow engines gives nice HSQLDB implementation which works great for evaluation.
Once something starts working I can tweak it to suit me, rather than spending days on a software which seems quite dead in the beginning.

Choosing Windows File Open and File Save Dialogs - What is the Best Practice?

For some time I've noticed how much the File Open and File save dialogs vary between Windows itself and Applications. In Delphi for example (which I use) you can use the built-in dialogs (which have a folder tree) and direct calls to the Windows API which produce variants of the Windows version, with or without large buttons for 'Desktop', 'My Computer' etc (At least on XP).
As an application developer I'm interested in providing the User with a clean, simple way of loading and saving files. Typically, this requires that I propose a preferred folder where my Application data files are stored but that I allow the User to access other folders - often the desktop and other local drives, and sometimes the network - without difficulty if required.
With the introduction of Vista, we seem to be favouring a 'bits missing' folder navigation tree for Windows dialogs and now, Windows 7 has another 'line-less tree' for navigation. I suspect that if one conforms to Microsofts assumptions and stores everything in ~/documents it's not a big problem. However, if one has to start at the root of a drives tree and there are many directories then it's a right pain - there is no horizontal scrolling so directory names get truncated.
My question is - what do other Application developers use? I wonder whether I should be following this Windows lead or simply sticking to a simple cut-down version of File dialogs over which I full control but risk falling into the past....?
Thanks
Brian
Always use the OS defaults - it'll be what your users are used to, and what they expect. Whatever you do, don't astonish the user. Whatever you do, please don't write your own file-open/file-save dialog.
FWIW, I'm not a great fan of Vista's file-open dialog (why do I have to work so hard to navigate my folders?), but I'd rather that than have to get to grips with something new. The less things your users have to learn, the easier your product is to use.
Since I am currently only coding for customers with Windows XP (in a corporate environment that isn't upgrading just yet) I use the standard dialog boxes.
When we do upgrade, I will most likely continue to use the standard old fashioned dialog boxes, until our customers are ready for a change.
In all honesty, I involve at least a few users in the development process, and I won't start new features unless I can bring one in to sit in front of my development PC to see how it works, and they sign off on it.
For those apps that we write for our web site, we tend to be conservative as well... Focus on clean, understandable design, and introduce fancy new features only when there is a compelling reason, and even then, we tend to involve focus groups.
So all that was a long way of saying "Ask your customers". Give them what they want.

Confusing _NET_SUPPORTING_WM_CHECK

I am trying to make my window manager conform to the ICCCM specifications. I fully understand the reason for the _NET_SUPPORTING_WM_CHECK atom - this ensures that no invalid information stays whenever the window manager isn't running anymore.
What I don't understand is why are no other atoms like _NET_NUMBER_OF_DESKTOPS expected on the supporting window besides _NET_WM_NAME and _NET_SUPPORTING_WM_CHECK itself.
Window managers are supposed to set and overwrite the data but this can be misleading in the case the new window manager isn't compliant.
Well the atoms that you are talking about are not the ICCCM.
They belong to the newer set of EWMH
So basically it goes like this.
First we had the ICCCM.
They are
old
mature
supported by most window managers (in full or in part)
easy to implement
Unix standard
Then we had EWMH that are
newer (GNOME and KDE)
not many window managers support them
more complex (e.g. virtual desktops)
A freedesktop standard.
Freedesktop wanted to make the EWMH as broad as possible (apart from GNOME and KDE)
and that is why most of the atoms are SHOULD and not MUST. They are giving a chance to small window manager to claim compliance.
I think the idea is you have to check whether a property is supported, and only use it from the root window if it's supported.
The _NET_SUPPORTING_WM_CHECK window was added later after a lot of the other properties already existed, if I remember right.

How do you control printer tray selection for printer in Windows

We need to be able to change the default selected print tray of a given printer. Does anyone have VC++/win32 code for doing this?
In case it matters, I believe we have to change the default setting for the printer. Our print jobs are executed by an application other than ours, so we can't make these kinds of changes in the context of a print operation originating from inside our application. Unless there is some way to modify the default print settings in a different application, I think we are stuck changing the user's defaults for the printer, initiating our print job, then setting the defaults back to the original values.
We'd really prefer to have the defaults change for the current user only, and not require any special UAC elevation, etc...
I suspect that it will use something similar to what is shown in this MSDN article, and involve setting fields in the DEVMODE structure (either dmDefaultSource or dmFormName or both).
Any takers? Or does anyone have any gotchas they'd like to share?
EDIT: Here is a link for DEVMODE documentation DEVMODE documentation
EDIT: I should also point out that we are looking for a general solution - not something specific to a particular printer (we deploy in many, many environments)
FYI - the solution we wound up using was to capture the DEVMODE structure. We have a small win32 app that presents the printer settings dialog (via DocumentProperties with fMode set to DM_IN_PROMPT). The resultant DEVMODE is then saved to disk. When we do our printing, we capture the current DEVMODE, set the stored DEVMODE, initiate the print, then restore the original DEVMODE.
This actually works quite well. Occasionally, the print drivers will update and cause the stored DEVMODE to break, but that doesn't happen very often and it's easy enough for users to fix.
As an extra bonus, this approach allows us to capture ALL of the printer settings (not just the output tray) - so we were able to support advanced settings like stapling, collating, etc...
Tip: If you try this, be sure to write to disk as a binary output stream. In my initial evaluation of this approach, I accidentally set the output stream up as a text output stream. Things would work fine for many cases, then suddenly break for some printers (that used high order bytes in their DEVMODE private data). A dumb, but easy, mistake to make - and one that took a very nice solution off the table for awhile.
Setting features like this can be tricky, especially if the driver doesn't follow Microsoft's print guidelines. That being said, we've had some success with System.Drawing.Printing.PrinterSettings. You can set PaperSource but I'm not sure you can set the defaults.
If you haven't seen this example you may want to look further at it. It describes a method to store and reload printer settings. One of my guys pointed it to me:
PrinterSettings - Changing, Storing and Loading Printer Settings
Another method, that could work but might not work for you, is to determine your the handful of setups you need. Install a printer with each of these (ie: Tray 1, Tray 2) setups. Then simply switch the default printer on print. Not what you are looking for but it may help.
What we typically do in these situations is have the 3rd party app write the data to a folder that we are monitoring, we then pick up the file and parse the Postscript or PCL ourselves and change the paper tray and then send onto the destination device. A lot simpler then it may sound.
dmDefaultSource controls the tray. Unfortunately the values you'll want to set this to differs depending on your driver as this is a bin number and not necessarily the same number as the tray# printed on your printer.
The following link provides some VB6 code for gathering information about your printers tray/bin assignments. You can use that information to programatically assign dmDefaultSource to the appropriate bin # for a tray. You basically need to use DeviceCapabilities to return information about your printers and then search for a string (like "Tray 1") to get the associated bin number.
http://support.microsoft.com/kb/194789
I had to do something very similar recently on a specific printer driver and it required a vendor specific SDK. The tray doesn't seem to appear in DEVMODE or any of the other PRINTINFO_* structures so I guess I'd drop an email to the printer vendor.
As a last resort, I can think of two possible hacks. One is to automate the driver at GUI level using a scripted tool such as AutoIT. Second is to dump the registry to file, change the driver setting, dump the registry again, and compare the differences (may or may not work).
As far as I know, printers are controlled by the printer driver by sending them SNMP or PJL commands. But not all printers implement completely these sets of commands.
For HP printers I found at: http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?lang=en&cc=us&objectID=bpl07282&jumpid=reg_R1002_USEN some PJL commands (there are some related to the tray too).
I'm not sure this help, but take it as a hint for future searches...

Resources