preventing window maximisation/minimisation in x window system - c++

i'm writing some low level window code for a window in x (in c++), and I want to prevent the user from either maximising or minimising the window. i don't mind whether this is done by rejecting the request to resize, or by removing the buttons themselves. however, i am tied to x and can't use qt or other higher-level libraries which i know provide this functionality.
at the moment all i have managed to do is intercept the ResizeRequest event and then set the window size back using XResizeWindow... but this causes the window to momentarily maximise and then return to its original state. is there a way to directly reject a ResizeRequest, that would seem to be the proper way to handle this but a fair bit of googling and document trawling has not come up with a solution.
thanks,
james

you can't.
essentially you would fight like hell against the window manager (and against the user in the end).
eg, you could watch PropertyNotify events to check if your window (or rather the window your window is attached to (provided by the window manager)) gets minimized. and then you unminimize it. and then the user minimizes it, or the window manager. technically, you can fight against it, but i would strongly advise against it.
that said: you can try to give the window manager some hints about what you think is appropriate for the window. see http://standards.freedesktop.org/wm-spec/1.3/ar01s05.html#id2523223:
_NET_WM_ALLOWED_ACTIONS
is a property the window manager manages per window (to tell other tools what is possible with that window). one of such actions is
_NET_WM_ACTION_RESIZE indicates that the window may be resized.
(Implementation note: Window Managers can identify a non-resizable
window because its minimum and maximum size in WM_NORMAL_HINTS will
be the same.)
so, if your users are using a window manager which interpretes WM_NORMAL_HINTS correctly and drops any resizing, maximizing, minimizing: then you can feel lucky.
what do you really want to achieve? some kind of kiosk-mode? some kind of fair-trade mode where people walking by can not "shutdown", close, resize, fiddle around with the app you are presenting?
if so: consider running a xsession without any window manager involved at all. just start your app as big as you need it and done.

Technically you can't prevent anything, as WMs can do whatever they want, but most reasonable window managers will let you control this.
The preferred modern way to do it is to set _NET_WM_WINDOW_TYPE semantic type if any of those are applicable. For example, in many WMs a dialog type may imply not-maximizable.
http://standards.freedesktop.org/wm-spec/1.3/
It sounds like none of these apply to your app though probably, so you'll have to set the specific hints.
To avoid maximization you just want to make the window not-resizable. As you've discovered, "fighting" the resize by just resizing back is a Bad Idea. It has infinite loop potential among other things.
XSetWMSizeHints() is the correct way to avoid maximization. Set min size = max size. voila, not resizable.
To avoid minimization, you have to use a bit of old legacy cruft called the Mwm hints. Unfortunately this involves cut-and-pasting a struct definition and then setting a property to the bits of the struct.
I just googled for MWM hints docs, and one of the results is me suggesting documenting them, 9 years ago ;-)
http://mail.gnome.org/archives/wm-spec-list/2001-December/msg00044.html
Unfortunately, none of the results are actual docs.
You can likely figure it out from http://git.gnome.org/browse/gtk+/tree/gdk/x11/MwmUtil.h and gdk_window_set_mwm_hints() http://git.gnome.org/browse/gtk+/tree/gdk/x11/gdkwindow-x11.c#n4389
MwmUtil.h is the struct that's cut-and-pasted everywhere (into most WMs and toolkits).
The _NET_WM_ALLOWED_ACTIONS hint is set on your window by the WM indicating which features the WM has decided to put on the window. The main purpose of this hint is that pagers and task lists and other desktop components can then offer the matching actions for the window.
The specs that cover all this are the ICCCM (old spec, still mostly valid) and EMWH (new extensions and clarifications, since ICCCM left lots of things unaddressed).
For gory details, try the source code... for example recalc_window_features() in metacity's window.c file, currently on line 6185 http://git.gnome.org/browse/metacity/tree/src/core/window.c#n6185
A philosophical adjustment when coding for X: mileage will vary with window manager. The "mainstream" ones lots of people use generally will follow the specs and work about as you'd expect. However, there are all kinds of WMs out there, some broken, others deliberately quirky. The worst thing you can do is try to "fight" or work around the WM, because basically all ways of doing that will end up breaking the app when running with a sane WM. Your best bet is make things follow the specs, work with the normal WMs, and if you get users upset that they can resize your not-resizable window because their WM allows that, you just have to tell them to complain to whoever provides that WM. The whole point of the pluggable WM design is that the WM determines some of this behavior, rather than the app.
Good luck. Modern X is pretty complex and coding Xlib with no toolkit is kind of asking for things to be... not quite right. But you can probably get it going well enough. :-P

