Howto prevent a CFrameWnd from being mouse moved - visual-c++

I have an application that displays a CFrameWnd that is displayed on top of the main window. I need the window to be non-movable and non-resizable when the user selects a certain mode for the window.
My CFrameWnd is created with the styles WS_OVERLAPPEDWINDOW | WS_THICKFRAME | WS_POPUP
I have come across a solution using an overload of CWndOnNcHitTest to rewrite
HTLEFT,HTRIGHT,HTTOP,HTTOPLEFT,HTTOPRIGHT,HTBOTTOM,HTBOTTOMLEFT,HTBOTTOMRIGHT,HTSIZE,HTCAPTIONto HTBORDERto prevent the framework to recognize the areas responsible for sizing / moving.
This method works well for resizing in my case, but moving the window is still possible, although the hittest override works correctly (verified with traces).
Is there anything wrong in my approach, or could there be something interfering with this solution and if so, do you have any tips on where to look?

You should be able to make OnNcHitTest() work, don't return HTCAPTION.
Still, there's more than one way to move/size a window, you also have to worry about the system menu (type Alt+Space). Write a message handler for WM_MOVING and WM_SIZING and override the RECT so the window stays put.

Related

How to make an overlay which capture no events

I would like to draw some sort of window on top of all the other windows. For example, to display some debugging infos (like conky) or things like a timer.
The main thing is that I would like to able to continue using the other windows while using it (the events go through transparently).
I've tried doing it with pygtk, pyqt and others but can't find a way to make it a real overlay with no event capture.
Is there some low-level x11 solution?
I think the Composite-extension-approach will not work when a compositing manager is running (and thus Composite's overlay window is already used).
Since you explicitly mention "no event capture":
The SHAPE extension allows to set some different shapes for a window. Version 1.1 of this extension added the "input" shape. Just setting this to an empty region should pretty much do what you want.
Some concrete example of exactly what I think you ask for can be found in Conky's source code: http://sources.debian.net/src/conky/1.10.3-1/src/x11.cc/?hl=769#L764-L781
Edit: Since you said that you didn't find anything in Gtk (well, PyGtk), here is the function that you need in Gtk: https://developer.gnome.org/gdk3/stable/gdk3-Windows.html#gdk-window-input-shape-combine-region
You might need Composite extension + GetOverlayWindow request:
Version 0.3 of the protocol adds the Composite Overlay Window, which
provides compositing managers with a surface on which to draw without
interference. This window is always above normal windows and is always
below the screen saver window. It is an InputOutput window whose width
and height are the screen dimensions. Its visual is the root visual
and its border width is zero. Attempts to redirect it using the
composite extension are ignored. This window does not appear in the
reply of the QueryTree request. It is also an override redirect
window. These last two features make it invisible to window managers
and other X11 clients. The only way to access the XID of this window
is via the CompositeGetOverlayWindow request. Initially, the Composite
Overlay Window is unmapped.
CompositeGetOverlayWindow returns the XID of the Composite Overlay
Window. If the window has not yet been mapped, it is mapped by this
request. When all clients who have called this request have terminated
their X11 connections the window is unmapped.
Composite managers may render directly to the Composite Overlay
Window, or they may reparent other windows to be children of this
window and render to these. Multiple clients may render to the
Composite Overlay Window, create child windows of it, reshape it, and
redefine its input region, but the specific arbitration rules followed
by these clients is not defined by this specification; these policies
should be defined by the clients themselves.
C api : XCompositeGetOverlayWindow
PyGTK Solution:
I think the composite and shapes X extensions are sufficiently ubiquitous and shall assume here that they are active on your system. Here's PyGtk code for this:
# avoid title bar and standard window minimize, maximize, close buttons
win.set_decorated(False)
# make the window stick above all others (super button will still override it in the z-order, which is fine)
win.set_keep_above(True)
# make events pass through
region = cairo.Region(cairo.RectangleInt(0, 0, 0, 0))
my_window.input_shape_combine_region(region)
win.show_all()
# set the entire window to be semi-transparent, if we like
win.set_opacity(0.2)
Basically what this does is tell Gtk that other than pixel (0,0) the entire window my_window should not be considered part of itself in terms of event propagation. That in turn, according to my current understanding means that when the pointer moves and clicks, the events go to the underlying window under the pointer position, as if my_window was not there.
Caveat:
This does allow your overlay window being the focus window (due to user-solicited window switching or just because it pops up and gets the focus when your application starts). Which means that for example, keyboard events will still undesirably go to it up until the user has clicked through it to make it lose focus in favor of whatever window is under the cursor. I would likely use the approach described here to iron out this aspect.
If there's a different and proper approach for making a portion of the screen "display stuff but not receive events", without building an oddball window like above over it, I'm happy to learn about it.
I assume that one's particular desktop environment (gnome, unity, etc. on linux) may interfere with this solution depending on version and configuration, on some occasions.

JavaFX request layout does nothing

I'm absolutely confused.
Studying JavaFX for several months.
In my application I have a custom scrollpane, where I recount scrollbar values manually. Everything is OK there. And when I resize the window it also works fine.
The problem appears when I launch application the first time. I see that my scrollbar value is incorrect, and it become correct when I resize window or move the pane placed inside scrollpane.
So theoretically all i need is just update my scrollpane on window start, or after window start. And... I've spent more than week trying to find out how. And the only way I've managed to do this is to call layoutChildren recursively. This is awful of course.
layout() - doesn't have any effect. I tried it with runLater() and placed it inside timer call. No way!
requestLayout() - also makes no sense.
Is it possible just UPDATE or REDRAW or MARK CONTROL TREE AS DIRTY in JAVAFX ???
Ok well, try this way
first gaining the focus, then try relayout options..
blah.requestFocus();
blah.layout();
Well. layout() works. But it shouldn't be placed inside Platform.runLater().
In simple example everything is fine. Then I suggest I have something wrong with my controls.
Thanks.

Xlib center window

I am writing a Xlib app where I want the window to be centered. I have used XMoveWindow with (desktopWidth - width) / 2, (desktopHeight - height) / 2 and it is roughly in the right place.
However the problem is that width and height are the client area, not the total area. Is there any way for me to get the total area of the window?
I need to use Xlib because I am using Glx and OpenGL. I don't want to use SDL, nor have a bulky graphics library.
There are various ways to go about this, depending on why you are doing it. The first two are "officially supported" by most window managers and described in specs, and then it descends into fragile hacks.
Semantic
The specs encourage you to use _NET_WM_WINDOW_TYPE rather than setting the position, if it makes sense to do so. See http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html#id2507144
For example, a DIALOG type (or a window with the WM_TRANSIENT_FOR hint set) will usually be centered on its parent window or on the screen, and the _NET_WM_WINDOW_TYPE_SPLASH (splashscreen) type will usually be centered on the screen. "Usually" here means "sensible window managers probably center it, and people using weird window managers are not your problem, let them suffer."
(Another hint along the same lines, though not what you want here, is _NET_WM_STATE_FULLSCREEN, which avoids manually sizing/positioning in order to be fullscreen.)
If semantic hints work, the window manager code to handle the positioning is hopefully smarter than anything one can easily code by hand, for example it might deal with multihead setups. Setting the proper semantic type may also allow the WM to be smart in other ways, beyond positioning.
Gravity
If there's no semantic hint in the specs that helps you, then you can center by hand. It's important to note that window managers are allowed to ignore a manual position request and some of them will. Some may only honor the request if you set the USPosition flag in WM_NORMAL_HINTS (this flag is supposed to be set only if the user explicitly requested the position, for example with a -geometry command line option). Others may ignore the request always. But, you can probably ignore WMs that do this; the user chose to use that WM.
The way you compensate for the window decorations (the titlebar, etc.) is to use the win_gravity field of WM_NORMAL_HINTS, which is originally in the ICCCM (see http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.2.3) but better-specified in an implementation note in the EWMH: http://standards.freedesktop.org/wm-spec/latest/ar01s09.html#id2570420
For WM_NORMAL_HINTS see http://tronche.com/gui/x/xlib/ICC/client-to-window-manager/wm-normal-hints.html#XSizeHints (note: the type of the property is WM_SIZE_HINTS and the name of the property is WM_NORMAL_HINTS, so there are two different atom names involved).
To center, you would set the win_gravity to Center, which allows you to position the center of the window (including its decorations) instead of the top-left corner.
win_gravity is not often used and is likely to be buggy in some window managers because nobody bothered to code/test it, but it should work in the more mainstream ones.
Update, possible confusion point: There are other "gravities" in the X protocol, specifically the CreateWindow request lets you set a "bit_gravity" and "win_gravity"; these are different from the XSizeHints.win_gravity. The CreateWindow gravities describe how the contents (pixels/subwindows) of a window are handled when the window is resized.
Hacks based on guessing decoration size
It's a fragile hack, but... you can try to figure out the decoration size and then incorporate that into your positioning.
To get the size of the window decorations, one way is the _NET_FRAME_EXTENTS hint, see http://standards.freedesktop.org/wm-spec/latest/ar01s05.html#id2569862
For older-school window managers (but not the fancy new compositing ones, though those hopefully support _NET_FRAME_EXTENTS) the window decorations are an X window, so you can get your parent window and look at its size.
The problem with both of these approaches is that you have to map the window before the decorations are added, so you have to map; wait to get the MapNotify event; then get the decoration size; then move the window. This will unfortunately cause user-visible flicker (the window will initially appear and then move). I don't think there's a way to get the window decoration size without mapping first.
Descending further into the realm of awful hacks, you could assume that for windows after the first one you map, the decorations will match previously-mapped windows. (Not that this is a sound assumption: different kinds of windows may have different decorations.)
Implementation note: keep in mind that the decoration window can be destroyed at any time, which would cause an X error in any outstanding Xlib requests you have that mention that window and by default exit your program. To avoid this, set the X error handler when touching windows that don't belong to your client.
Override redirect
Using override redirect is a kind of bazooka with bad side effects, and not at all a good idea if your goal is just to center a window.
If you set the override redirect flag when creating a window, then the window manager won't manage its size, position, stacking order, decorations, or map state (the window manager's redirection of ConfigureRequest and MapRequest is overridden).
This is a really bad idea for anything the user would think of as a window. It's usually used for tooltips and popup menus. If you set override redirect on a window, then all the normal window management UI will be broken, the stacking order will end up basically random (the window will tend to get stuck on top or on bottom, or worse get in an infinite-loop restack fight with another client).
But, the override-redirected window won't have decorations or be touched by the WM, so you can surefire center it with no interference.
(If you just want no decorations, use a semantic type like SPLASH or use the "MWM" hints, don't use override redirect.)
Summary
The short answer is set the semantic hint if any is applicable, and otherwise use XSizeHints.win_gravity=Center.
You can kind of see why people use toolkits and SDL ;-) lots of weird historical baggage and corner cases in the client-to-window-manager interaction generally, setting window positions is just the beginning of the excitement!
win_gravity is not often used and is likely to be buggy in some window managers because nobody bothered to code/test it, but it should work in the more mainstream ones.
Apparently Unity haven't implemented this. Testing shows that XCB_GRAVITY_STATIC is not respected and by taking a quick look at Unity source code I could not find code implementing this part of the specification.

