Cannot get XCreateSimpleWindow to open window at the right position - x11

The following code opens a window of the right size, w,h, but not at the correct position, x,y.
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
using namespace std;
int main(int argc, char* argv[]){
Display *display; // A connection to X server
int screen_number;
Window canvas_window;
unsigned long white_pixel;
unsigned long black_pixel;
display = XOpenDisplay(NULL); // Connect X server by opening a display
if(!display){
cerr<<"Unable to connect X server\n";
return 1;
}
screen_number = DefaultScreen(display);
white_pixel = WhitePixel(display, screen_number);
black_pixel = BlackPixel(display, screen_number);
int x=0, y=100, w=300, h=400;
canvas_window = XCreateSimpleWindow(display,
RootWindow(display, screen_number),
x,y, // top left corner
w,h, // width and height
2, // border width
black_pixel,
white_pixel);
XMapWindow(display, canvas_window); // Map canvas window to display
XSync(display, False);
cin >> x; // just so that the program does not end
}
I compiled this with g++ xwindowtest.cpp -lX11 where g++ is version 4.6.2 and ran under Debian GNU/Linux.

The above solution is sort of correct, but not complete.
Creating a new top-level window on the desktop, and creating a new (child) window within the top-level window of your application use the same XCreateSimpleWindow() call, but the actual behaviour can be different.
When creating a new child window within your application you are in charge, and the origin coordinates (relative to its parent window's origin) and size you give for the new window will be honoured. In other words the window will go where you want it to.
However when creating a new top-level window on the desktop you have to deal with the pesky window manager, for example Motif, KDE, Gnome, etc. This intervenes when you create a top-level window to add borders ("decoration"), title, possibly icons, etc. More to the point it will, by default, ignore your requested origin coordinates in most cases and put the new window where it wants rather than where you asked it to put it. It is only when it has been mapped (somewhere) that you can then move it with XMoveWindow().
To avoid this you can ask, or in X11-speak "Hint to", the Window manager that "no, I want you to put the window where I ask, not where you want to put it". You do this with the following sequence:
(1) Define a XSizeHints structure.
(2) Set the flags bit in this structure with a mask of what you want to specify
(3) Populate the relevant arguments
(4) Call XSetNormalHints() on the newly created window (before you map it).
So in C code you would do:
XSizeHints my_hints = {0};
my_hints.flags = PPosition | PSize; /* I want to specify position and size */
my_hints.x = wanted_x_origin; /* The origin and size coords I want */
my_hints.y = wanted_y_origin;
my_hints.width = wanted_width;
my_hints.height = wanted_height;
XSetNormalHints(disp, new_window, &my_hints); /* Where new_window is the new window */
Then map it and - hopefully - it will be where you want it.

I usually declare a XSizeHints first and assign x,y coordinates etc to hints.
When creating x window you could do
XCreateSimpleWindow(display,
DefaultRootWindow(display),
hints.x, hints.y,
hints.width,hints.height,
borderWidth,
blackPixel, whitePixel)
That always works for me with 100% correct windows location.

I had the same problem. I am just starting with X11. Maybe others with more experience can clarify why this works (and simply specifying the x, y for XCreateSimpleWindow does not).
Here's my fix:
disp is your display, win0 is your canvas_window:
XMoveWindow(disp, win0, 200, 200);
XSync (disp, FALSE);
..... do something .....
XMoveWindow(disp, win0, 0, 0);
XSync (disp, FALSE);
... do something
When I run this code snippet, the window moves. You need to follow the XMoveWindow by XSync so that requests (such as a move) are handled appropriately.

Related

CRect member variables have strange values

I'm trying to use the member variables from my client rect, but they are holding extremely negative values, like -858993460. Even when I call rect.Width(), it returns an extremely negative number. I need the values to determine the corresponding section of a wave file to play when I select the wave that I have drawn on the screen. Would anyone happen to know why it could be doing this?
Note: I threw int's right, left, and width in just to see what values they are holding. I really only need rect.Width() to scale the selection to be able to access the data array of my wave file.
void CWaveEditView::OnToolsPlay32775()
{
// TODO: Add your command handler code here
CWaveEditDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(!pDoc){
return;
}
if(pDoc->wave.hdr==NULL){
return;
}
if(selectionStart!=selectionEnd){
CRect rect;
GetClientRect(&rect);
rect.NormalizeRect();
int right = rect.right;
int left = rect.left;
int width = rect.Width();
int startms=(1000.0*pDoc->wave.lastSample/pDoc->wave.sampleRate)*selectionStart/rect.Width();
int endms=(1000.0*pDoc->wave.lastSample/pDoc->wave.sampleRate)*selectionEnd/rect.Width();
WaveFile * selection = new WaveFile(pDoc->wave.numChannels, pDoc->wave.sampleRate, pDoc->wave.bitsPerSample);
while(startms<=endms){
selection->add_sample(pDoc->wave.get_sample(startms));
startms++;
}
selection->updateHeader();
selection->play();
delete selection;
}
The default constructor of CRect does not initialise its members (because it is a thin wrapper for the RECT structure). You could initialise it to (0,0,0,0) and check whether or not it is empty after your call to GetClientRect.
Since GetClientRect appears to be failing, you may want to check that your window handle is valid using GetSafeHwnd().

Showing a windows with XCB / Strange Behaviour

I'm trying to show a window in xcb, inside the main window, but actually without luck.
The idea is that when the user press a button (in that case the X button) a small white window is shown (just for test).
But actually i'm stuck on that step. I watched the example code here:
http://en.wikibooks.org/wiki/X_Window_Programming/XCB
And tried to do the same in my application.
[EDIT 28/10/2013] Now with that code i can show a window, but if i try to add other variable like int i=0, or whatever, the window doesn't appear, and no expose events were raised (all events that were raised are or 0 or 2 (even if i add the variables inside other events). Any idea?
This is the XCB_KEY_PRESS event handler code:
Edit (with the new code)
case XCB_KEY_PRESS:{
xcb_key_press_event_t *kp = (xcb_key_press_event_t *)ev;
if(kp->detail==53){
printf("X pressed\n");
uint32_t vals[2];
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
vals[0]=screen->white_pixel;
vals[1]=XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
win = xcb_generate_id(connection);
xcb_create_window(
connection,
XCB_COPY_FROM_PARENT,
win,
root,
80,80,
150,150,
10,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
mask, values);
mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
vals[0]=screen->white_pixel;
vals[1]=0;
background=xcb_generate_id(connection);
xcb_create_gc(connection, background, win, mask, vals);
xcb_map_window(connection,win);
xcb_flush(connection);
printf("finished\n");
}
printf("KEY_PRESS - Pressed: %d\n", kp->detail);
}
root is the root window obtained from xcb_screen_t variable.
The definition of background and win are the following:
xcb_window_t win;
xcb_gcontext_t background;
And i added even a XCB_EXPOSE event handler:
case XCB_EXPOSE:{
printf("EXPOSE NEW WINDOW CREATED\n");
xcb_poly_fill_rectangle(connection, win, background,1,&rectangle);
xcb_flush(connection);
}
What is wrong with that code? What am i missing? (I'm trying to develop a very basic window manager, just for fun)
(My idea for that program is that when x is pressed an input box is shown, do you have any suggestion on how to do that?)

How to get multitouch to work in QGraphicsView, Qt 5.0.2 in Windows 8

I am struggling with getting multi-touch to work on a couple of QWidgets that I have added to a QGraphicsView. I have created a subclass of QWidget in which I set up a QGraphicsScene and QGraphicsView. This is my (test) subclass of QWidget:
#include "qttest1.h"
#include <QtWidgets>
#include <QTouchEvent>
qttest1::qttest1(QWidget *parent)
: QWidget(parent)
{
setEnabled(true);
if(!QCoreApplication::testAttribute(Qt::AA_DontCreateNativeWidgetSiblings))
setAttribute(Qt::WA_NativeWindow);
setAttribute(Qt::WA_AcceptTouchEvents);
scene = new QGraphicsScene(this);
scene->setSceneRect(0, 0, 1920, 1080);
graphicsView = new QGraphicsView(scene, this);
graphicsView->setRenderHints(QPainter::Antialiasing);
graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
graphicsView->setAttribute(Qt::WA_AcceptTouchEvents);
graphicsView->viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
QBoxLayout *layout = new QVBoxLayout;
layout->addWidget(graphicsView);
setLayout(layout);
}
qttest1::~qttest1() {}
void qttest1::showGraphics()
{
for(int i = 0; i < 10; i++)
{
Dial *dial = new QDial();
dial->move(i * 120 + 50, 200);
dial->resize(120, 120);
dial->setAttribute(Qt::WA_AcceptTouchEvents);
QGraphicsProxyWidget *proxy = scene->addWidget(dial);
proxy->setAcceptTouchEvents(true);
}
}
This is my main:
int main(int argc, char **argv)
{
QApplication app(argc, argv);
app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
QRect rect = app.desktop()->screenGeometry();
qttest1 test;
test.resize(rect.width(), rect.height());
test.showFullScreen();
test.showGraphics();
return app.exec();
}
I know the code isn't pretty and probably leaking a bit, but the point is to try to get multi-touch to work.
I can see and use every kind of widget I add to the scene, but as soon as I touch a dial it swallows every touch that comes after the first. Which makes the dial jump between several positions. What I want is that every dial (or any type of widget) can be used individually and at the same time. I am using QT 5.0.2, Windows 8 with a monitor that supports up to 10 touches.
The Qt docs state : -
Reimplement QWidget::event() or QAbstractScrollArea::viewportEvent()
for widgets and QGraphicsItem::sceneEvent() for items in a graphics
view to receive touch events.
With that, I believe that you need to handle the QEvent::TouchBegin, QEvent::TouchUpdate and QEvent::TouchEnd events, which I don't see in the code you've posted.
Qt may handle the first touch for you, but it's not going to know what you want to do with the second, third, fourth etc. simultaneous touches. For example, you may want your app to do any of the following with the second touch moving: -
1) Rotate the object that the first item is over
2) Scale the object that the first item is over
3) Select the second item
4) Translate the view
5) etc.
So, you need to handle the consecutive touches to do what you want it to do. Also, you may want to look at Gestures in Qt.

