linux: a few small improvements:
* Add PropertyChangeMask to events, makes compiz redraw better with (un)maximizing * Create the window on the default screen instead of iterating through all of them * Set backing store hint, looks nicer when moving stuff over the 4ed window * Set some other WM hints like min/max/default size, gravity, etc since most other apps seem to set them
This commit is contained in:
parent
4815ab8620
commit
16677d3f90
130
linux_4ed.cpp
130
linux_4ed.cpp
|
@ -136,6 +136,9 @@ struct Linux_Vars{
|
||||||
Atom atom__NET_WM_STATE_MAXIMIZED_HORZ;
|
Atom atom__NET_WM_STATE_MAXIMIZED_HORZ;
|
||||||
Atom atom__NET_WM_STATE_MAXIMIZED_VERT;
|
Atom atom__NET_WM_STATE_MAXIMIZED_VERT;
|
||||||
Atom atom__NET_WM_PING;
|
Atom atom__NET_WM_PING;
|
||||||
|
Atom atom__NET_WM_WINDOW_TYPE;
|
||||||
|
Atom atom__NET_WM_WINDOW_TYPE_NORMAL;
|
||||||
|
Atom atom__NET_WM_PID;
|
||||||
Atom atom_WM_DELETE_WINDOW;
|
Atom atom_WM_DELETE_WINDOW;
|
||||||
|
|
||||||
b32 has_xfixes;
|
b32 has_xfixes;
|
||||||
|
@ -1601,6 +1604,7 @@ LinuxInputInit(Display *dpy, Window XWindow)
|
||||||
KeyPressMask | KeyReleaseMask |
|
KeyPressMask | KeyReleaseMask |
|
||||||
ButtonPressMask | ButtonReleaseMask |
|
ButtonPressMask | ButtonReleaseMask |
|
||||||
EnterWindowMask | LeaveWindowMask |
|
EnterWindowMask | LeaveWindowMask |
|
||||||
|
PropertyChangeMask |
|
||||||
PointerMotionMask |
|
PointerMotionMask |
|
||||||
FocusChangeMask |
|
FocusChangeMask |
|
||||||
StructureNotifyMask |
|
StructureNotifyMask |
|
||||||
|
@ -1840,50 +1844,34 @@ b32 LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
||||||
// Behold the true nature of this wonderful OS:
|
// Behold the true nature of this wonderful OS:
|
||||||
// (thanks again to Casey for providing this stuff)
|
// (thanks again to Casey for providing this stuff)
|
||||||
|
|
||||||
Colormap cmap;
|
#define BASE_W 800
|
||||||
XSetWindowAttributes swa;
|
#define BASE_H 600
|
||||||
b32 window_setup_success = 0;
|
|
||||||
|
|
||||||
if (linuxvars.settings.set_window_size){
|
if (linuxvars.settings.set_window_size){
|
||||||
*WinWidth = linuxvars.settings.window_w;
|
*WinWidth = linuxvars.settings.window_w;
|
||||||
*WinHeight = linuxvars.settings.window_h;
|
*WinHeight = linuxvars.settings.window_h;
|
||||||
} else {
|
} else {
|
||||||
*WinWidth = 800;
|
*WinWidth = BASE_W;
|
||||||
*WinHeight = 600;
|
*WinHeight = BASE_H;
|
||||||
}
|
}
|
||||||
|
|
||||||
int XScreenCount = ScreenCount(linuxvars.XDisplay);
|
if (!GLXCanUseFBConfig(linuxvars.XDisplay)){
|
||||||
glx_config_result Config = {};
|
|
||||||
|
|
||||||
if(!GLXCanUseFBConfig(linuxvars.XDisplay)){
|
|
||||||
fprintf(stderr, "Your GLX version is too old.\n");
|
fprintf(stderr, "Your GLX version is too old.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(inso): maybe should try the default screen first? or only the default without iterating.
|
glx_config_result Config = ChooseGLXConfig(linuxvars.XDisplay, DefaultScreen(linuxvars.XDisplay));
|
||||||
|
if (!Config.Found){
|
||||||
|
fprintf(stderr, "Could not create GLX FBConfig.\n");
|
||||||
|
}
|
||||||
|
|
||||||
for(int XScreenIndex = 0;
|
XSetWindowAttributes swa = {};
|
||||||
XScreenIndex < XScreenCount;
|
swa.backing_store = WhenMapped;
|
||||||
++XScreenIndex)
|
|
||||||
{
|
|
||||||
Screen *XScreen = ScreenOfDisplay(linuxvars.XDisplay, XScreenIndex);
|
|
||||||
|
|
||||||
i32 ScrnWidth, ScrnHeight;
|
|
||||||
ScrnWidth = WidthOfScreen(XScreen);
|
|
||||||
ScrnHeight = HeightOfScreen(XScreen);
|
|
||||||
|
|
||||||
if (ScrnWidth + 50 < *WinWidth) *WinWidth = ScrnWidth + 50;
|
|
||||||
if (ScrnHeight + 50 < *WinHeight) *WinHeight = ScrnHeight + 50;
|
|
||||||
|
|
||||||
Config = ChooseGLXConfig(linuxvars.XDisplay, XScreenIndex);
|
|
||||||
if(Config.Found)
|
|
||||||
{
|
|
||||||
swa.colormap = cmap = XCreateColormap(linuxvars.XDisplay,
|
|
||||||
RootWindow(linuxvars.XDisplay, Config.BestInfo.screen ),
|
|
||||||
Config.BestInfo.visual, AllocNone);
|
|
||||||
swa.background_pixmap = None;
|
|
||||||
swa.border_pixel = 0;
|
|
||||||
swa.event_mask = StructureNotifyMask;
|
swa.event_mask = StructureNotifyMask;
|
||||||
|
swa.bit_gravity = NorthWestGravity;
|
||||||
|
swa.colormap = XCreateColormap(linuxvars.XDisplay,
|
||||||
|
RootWindow(linuxvars.XDisplay, Config.BestInfo.screen),
|
||||||
|
Config.BestInfo.visual, AllocNone);
|
||||||
|
|
||||||
linuxvars.XWindow =
|
linuxvars.XWindow =
|
||||||
XCreateWindow(linuxvars.XDisplay,
|
XCreateWindow(linuxvars.XDisplay,
|
||||||
|
@ -1891,42 +1879,31 @@ b32 LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
||||||
0, 0, *WinWidth, *WinHeight,
|
0, 0, *WinWidth, *WinHeight,
|
||||||
0, Config.BestInfo.depth, InputOutput,
|
0, Config.BestInfo.depth, InputOutput,
|
||||||
Config.BestInfo.visual,
|
Config.BestInfo.visual,
|
||||||
CWBorderPixel|CWColormap|CWEventMask, &swa);
|
CWBackingStore|CWBitGravity|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa);
|
||||||
|
|
||||||
if(linuxvars.XWindow)
|
if (!linuxvars.XWindow){
|
||||||
{
|
|
||||||
window_setup_success = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!window_setup_success){
|
|
||||||
fprintf(stderr, "Error creating window.\n");
|
fprintf(stderr, "Error creating window.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE(inso): Set the window's type to normal
|
//NOTE(inso): Set the window's type to normal
|
||||||
Atom _NET_WM_WINDOW_TYPE = XInternAtom(linuxvars.XDisplay, "_NET_WM_WINDOW_TYPE", False);
|
|
||||||
Atom _NET_WIN_TYPE_NORMAL = XInternAtom(linuxvars.XDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False);
|
|
||||||
XChangeProperty(
|
XChangeProperty(
|
||||||
linuxvars.XDisplay,
|
linuxvars.XDisplay,
|
||||||
linuxvars.XWindow,
|
linuxvars.XWindow,
|
||||||
_NET_WM_WINDOW_TYPE,
|
linuxvars.atom__NET_WM_WINDOW_TYPE,
|
||||||
XA_ATOM,
|
XA_ATOM,
|
||||||
32,
|
32,
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
(unsigned char*)&_NET_WIN_TYPE_NORMAL,
|
(unsigned char*)&linuxvars.atom__NET_WM_WINDOW_TYPE_NORMAL,
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|
||||||
//NOTE(inso): window managers want the PID as a window property for some reason.
|
//NOTE(inso): window managers want the PID as a window property for some reason.
|
||||||
Atom _NET_WM_PID = XInternAtom(linuxvars.XDisplay, "_NET_WM_PID", False);
|
|
||||||
pid_t pid = getpid();
|
pid_t pid = getpid();
|
||||||
XChangeProperty(
|
XChangeProperty(
|
||||||
linuxvars.XDisplay,
|
linuxvars.XDisplay,
|
||||||
linuxvars.XWindow,
|
linuxvars.XWindow,
|
||||||
_NET_WM_PID,
|
linuxvars.atom__NET_WM_PID,
|
||||||
XA_CARDINAL,
|
XA_CARDINAL,
|
||||||
32,
|
32,
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
|
@ -1939,45 +1916,53 @@ b32 LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
||||||
//NOTE(inso): set wm properties
|
//NOTE(inso): set wm properties
|
||||||
XStoreName(linuxvars.XDisplay, linuxvars.XWindow, WINDOW_NAME);
|
XStoreName(linuxvars.XDisplay, linuxvars.XWindow, WINDOW_NAME);
|
||||||
|
|
||||||
char* win_name_list[] = { WINDOW_NAME };
|
|
||||||
XTextProperty win_name;
|
|
||||||
|
|
||||||
XStringListToTextProperty(win_name_list, 1, &win_name);
|
|
||||||
|
|
||||||
XSizeHints *sz_hints = XAllocSizeHints();
|
XSizeHints *sz_hints = XAllocSizeHints();
|
||||||
XWMHints *wm_hints = XAllocWMHints();
|
XWMHints *wm_hints = XAllocWMHints();
|
||||||
XClassHint *cl_hints = XAllocClassHint();
|
XClassHint *cl_hints = XAllocClassHint();
|
||||||
|
|
||||||
if(linuxvars.settings.set_window_pos){
|
sz_hints->flags = PMinSize | PMaxSize | PBaseSize | PWinGravity;
|
||||||
|
|
||||||
|
sz_hints->min_width = 50;
|
||||||
|
sz_hints->min_height = 50;
|
||||||
|
|
||||||
|
sz_hints->max_width = sz_hints->max_height = (1UL << 16UL);
|
||||||
|
|
||||||
|
sz_hints->base_width = BASE_W;
|
||||||
|
sz_hints->base_height = BASE_H;
|
||||||
|
|
||||||
|
sz_hints->win_gravity = NorthWestGravity;
|
||||||
|
|
||||||
|
if (linuxvars.settings.set_window_pos){
|
||||||
sz_hints->flags |= USPosition;
|
sz_hints->flags |= USPosition;
|
||||||
sz_hints->x = linuxvars.settings.window_x;
|
sz_hints->x = linuxvars.settings.window_x;
|
||||||
sz_hints->y = linuxvars.settings.window_y;
|
sz_hints->y = linuxvars.settings.window_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
wm_hints->flags |= InputHint;
|
wm_hints->flags |= InputHint | StateHint;
|
||||||
wm_hints->input = True;
|
wm_hints->input = True;
|
||||||
|
wm_hints->initial_state = NormalState;
|
||||||
|
|
||||||
cl_hints->res_name = "4coder";
|
cl_hints->res_name = "4coder";
|
||||||
cl_hints->res_class = "4coder";
|
cl_hints->res_class = "4coder";
|
||||||
|
|
||||||
|
char* win_name_list[] = { WINDOW_NAME };
|
||||||
|
XTextProperty win_name;
|
||||||
|
XStringListToTextProperty(win_name_list, 1, &win_name);
|
||||||
|
|
||||||
XSetWMProperties(
|
XSetWMProperties(
|
||||||
linuxvars.XDisplay,
|
linuxvars.XDisplay,
|
||||||
linuxvars.XWindow,
|
linuxvars.XWindow,
|
||||||
&win_name,
|
&win_name, NULL,
|
||||||
NULL,
|
argv, argc,
|
||||||
argv,
|
sz_hints, wm_hints, cl_hints
|
||||||
argc,
|
|
||||||
sz_hints,
|
|
||||||
wm_hints,
|
|
||||||
cl_hints
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
XFree(win_name.value);
|
||||||
|
|
||||||
XFree(sz_hints);
|
XFree(sz_hints);
|
||||||
XFree(wm_hints);
|
XFree(wm_hints);
|
||||||
XFree(cl_hints);
|
XFree(cl_hints);
|
||||||
|
|
||||||
XFree(win_name.value);
|
|
||||||
|
|
||||||
LinuxSetIcon(linuxvars.XDisplay, linuxvars.XWindow);
|
LinuxSetIcon(linuxvars.XDisplay, linuxvars.XWindow);
|
||||||
|
|
||||||
//NOTE(inso): make the window visible
|
//NOTE(inso): make the window visible
|
||||||
|
@ -1987,15 +1972,7 @@ b32 LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
||||||
GLXContext GLContext =
|
GLXContext GLContext =
|
||||||
InitializeOpenGLContext(linuxvars.XDisplay, linuxvars.XWindow, Config.BestConfig, IsLegacy);
|
InitializeOpenGLContext(linuxvars.XDisplay, linuxvars.XWindow, Config.BestConfig, IsLegacy);
|
||||||
|
|
||||||
XWindowAttributes WinAttribs;
|
|
||||||
if(XGetWindowAttributes(linuxvars.XDisplay, linuxvars.XWindow, &WinAttribs))
|
|
||||||
{
|
|
||||||
*WinWidth = WinAttribs.width;
|
|
||||||
*WinHeight = WinAttribs.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow);
|
XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow);
|
||||||
XSync(linuxvars.XDisplay, False);
|
|
||||||
|
|
||||||
if (linuxvars.settings.set_window_pos){
|
if (linuxvars.settings.set_window_pos){
|
||||||
XMoveWindow(
|
XMoveWindow(
|
||||||
|
@ -2009,6 +1986,14 @@ b32 LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
|
||||||
if (linuxvars.settings.maximize_window){
|
if (linuxvars.settings.maximize_window){
|
||||||
LinuxMaximizeWindow(linuxvars.XDisplay, linuxvars.XWindow, 1);
|
LinuxMaximizeWindow(linuxvars.XDisplay, linuxvars.XWindow, 1);
|
||||||
}
|
}
|
||||||
|
XSync(linuxvars.XDisplay, False);
|
||||||
|
|
||||||
|
XWindowAttributes WinAttribs;
|
||||||
|
if (XGetWindowAttributes(linuxvars.XDisplay, linuxvars.XWindow, &WinAttribs))
|
||||||
|
{
|
||||||
|
*WinWidth = WinAttribs.width;
|
||||||
|
*WinHeight = WinAttribs.height;
|
||||||
|
}
|
||||||
|
|
||||||
Atom wm_protos[] = {
|
Atom wm_protos[] = {
|
||||||
linuxvars.atom_WM_DELETE_WINDOW,
|
linuxvars.atom_WM_DELETE_WINDOW,
|
||||||
|
@ -2531,6 +2516,9 @@ main(int argc, char **argv)
|
||||||
LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
|
LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
|
||||||
LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
|
LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
|
||||||
LOAD_ATOM(_NET_WM_PING);
|
LOAD_ATOM(_NET_WM_PING);
|
||||||
|
LOAD_ATOM(_NET_WM_WINDOW_TYPE);
|
||||||
|
LOAD_ATOM(_NET_WM_WINDOW_TYPE_NORMAL);
|
||||||
|
LOAD_ATOM(_NET_WM_PID);
|
||||||
LOAD_ATOM(WM_DELETE_WINDOW);
|
LOAD_ATOM(WM_DELETE_WINDOW);
|
||||||
|
|
||||||
#undef LOAD_ATOM
|
#undef LOAD_ATOM
|
||||||
|
|
Loading…
Reference in New Issue