I'm trying to set my X11 cursor position. I tried calling XWarpPointer with the window set to None, root (DefaultRootWindow(display)), to the previously created window (XCreateWindow). The function IS being called, the mouse slows down a bit, but it does not physically move. Why could this be?
void GameWindow::ResetCursor() {
SetCursor(resX / 2, resY / 2);
}
void GameWindow::SetCursor(int x, int y) {
// Window root = DefaultRootWindow(display);
XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
XFlush(display);
}
EDIT: Here's the entire X11 Windowing file in case you can't find the reason here. https://gist.github.com/KarimIO/7db1f50778fda63a36c10242989baab6
The answer to this was relatively silly. I was using Gnome on Wayland, assuming it supported X11 as well. I assumed wrong.
Related
I am trying to "raise" (draw "on top" of other overlapping windows and possibly make "active") a specific window in response to an event. The official FLTK documentation seems to say that the Fl_Window::show() method is the way to do this. However, there is no corresponding WindowExt::show() (or any similar) method in fltk-rs.
There is a WidgetExt::show() method, but it does not raise a window when invoked. There is also a similarly promising but similarly disappointing DoubleWindow::platform_show() method.
What I have gotten to work is to call .hide() and then immediately call .show() on the window in question. This produces the desired effect of raising the window in question to the top of the pile. However, this
Seems hacky, right? Like going around one's rear to reach one's elbow.
Really does hide then show the window. On my Debian system running i3, this is almost unnoticeable (the flicker might just be standard window-redrawing), but under Windows this is terrible, because .hide()ing the window triggers a short (but oh-so-noticeable) fade-out animation (and .show()ing it a corresponding fade-in animation, plus there might even be a little shrink/grow action happening, too), which is bad user experience and looks like something is malfunctioning.
Here's an example:
use fltk::{
prelude::*,
app::App,
enums::Color,
frame::Frame,
window::DoubleWindow,
button::Button,
};
fn main() {
let a = App::default();
let mut sub_win = DoubleWindow::default()
.with_size(128, 128)
.with_pos(64, 64);
sub_win.set_border(false);
sub_win.set_color(Color::Magenta); // So you can see it clearly.
let _ = Frame::default().with_label("Sub Window")
.with_size(128, 128)
.with_pos(0, 0);
sub_win.end();
sub_win.show();
let mut main_win = DoubleWindow::default().with_label("Main Window")
.with_size(256, 128)
.with_pos(0, 0);
let mut b0 = Button::default().with_label("won't work")
.with_size(96, 64)
.with_pos(20, 32);
let mut b1 = Button::default().with_label("is hacky")
.with_size(96, 64)
.with_pos(130, 32);
main_win.end();
main_win.show();
b0.set_callback({
let mut sub_win = sub_win.clone();
move |_| {
sub_win.show(); // The FLTK docs suggest this should work.
sub_win.platform_show(); // This also disappoints.
}
});
b1.set_callback(move |_| {
sub_win.hide(); // This combination is what
sub_win.show(); // actually works.
});
a.run().unwrap();
}
If anybody knows the magic incantation I seek, I'd appreciate it.
Edit
I guess I didn't do enough investigation beforehand. The problem does not seem to be with fltk-rs specifically; in fact, it may not even be with FLTK; it might be specific to my X11 or window manager settings.
For example, the following C++ program exhibits the exact same behavior as the Rust one above:
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
Fl_Window *SUB_WIN;
void b_zero_cb(Fl_Widget *b) {
SUB_WIN->show();
SUB_WIN->redraw();
}
void b_one_cb(Fl_Widget *b) {
SUB_WIN->hide();
SUB_WIN->show();
SUB_WIN->redraw();
}
int main(int argc, char **argv) {
SUB_WIN = new Fl_Window(64, 64, 128, 128);
Fl_Box *sub_label = new Fl_Box(0, 0, 128, 128, "Sub Window");
SUB_WIN->color(FL_DARK_MAGENTA);
SUB_WIN->border(false);
SUB_WIN->xclass("Floating");
SUB_WIN->end();
SUB_WIN->show();
Fl_Window *win = new Fl_Window(0, 0, 256, 128, "Main Window");
Fl_Button *b0 = new Fl_Button(20, 32, 96, 64, "won't work");
Fl_Button *b1 = new Fl_Button(130, 32, 96, 64, "hacky?");
win->end();
win->xclass("Floating");
win->show();
b0->callback(b_zero_cb);
b1->callback(b_one_cb);
return Fl::run();
}
Several commenters report that the Rust version works as expected on their systems, and neither of the above programs work as expected on my system, so I'm going to assume it's an issue with my system.
If it matters, I am using X11 with the i3 tiling window manager. (I do have it configured so that the windows in these examples are all automatically placed in the floating layer and not tiled; I'm not that dense.)
I'm not sure what to do with this questions. Should I just delete it?
On the C++ end, Fl_Widget::show() is a virtual function that should raise the window, if the variable points to a top-level window (a window with no parent). On the Rust side, I see these lines:
extern "C" {
pub fn Fl_Window_show(arg1: *mut Fl_Window);
}
which seem to indicate that there is a direct interface for calling Fl_Window::show(), and the same for Fl_Double_Window.
I've read window(3NCURSES) man page, but I can't fully understand what mvwin() function actually does and what happens to its subwindows.
The code below creates a window with a title "Window" and a border, it also creates a subwindow that is used for printing y,x position without corrupting parent window border. It then moves the parent window to a new location, but the result is not what I expected:
After the window is moved, the outline of the windows border + text is not automatically erased at the old location.
After the move, writing text to a subwindow, outputs it at the old and new location.
After the move, parent window has new y,x coordinates, but subwindow still shows old coordinates.
I don't have a lot of experience with ncurses, and maybe I'm missing something, but this behaviour is completely illogical. If I have to manually erase windows at old location and manually move all subwindows, then this negates the benefit of using ncurses in the first place. I was expecting ncurses to automatically handle these low-level details.
My understanding of subwindows was that they are used to partition one large window into smaller non-overlapping areas. So when the parent window is moved or refreshed, all its subwindows should be moved or refreshed automatically. Is this correct?
#include <assert.h>
#include <ncurses.h>
#include <unistd.h>
int main()
{
WINDOW *win, *swin;
int lines, cols, y, x;
initscr();
keypad(stdscr, TRUE);
noecho();
// Create window
lines = 10; cols = 40;
y = 5; x = 5;
win = newwin(lines, cols, y, x);
assert(win != NULL);
// Create window border
box(win, 0, 0);
mvwprintw(win, 0, 2, " Window ");
// Create subwindow
swin = subwin(win, lines-2, cols-2, y+1, x+1);
assert(swin != NULL);
// Print window and subwindow y,x
mvwprintw(swin, 0, 0, "win y,x=%d,%d swin y,x=%d,%d\n",
getbegy(win), getbegx(win), getbegy(swin), getbegx(swin));
// Refresh
wnoutrefresh(stdscr);
wnoutrefresh(win);
wnoutrefresh(swin);
doupdate();
sleep(2);
// Move window
y = 20; x = 40;
mvwin(win, y, x);
mvwprintw(swin, 0, 0, "win y,x=%d,%d swin y,x=%d,%d\n",
getbegy(win), getbegx(win), getbegy(swin), getbegx(swin));
// Refresh
wnoutrefresh(stdscr);
wnoutrefresh(win);
wnoutrefresh(swin);
doupdate();
wgetch(swin);
endwin();
return 0;
}
Apparently not: a quick check with Solaris 10 gives the same behavior. You might find some scenario where ncurses differs unintentionally, but this is not one of those. The FAQ makes this point about compatibility:
extensions (deviations from SVr4 curses) are allowed only if they do not modify the documented/observed behavior of the API.
The Solaris manual page does not make this clear, since the only mention of subwindows is in regard to moving them:
The mvwin() routine moves the window so that the upper left-hand corner is at position (x, y). If the move would cause the window to be off the screen, it is an error and the window is not moved. Moving subwindows is allowed, but should be avoided.
The Solaris source code tells the story for that: it does nothing with subwindows. Some retesting a while back (early 2006) in response to a user's comment about differences pointed out that ncurses was incorrectly attempting to copy subwindows. That part is ifdef'd out (since it's too interesting to just delete). Since there's not much left for mvwin to do, the actual code is fairly similar.
X/Open's description of mvwin is too brief and vague to be of any use.
I'm using the following code to lock an IDirect3DTexture9 for update. This piece of code works fine on my NVidia graphic card (NVidia GeForce GTX 970M) but causes memory violation on Intel integrated graphic card (Intel HD Graphics 530), even the texture is immediately unlocked and no data is written on locked region. x, y, w and h parameters are far from boundary conditions so the locked rect is totally inside the texture.
void InnerLock(int x, int y, int w, int h, D3DLOCKED_RECT *lr)
{
int left, right, top, bottom;
left = clamp(x, 0, Width() - 1);
top = clamp(y, 0, Height() - 1);
right = clamp(x + w, left + 1, Width());
bottom = clamp(y + h, top + 1, Height());
RECT rc = { left, top, right, bottom };
texture->LockRect(0, lr, &rc, D3DLOCK_NO_DIRTY_UPDATE);
// this line returns zero but causes an exception on igdumdim32.dll later
texture->AddDirtyRect(&rc)
// everything become all right when I set the whole texture as dirty region
//RECT fc = { 0, 0, Width(), Height() };
//texture->AddDirtyRect(&fc);
}
The AddDirtyRect operator returns correct value, but the error occurs later in igdumdim32.dll (I'm not sure where the error exactly occurs, maybe in the draw call).
I first found the error when using LockRect with zero flag. The program crashed on some rect parameter (in my case the error occurred when y value of the rect is large enough, but still smaller than texture height). Then I used D3DLOCK_NO_DIRTY_UPDATE and manually added dirty rect. The error only occurs when AddDirtyRect is called.
This error is reproduced on another user with intel graphics card. My operating system is Windows 10. All drivers are updated to the latest version. If you need any information please tell me. Thank you!
I know users can move a window around and make it partially outside of the resolution boundary under X window system. Is it possible to change the size to achieve the same result either programmatically or manually?
Here is my experimental code, but it doesn't work.
Window w;
int revert_to;
XGetInputFocus(m_display, &w, &revert_to);
if (w == None) {
printf("can't get focused window");
}
else {
Window top = get_top_window(m_display, w);
XWindowAttributes xwa;
XGetWindowAttributes(m_display, top, &xwa);
XClassHint xch;
XGetClassHint(m_display, top, &xch);
printf("focused window name: %s pos: %d, %d size: %d, %d", xch.res_class, xwa.x, xwa.y, xwa.width, xwa.height);
XResizeWindow(m_display, top, 900, 1900);
}
get_top_window is some codes from internet
Window get_top_window(Display* d, Window start) {
Window w = start;
Window parent = start;
Window root = None;
Window *children;
unsigned int nchildren;
Status s;
printf("getting top window ... \n");
while (parent != root) {
w = parent;
s = XQueryTree(d, w, &root, &parent, &children, &nchildren); // see man
if (s)
XFree(children);
if(xerror) {
printf("fail\n");
exit(1);
}
printf(" get parent (window: %d)\n", (int)w);
}
printf("success (window: %d)\n", (int)w);
return w;
}
Take terminal as an example, this code could change the inner window but the outline window with titlebar is not affected. is this because the outline window is generated by window manager? And how could I resize it as one unit?
Apart from that, I also can't resize the window out of the resolution boundary. Any solution?
Edit: I use compiz window manager and there is no corresponding setting in Compiz configuration settings manager.
Edit: With the settings in this link, I'm able to resize a window out of the screen resolution by using mouse middle button click and drag trick. But programmatical method is still not working.
I have a standard scene with the init method as follows:
#interface CommodoreScene : CCLayerColor
#end
#implementation CommodoreScene
- (id) init {
if (( self=[super initWithColor:ccc4(255, 255, 255, 255)] )) {
}
return self;
}
#end
However when I run the scene on my iPhone4, or the simulator half the screen goes black, the other half my layer color (white).
I'm currently running the scene with [_director pushScene:[CommodoreScene node]]; and running cocos2d-iphone 2.0.0.
- (id) init {
if (( self=[super initWithColor:ccc4(255, 255, 255, 255) width:480 height:320] )) {
}
return self;
}
Try that. The important part is of course the change in the call to super. You might still have an issue with [[CCDirector] winSize] reading properly in the -init method if you're in landscape (which judging from the bug you're experiencing - you are), at least I did on my tests. As I recall, this is a known bug of some kind, as it seems to read the winSize as portrait instead of landscape. You can fix this by doing the following:
CGRect rect = CGRectMake(0, 0, 480, 320);
CGSize size = rect.size;
// position the label on the center of the screen
label.position = ccp( size.width /2 , size.height/2 );
Using that newly created size instead of winSize in your -init method fixes the issue. Notice that if you create and position an element after initialization, such as in onEnter, this problem goes away and the winSize from the director reads properly. Odd bug, it is.
You can change content size of your color layer;
CGSize boxSize = CGSizeMake(sGame.winWidth, sGame.winHeight);
CCLayerColor *box = [CCLayerColor layerWithColor:ccc4(155,155,200,255)];
box.position = ccp(0.0f, 0.0f);
box.contentSize = boxSize;
[self addChild:box z:-6];