I have a CView that acts as a placeholder for several Ctrl's stacked vertically so as the occupy all available space. What I wish to do is grab a horizontal boundary with the mouse and drag it up or down to resize Ctrl height.
The problem being that the child Ctrl's of the CView intercept the mouse messages and not the CView parent window (WM_LBUTTONDOWN, WM_MOUSEMOVE etc). The Ctrl's also handle these messages for unrelated editing requirements.
Would anyone be able to offer advice or supply a reference to possible solution(s) to this sizing/editing requirement. The situation is some what similar to the resource editor in Visual Studio. Only I wish to edit in a live environment.
I think this could easily be done as follows:
Leave a small gap between the child controls (say 2 or 3 pixels). This could be drawn in the same color, or a slightly different shade.
Set the cursor to IDC_SIZENS for the main CView.
Handle the mouse messages (when the mouse is over that gap) in the main CView (down, move, ..).
On 'dragging' resize the child controls.
That way all messages would still go to te child controls, except when the mouse is above those 2 to 3 pixel 'splitters'.
If leaving a small gap is really no option, than you would have to capture all mouse messages in the CView and check if they are on a border. If not, forward (or default) them to the child window below the mouse cursor.
Related
I have a program using glfw for window management and opengl for rendering. The program works on Windows and linux, and eventually Mac OSX so I want any solution to be portable.
glfw seems to either support a cursor, or getting full mouse input but not both. For example, with the cursor enabled (default) the glfwscroll_callback does nothing. If I disable the cursor, then scrolling the mouse is captured but then the user cannot see where the mouse pointer is. That's ok if I can draw the cursor myself when I want but I cannot find any function to drawcursor at a particular location.
How does the cursor work, ie what is the hardware basis for the cursor? Is there a sprite in hardware still? If it's all in software, I suppose we could draw a cursor at the current mouse location the last thing in render. But that's not convenient. For one thing if the scene hasn't changed, I shut down rendering completely to reduce power.
Is there any way to manually draw a cursor on top of the current screen so that we don't have to manage the buffers manually? Is my only option to change the logic and not render the scene if nothing has changed, but to manually draw a cursor on top of the current scene every frame?
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.
Can I have a frameless but resizeable window in X?
Setting just MWM_DECOR_RESIZEH without the other flags doesn't make it resizeable.
I can resize it myself manually but then I need to scrape for themed mouse cursors which are non-standardized and are also different for each corner and side.
There are exactly two ways to resize windows:
Leave it to the window manager and be happy. This is recommended way for X. If someone don't like it, he can install another WM that will make it better.
Make it by yourself - draw border around window, track the mouse cursor and when the user drags the edges - resize the window in a way you like. In this case you must set the override-redirect flag of the window and WM will not mess with it.
I'm pretty new to javafx so I'm trying to learn here so please be reasonable and don't dis away my question, I really appreciate any help at all, thanks!
I would like to know how I could move an object, let's say this circle on different events, like keypress or mouseclick, mousemove, whatever.
Circle circle = new Circle();
circle.setCenterX(100.0f);
circle.setCenterY(100.0f);
circle.setRadius(50.0f);
Do I need to use that KeyFrame thing I saw on the javafx site tutorial, or how does this work?
I would not have asked this here if I weren't feeling so lost, honestly.
So to make this clear: What is the code for moving objects that I created, by using events?
EDIT: By moving it I mean, press up key and it moves up by a few pixels, transform it maybe, with another key, or click somewhere on the scene and make it move there instantly or travel there with a certain speed. I don't have to redraw it like you need to with html5 canvas, I hope, right?
I don't have to redraw it like you need to with html5 canvas, I hope, right?
Not if you are using a standard JavaFX scene graph as opposed to a JavaFX canvas.
I would like to know how I could move an object, let's say this circle on different events, like keypress or mouseclick, mousemove, whatever
There are three ways to move a Shape:
You can adjust the shape's geometry (e.g. the centerX/centerY properties of a circle).
You can adjust the shape's layout (e.g. it's layoutX/layoutY properties).
You can adjust the shape's translation (e.g. it's translateX/translateY properties).
You can think of the layout as the home position for the object; i.e. where it should normally be in the context of it's parent group. You can think of it's translation transform as a temporary position for an object (often used when the object is being animated).
If you are using a layout pane such as a VBox or TilePane, then the layout pane will handle setting the layout co-ordinates of the child node for you. If you are using a simple Group or a plain Pane or Region, then you are responsible for setting the correct layout values for the child nodes.
To listen for events, set event handlers on Nodes or Scenes.
Here is a small sample app which demonstrates the above. It places the object to be moved inside a Group and modifies the position of the object within a Group in response to various events.
I have several nested X Windows - let's say - a scrollable window within a scrollable window (see the example below). In such case the main window contains (at least) the major scroll bars and the (major) drawing area they control. This drawing area on its turn contains (at least) a scrollable window batch - a (minor) main window, containing a scroll bar and minor drawing area.
During live scrolling of an inner drawing area the redraw procedure messes up, because I am using the XCopyArea to speed the process and move the contents that are valid and invoke the actual redraw routine for just the newly appeared content. This works fine when the inner drawing batch is by itself, but when nested within another one a problem occurs - when the inner scrolling-batck is partially visible (i.e. the major drawing area is scrolled) redrawing of newly appeared contents is clipped from the major drawing area and never actually redrawn, but considered to be so. When on the next scroll XCopyArea gets this supposedly-redrawn area it is actually empty. Finally this empty area show up on the partially visible inner scrolling-batch and it is empty. On the first general redraw message they are fixed.
If I can obtain the clipping mask for what is actually visible from (my) inner drawing area I can adjust the XCopyArea() call and redraw call and overcome the problem without the plan "B" which is redrawing all contents on each scroll bar movement.
Example: Developing a plugin for Mozilla Firefox and needing to determine the region that describes the visible area of "my" window, i.e. the one that is passed from the Mozilla system as plugin viewport.
If its really an X Window you get, and not a widget from some specific toolkit (like GTK+ maybe?) then you can use the XGetWindowAttributes function call.
This fills out a provided XWindowAttributes structure, which includes integers for the x and y position of the window as well as its width and height and other useful facts.
But in reality I think you are probably using the Mozilla plugin API inherited from Netscape, aka NSAPI, and in that case what you get is a call to your function NPP_SetWindow() at least once (and again if necessary because something changed) with a structure which contains the information you're looking for. Try looking at http://www.mozilla.org/projects/plugins/ for more information about the APIs you should use.