It's an old question, but, there is an unofficial, yet supported by most Window managers way to do such things - _MOTIF_WM_HINTS.
Look here: Disable actions, move, resize, minimize, etc using python-xlib for sample code.

Related

SDL2 events on mobile

I've fought for a couple of hours with a bug due to a behavior of SDL2 of which I didn't know anything.
In particular, I didn't know that, on mobile, whenever the user touches the screen, two events are sent:
The first one was quite obvious to me: a finger down event.
The second one was indeed less obvious: a mouse button down event.
The same applies for the finger up/mouse button up events.
Because of them, an internal command was thrown twice giving me an headache.
The target is to support both mobile and desktop environments for reasons that are beyond the purpose of the question.
Also, I can guess SDL2 works like that in order to support smooth migration of already existent codebase.
Anyway, is there a (let me say) SDL2-way to inhibit the mouse related events on mobile?
Honestly, they don't make much sense from my point of view and I would like to get rid of them, unless the software is executed on a desktop environment.
Also, I don't want neither to use compile time parameters nor to have dedicated parts of code the aim of which is to suppress those events on mobile.
The code is quite simple. Below a (maybe) meaningful, reduced example:
SDL_Event ev;
while(SDL_PollEvent(&ev)) {
switch(event.type) {
case SDL_FINGERDOWN:
// read it and throw an internal event E
break;
case SDL_MOUSEBUTTONDOWN:
// read it and throw an internal event E
break;
}
}
Unfortunately, both the events above are read when the user touches the screen, as explained.
* EDIT *
I didn't mention that I was testing my application on an Android device and I'm far to be sure that the same problem arises on iOS.
See the response below. It seems indeed that the issue (that so far I've understood it is not exactly an issue) is mainly due to the way SDL2 treats by default finger events on Android.
Even though I really like the idea of Christophe to add an event filter, I've found that SDL2 already gives support for this problem in terms of an hint on Android.
In particular, there exists the hint SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH.
One can set it by means of the function SDL_SetHint. See here for further details.
It's as simple as:
SDL_SetHint(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1");
As from the documentation of the hint, by default it is set to 0 and that means that:
mouse events will be handled as touch events and touch will raise fake mouse events
That's true, it was my problem, but by setting it to 1 we can get what follows:
mouse events will be handled separately from pure touch events
So, no longer fake mouse events on Android devices.
The reason behind the default value is not so clear to me, but this one sounds really like the right way to achieve it.
EDIT (more details)
This change seems to be recent.
Here is a link to the libsdl forum where they were discussing the issues that arose as a consequence of the patch that introduced this behavior.
Someone had the same problem I had and some others were trying also to explain why the patch had been accepted.
EDIT: alternative solution
The hint SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH is available since SDL v2.0.4, so it seems that the only viable solution for lower versions of SDL2 is to use an event filter.
Anyway, I discourage to query the platform by using SDL_GetPlatform in order to decide if to set or not to set an event filter.
Instead, as from the documentation of both SDL_MouseMotionEvent and SDL_MouseButtonEvent, there exists the which parameter that:
[...] may be SDL_TOUCH_MOUSEID, for events that were generated by a touch input device, and not a real mouse. You might want to ignore such events, if your application already handles SDL_TouchFingerEvent.
Because of that, I suggest to set an event filter no matter of what's the underlying platform, thus to queue the events or to filter them if needed.
Unfortunately, there is no such platform specific deactivation parameter.
The cleanest way to do it would hence be in the initialisation code to query for the platform with SDL_GetPlatform() and, if mobile, set an eventfilter with SDL_SetEventFilter() which prevents the mouse events from being queued.
It's not exactly the answer you expect, but I see no other sdl alternative.
A simpler approach, if you control the code of your event loop, would be to set a flag instead of an event filter, and if the flag is set do nothing on the mouse event. This second approach is however not so clean, as you have to take care of platform specific behaviour in all your code, whereas it's much more isolated in the first alternative.

Multiple console windows from one Win32 console app

I've written a program based on an empty Win32 console app in VS2008 running on Win7 64bit. The program is entirely menu based spawning from a main.cpp which only calls external functions that lead to other interfaces based on the users needs (e.g. cashier, inventory, report, etc...). What I would love to do is provide a new console window for each interface.
Ideally it would close the main menu upon invoking any other interfaces and so on as the user progresses through its functions, including reopening the main menu when necessary.
The basis for doing it this way is that I'm starting a new semester next week diving deeper in OOP with C++ and I wanted to go over my text and complete the capstone project which progresses with the topics to ensure that I have all the basics down pat. As much as I would love to do this the smartest-easiest way, it's best if I stick to the limited knowledge presented in the book which only hints at STL and speaks nothing of additional libraries like boost.
I, of course, have searched on SO and elsewhere looking for the solution. I have found answers, most of them falling outside of my tight requirements, some dealing with building a console window from scratch. While from-scratch seems the most promising, it seemed to be dealing with those not using a robust IDE like VS and I don't know if it will cause more conflict than it's worth, or if it can even be used in multiplicity. The majority, however, left me with the impression it isn't possible. The one exception to this was linking a console to a process. This is what I hope is in my future!
What brought me to this was the need to present a clean look at each turn of events. At first I was fooling around with trying to clear the screen with a basic function like void clearScreen(int lines); but this will always clear from the bottom. So, if I clear the screen before the next interface it's still at the bottom. If I clear it then accept input, the prompt is still at the bottom.
In case it hasn't been clear up to this point. My question is:
Is it possible, within reason, to produce multiple console windows which are tied to processes, or is there an easy way which I do not know to manipulate the scrolling of the main console window?
Even though I "need" to stay within the confines of the baby-step process of traditional learning, I would love to hear any input aside from switching the app type.
This is more of an OCD issue than a requirement of the task, so if the effort isn't worth the benefit that's okay too.
There is no portable way of moving the cursor around the console window - in Unix/Linux, you can send terminal codes for that, in Windows I have no idea.
What would work cross-platform, but be terribly slow and not too nice, would be:
read your input character-by-character
remember where on the screen the next character should appear
redraw the whole screen after each key press
If you want to do better, you must turn to platform-specific solutions, or find a library which would do it for you (like ncurses in the Unix world), but I don't know if any of these fit in your requirements.
You can set the cursor-position on Windows using SetConsoleCursorPosition.
Since you were saying something about VS, I assume restricting yourself to Windows isn't a problem. If so, you can use the Windows API for this.
Other than that, ncurses seems to be at least partially ported to most common platforms.
If you were looking for a way to do this in standard C++ - it doesn't exist. C++ doesn't require the platform it's running on to even have a console, so there are no console manipulation functions.
Both aren't that hard to use, but if this is really just some student thingy where you expect to learn something useful you probably shouldn't bother. Console manipulation isn't something you'll have or want to do very often.
Although it may not have been clear in my original question, I was looking for a solution to be used in a console window. Ideally the solution would have been operable on at least Linux and Windows because any programs I write for school must be compiled on each. This wasn't an assignment but it's obviously advantageous to learn things that are usable there as well.
Here's what I found ...Solution thanks to Tim Wei
void clearScreen()
{
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
}
This, as simple as it is, was exactly what I was looking for. The function clears the screen and puts the cursor at the top of the console window providing a way to provide static headers or titles with changing data tables. It also allows for simple text based animations - if you like that sort of thing. It made a significant difference in the look, feel and consistency in my console applications this semester!

Why does my DirectInput8 stack overflow?

The overall program is too complex to display here. Basically, just pay attention to the green highlights in my recent git commit. I am very new to DirectInput, so I expect I've made several errors. I have very carefully studied the MSDN documentation, so I promise I'm not just throwing this out there and stamping FIX IT FOR ME on it. :)
Basically, I think I have narrowed down my problem to the area of code around Engine::getEvent (line 238+). I do not understand how these functions work, and I've messed with certain pieces to achieve different results. My goal here is to simply read in keyboard events directly and output those raw numbers to the screen (I will deal with the numbers' meaning later). The problem here relates to KEYBOARD_BUFFER_SIZE. If I make it small, the program seems to run fine, but it outputs no events. If I make it big, it runs a bit better, but it starts to slow down and then freeze (the OpenGL window just has a rotating color cube). How do I properly capture keyboard events?
I checked the return values on all the setup steps higher in the code. They all return DI_OK just fine.
Your code seems to be okay (according to this tutorial, which I have used in the past). The use of several stack-based arrays is questionable, but shouldn't be too much of an issue (unless you start having lots of concurrent getEvent calls running).
However, your best bet would be to stop using DirectInput and start using Windows Raw Input. It's best to make this switch early (ie, now) rather than realise later on that you really need to use something other than DI to get the results you want.