Resize CMD Window

How can I resize the Command Prompt window programmatically in C or C++? For example 80x25 or 80x40 characters. Thank you in advance.
SetConsoleWindowInfo
The MODE command allows you to set the size of the Command Prompt window. The syntax is:
MODE [COLUMNS],[LINES]
For example for a 80x25 window you would use system("MODE 80,25");
This size is associated with a specific instance of the window so other command windows will be set to the default size. It works in both newer WinNT based OSs (i.e. Win2000/XP/7) and Win9x. If the size is not supported it will not change.
Place it before any output, as it clears the screen.
I did some more research and this is what I came up with:
#include <windows.h>
int main(){
system("mode 80,25"); //Set mode to ensure window does not exceed buffer size
SMALL_RECT WinRect = {0, 0, 80, 25}; //New dimensions for window in 8x12 pixel chars
SMALL_RECT* WinSize = &WinRect;
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), true, WinSize); //Set new size for window
//Insert your code here
return 0;
}

How do you use GdkRectangle to determine whether you size-allocate is growing or shrinking?

I have a callback for the size-allocate signal on my GtkScrolledWindow. I want to scroll to the right when I am adding stuff to that window. This works fine but introduces a subtle bug when removing items from that window. I would like to only scroll the window when adding stuff. I see the signal receives a GdkRectangle but I am unsure how to use it.
First size-allocate signal run-first, that means, If I'm not wrong, before the default handler. So you can get the GdkRectangle of the widget with gtk_widget_get_allocation, and compare it with the new one.
Now GdkRectangle is a cairo_rectangle_int_t and the definition of that is:
typedef struct {
int x, y;
int width, height;
} cairo_rectangle_int_t;
So you can check width and heights, with the old ones.

Resources