Magnifier like feature inside popup window....how to?

I need to create a magnifier like feature in my app. Like the "loupe" effect on the iphone !
The problem is that I need to do that inside a popup window and I don't get how to make it work !
The popup window display a grid of colors that I generate and draw one by one using shapeDrawables. What I want is to display that color bigger, zoom on it when the user touch and move his finger around the popup window (color grid). The idea is to create a tracking-zooming effect on the colors so the user can see more clearly under wich color his finger is currently located.
Problems are :
I can't seem to create another popup window on top of this one, Android limitation I think ?
If I modify the current shapeDrawable, resize it, change the boundaries, It needs to re-display the popup window before it takes effect (which is not acceptable of course)
So, anyone knows of a way I could draw over that popup window ?
EDIT :
I've tried solving this issue using a Custom Toast object...But it doesn't quite do the trick. It works, but toast object appears slowly and so the touch motion is not in sync at all with the user movement over the color grid.
I'm not sure if this will help you or not, but you might be able to accomplish this by using a second Activity... this second Activity would use Android's translucent theme if you include the following attribute in your manifest:
<activity android:theme="#android:style/Theme.Translucent">
This second activity will now only contain what you place in your layout. That is... the "real" activity you're running will still be visible behind it (anywhere you don't cover it up with views in the new layout).
You also might prefer Theme.Dialog if you really want to resemble a popup.
Something to keep in mind if you take this approach is you will probably want to override onWindowFocusChanged() in the new activity, and finish() in the event of you losing focus. Additionally, you'll need to figure out how to share your data between the two activities.