Is it acceptable to use a hidden window in a server application on Windows?

I'm thinking about using WSAAsyncSelect in a server. But then I need a window to receive the message.
Is such a (hidden) window acceptable in a server app without a GUI? Can it lead to unexpected problems?
Using a hidden window is probably ok, or even better, use a message only window.
Is there any reason why you can't use WSAEventSelect and events instead?
It can lead to problems, if you react to certain messages that can be broadcast (or sent directly with malicious intent). The proper way is to ignore them under such circumstances. Obviously a "rogue" process could send stuff to your window in its hidden state. The reason I say it can be a problem, because this is exactly what allowed for shatter attacks some years back. Higher privilege processes accepting messages from lower privilege processes.
In newer Windows versions the integrity levels and the ChangeWindowMessageFilterEx function (et. al.) help to lower risks.
Personally I think you didn't give enough data to make an assessment of the situation with the certainty that you probably expect. I just want to make sure you understand that, yes, even for a hidden window there are risks involved and that you should take precautions to mitigate them. But I agree with Anders, why not use WSAEventSelect and drop the window?

Parse information from programs added to taskbar with C++

Basically what I am trying to do is write my own pseudo task bar in C++. The program needs to idle until another program is started up, at which point it needs to visually depict that the other program is running. For each other program that is running, the user should be able to click on the visual representation and have Windows switch focus to the selected program.
The big underlying question at this point: is this even a possibility? Or has Windows hidden most/all of its fiddly-bits to make this close to, if not completely, impossible?
[EDIT:] restructured the question
The obvious starting point would be SetWindowsHookEx(WH_SHELL,...); which will get you notifications when top-level windows are created or destroyed (along with some other related events, like a different window being activated, a window's title changing, etc.)
Think ahead to actually bringing the window to the front, as I once researched myself.
SetForegroundWindow() won't work unless issued from the foreground process - neither SwitchToThisWindow() nor the AttachThreadInput() kludge seemed to always work, but maybe I just wasn't doing it right. Anyway as far as I know there no way to make a window foreground as good as Windows does, please enlighten me if say you discover say an undocumented call which actually Works.
It seems possible to me at least in a basic way:
1. Set up a shell hook as described by Jerry
2. figure the executable file from the module handle to access it's icons using shell services
The Vista-like feature of keeping a 'live' miniature of the screen seems much more challenging.