Problems with refreshing a draggable MFC window

Greetings.
I have to make a draggable MFC dialog window, which has a background - used that: http://www.codeproject.com/KB/graphics/picturewindow.aspx - and has several picturebox controls. I have tried two approaches, and while they do work, they have some problems.
First approach is "Manual" - on the LBUTTONDOWN message I check if it;s on a clean area of my window, and set a flag variable. On MOUSEMOVE, the flag is checked and if it's set, a MoveWindow function is called, and then, Invalidate(1). On LBUTTONUP, flag is unset.
This approach works correctly and redraws as needed, but is somehow very slow - if I'm moving the cursor too fast, the window falls behing and isn't dragged, as cursor's not over the window anymore.
The second approach is "Automatic" - I just call
DefWindowProc(WM_SYSCOMMAND, SC_MOVE+2,MAKELPARAM(point.x,point.y));
on LBUTTONDOWN, and it handles the rest, it's quick and never fall behind, but when I drag it over screen's edge ( so that some part of the window gets invisible), when I drag it back, all the controls get invisible and are not refreshed, background is okay. I suppose that's because Invalidate() isn't called during movement that way, as I actually call it after calling DefWindowProc() and so, everything is refreshed properly when I depress the button.
What should I do to improve either of those solutions? I need it both fast and correct. I may have not provided some required information, I'll add it is need arise.
Thanks in advance.
Solved the problem, by modifying the second way. I added a total redraw to the OnPaint(), and to get rid of flicker, I only redraw durng dragging, by using a flag variable.

Resources