#define Time X11Time
#define KeyCode X11KeyCode
#define Picture X11Picture
+#define Bool X11Bool
+
+#define _XTYPEDEF_BOOL
+typedef int X11Bool;
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
#include <X11/extensions/XShm.h>
+#undef Bool
#undef Picture
#undef Window
#undef Cursor
static X11Window activeWindow;
static X11Cursor systemCursors[SystemCursor];
+static Window acquiredInputWindow;
+static Point acquireStart;
+static Point lastMouse;
+static MouseButtons buttonsState;
+
+static bool keyStates[KeyCode];
+
static enum NETWMStateAction { remove = 0, add = 1, toggle = 2 };
static enum AtomIdents
_net_wm_window_type_desktop, _net_wm_window_type_dialog, _net_wm_window_type_dock, _net_wm_window_type_dropdown_menu,
_net_wm_window_type_menu, _net_wm_window_type_normal, _net_wm_window_type_popup_menu, _net_wm_window_type_splash,
_net_wm_window_type_toolbar, _net_wm_window_type_utility, _net_workarea, _net_frame_extents, _net_request_frame_extents,
- _net_wm_state_maximized_vert, _net_wm_state_maximized_horz, _net_wm_state_modal, app_selection, _net_supported
+ _net_wm_state_maximized_vert, _net_wm_state_maximized_horz, _net_wm_state_modal, app_selection, _net_supported,
+ _net_wm_state_skip_taskbar, _net_wm_state_fullscreen, _net_wm_state_above, capsLock, numLock, scrollLock
};
static Atom atoms[AtomIdents];
"_NET_WM_STATE_MAXIMIZED_HORZ", // _net_wm_state_maximized_horz
"_NET_WM_STATE_MODAL", // _net_wm_state_modal
"APP_SELECTION",
- "_NET_SUPPORTED"
+ "_NET_SUPPORTED",
+ "_NET_WM_STATE_SKIP_TASKBAR",
+ "_NET_WM_STATE_FULLSCREEN",
+ "_NET_WM_STATE_ABOVE",
+ "Caps Lock",
+ "Num Lock",
+ "Scroll Lock",
};
/*
_NET_WM_STATE_STICKY, ATOM
-_NET_WM_STATE_MAXIMIZED_VERT, ATOM
-_NET_WM_STATE_MAXIMIZED_HORZ, ATOM
_NET_WM_STATE_SHADED, ATOM
-_NET_WM_STATE_SKIP_TASKBAR, ATOM
_NET_WM_STATE_SKIP_PAGER, ATOM
-_NET_WM_STATE_HIDDEN, ATOM
-_NET_WM_STATE_FULLSCREEN, ATOM
-_NET_WM_STATE_ABOVE, ATOM
_NET_WM_STATE_BELOW, ATOM
-_NET_WM_STATE_DEMANDS_ATTENTION, ATOM
*/
static bool autoRepeatDetectable;
// Decorations Size
Box decor;
bool gotFrameExtents;
+ bool currentlyVisible;
};
bool XGetBorderWidths(Window window, Box box)
if(desktopX != x || desktopY != y || desktopW != w || desktopH != h)
{
- guiApp.SetDesktopPosition(x, y, w, h, updateChildren);
- desktopX = x;
- desktopY = y;
- desktopW = w;
- desktopH = h;
+ bool skip = false;
+ // Don't change the desktop area if another fullscreen application is running
+ // (Attemps to solve the debugging IDE being re-activated while switching debugged app between fullscreen/windowed on Cinnamon)
+ if(XGetWindowProperty(xGlobalDisplay, x_root, atoms[_net_active_window], 0, 32,
+ False, AnyPropertyType, &type, &format, &len,
+ &fill, &data) == Success && data)
+ {
+ X11Window active = *(long *)data;
+ XFree(data);
+ if(XGetWindowProperty(xGlobalDisplay, active, atoms[_net_wm_state], 0, 32, False,
+ XA_ATOM, &type, &format, &len, &fill, &data) == Success)
+ {
+ Atom * values = (Atom *) data;
+ int i;
+ for (i = 0; i < len; i++)
+ {
+ if(values[i] == atoms[_net_wm_state_fullscreen])
+ {
+ skip = true;
+ break;
+ }
+ }
+ XFree(data);
+ }
+ }
+ if(w && h && !skip)
+ {
+ guiApp.SetDesktopPosition(x, y, w, h, updateChildren);
+ desktopX = x;
+ desktopY = y;
+ desktopW = w;
+ desktopH = h;
+ }
}
}
if(key != leftControl && key != rightControl && event->state & ControlMask)
code.ctrl = true;
if(key != leftAlt && key != rightAlt && event->state & Mod1Mask)
+ {
+ if(fullScreenMode && key == tab)
+ {
+ XUngrabKeyboard(xGlobalDisplay, CurrentTime);
+ guiApp.SetAppFocus(false);
+ SetNETWMState((X11Window)window.windowHandle, true, remove, atoms[_net_wm_state_fullscreen], 0);
+ XIconifyWindow(xGlobalDisplay, (X11Window)window.windowHandle, DefaultScreen(xGlobalDisplay));
+ if(acquiredInputWindow)
+ XInterface::SetMousePosition(guiApp.acquiredMouseX, guiApp.acquiredMouseY);
+ }
code.alt = true;
+ }
#ifdef __APPLE__
if(key != leftAlt && key != rightAlt && event->state & (1<<13))
if(release == 1)
{
int numBytes;
+
+ if(code < KeyCode::enumSize) keyStates[code] = false;
if(windowData && windowData.ic) ch = buflength ? UTF8GetChar(buf, &numBytes) : 0;
if(ch == 127) ch = 0;
// printf("Release! %d %d %d\n", keysym, code, ch);
int c;
if(release == 0)
{
+ if(code < KeyCode::enumSize) keyStates[code] = true;
+
if(windowData.ic && buflength)
{
for(c = 0; c<buflength;)
}
*/
-static Bool EventChecker(void *display, XEvent *event, char * data)
+static X11Bool EventChecker(void *display, XEvent *event, char * data)
{
return (!data || (event->type == (int) data)) && event->type != NoExpose && event->type != GraphicsExpose;
}
-static Bool ConfigureNotifyChecker(void *display, XConfigureEvent *event, char * data)
+static X11Bool ConfigureNotifyChecker(void *display, XConfigureEvent *event, char * data)
{
return (!data || (event->window == (X11Window) data)) && event->type == ConfigureNotify;
}
+static X11Bool FocusInChecker(void *display, XFocusChangeEvent *event, char * data)
+{
+ X11Bool result = False;
+ if(event->type == FocusIn)
+ {
+ Window window = null;
+ XFindContext(xGlobalDisplay, event->window, windowContext, (XPointer *) &window);
+ if(window)
+ result = True;
+ }
+ return result;
+}
+
static enum FrameExtentSupport { unknown, working, broken };
static FrameExtentSupport frameExtentSupported;
}
}
-static bool RequestFrameExtents(Window window)
+static bool RequestFrameExtents(X11Window windowHandle)
{
- if(window.nativeDecorations && frameExtentSupported != broken)
+ if(frameExtentSupported != broken)
{
// Request decoration frame extents
XClientMessageEvent event = { 0 };
event.message_type = atoms[_net_request_frame_extents];
event.display = xGlobalDisplay;
event.serial = 0;
- event.window = (X11Window)window.windowHandle;
+ event.window = windowHandle;
event.send_event = 1;
- window.windowHandle = (void *)window.windowHandle;
event.format = 32;
if(frameExtentSupported == unknown && !frameExtentRequest)
{
frameExtentRequest = GetTime();
- frameExtentWindow = (X11Window)window.windowHandle;
+ frameExtentWindow = windowHandle;
}
XSendEvent(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), bool::false,
return result;
}
-static bool WaitForFrameExtents(Window window)
+static bool WaitForFrameExtents(Window window, bool update)
{
int attempts = 0;
//XFlush(xGlobalDisplay);
- while(attempts++ < 10)
+ while(attempts++ < 40)
{
- if(GetFrameExtents(window, false)) return true;
+ if(GetFrameExtents(window, update)) return true;
Sleep(1.0 / RESOLUTION);
}
return false;
guiApp.desktop.Destroy(0);*/
}
+static void X11UpdateState(Window window, bool * unmaximized)
+{
+ if(atomsSupported[_net_wm_state]) //window.nativeDecorations)
+ {
+ int format;
+ unsigned long len, fill;
+ Atom type;
+ char * data = null;
+ if(XGetWindowProperty(xGlobalDisplay, (X11Window)window.systemHandle, atoms[_net_wm_state], 0, 32, False,
+ XA_ATOM, &type, &format, &len, &fill, &data) == Success)
+ {
+ bool maxVert = false, maxHorz = false, isMinimized = false;
+ Atom * hints = (Atom *)data;
+ int c;
+ for(c = 0; c < len && hints[c]; c++)
+ {
+ if(hints[c] == atoms[_net_wm_state_maximized_vert])
+ maxVert = true;
+ else if(hints[c] == atoms[_net_wm_state_maximized_horz])
+ maxHorz = true;
+ else if(hints[c] == atoms[_net_wm_state_hidden])
+ isMinimized = true;
+ }
+ XFree(data);
+
+ if(maxVert && maxHorz)
+ {
+ if(window.state != maximized)
+ {
+ *&window.state = maximized;
+ if(!window.nativeDecorations)
+ window.CreateSystemChildren();
+ }
+ }
+ else if(isMinimized)
+ {
+ if(window.state != minimized)
+ {
+ *&window.state = minimized;
+ if(!window.nativeDecorations)
+ window.CreateSystemChildren();
+ }
+ }
+ else if(window.state != normal)
+ {
+ if(unmaximized && window.state == maximized)
+ *unmaximized = true;
+ *&window.state = normal;
+ if(!window.nativeDecorations)
+ window.CreateSystemChildren();
+ }
+ }
+ }
+}
+
class XInterface : Interface
{
class_property(name) = "X";
bool Initialize()
{
setlocale(LC_ALL, "en_US.UTF-8");
- XInitThreads();
+ // XInitThreads();
XSupportsLocale();
XSetLocaleModifiers("");
XSetErrorHandler(MyXErrorHandler);
#endif
xTerminate = false;
xGlobalDisplay = XOpenDisplay(null);
+ // XSynchronize(xGlobalDisplay, True);
frameExtentSupported = unknown;
joystickFD[0] = open("/dev/js0", O_RDONLY);
}
}
- {
- Atom protocols[2] = { atoms[wm_delete_window], atoms[wm_take_focus] };
-
- XSetWMProtocols(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), protocols, 2);
- }
-
/*
if(atomsSupported[_net_workarea])
printf("Warning: _NET_WORKAREA extension not supported\n");
if(event->button == Button1)
{
// Force a raise on click here to deal with confused active state preventing to bring the window up
- if(!atomsSupported[_net_active_window] && !window.isRemote)
+ if(!fullScreenMode)
{
- XRaiseWindow(xGlobalDisplay, (X11Window)window.windowHandle);
- XSetInputFocus(xGlobalDisplay, (X11Window)window.windowHandle, RevertToPointerRoot, CurrentTime);
+ if(!atomsSupported[_net_active_window] && !window.isRemote)
+ XRaiseWindow(xGlobalDisplay, (X11Window)window.windowHandle);
+ XSetInputFocus(xGlobalDisplay, (X11Window)window.windowHandle, RevertToParent, CurrentTime);
}
button = __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonDown;
buttonDouble = __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftDoubleClick;
whichButton = 0;
buttonMask = Button1Mask;
keyFlags.left = true;
+ buttonsState.left = true;
}
else if(event->button == Button3)
{
whichButton = 2;
buttonMask = Button3Mask;
keyFlags.right = true;
+ buttonsState.right = true;
}
else
{
whichButton = 1;
buttonMask = Button2Mask;
keyFlags.middle = true;
+ buttonsState.middle = true;
}
if(event->state & buttonMask)
break;
{
button = __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnLeftButtonUp;
buttonMask = Button1Mask;
+ buttonsState.left = false;
}
else if(event->button == Button3)
{
button = __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnRightButtonUp;
buttonMask = Button3Mask;
+ buttonsState.right = false;
}
else
{
button = __ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMiddleButtonUp;
buttonMask = Button2Mask;
+ buttonsState.middle = false;
}
timeStamp = event->time;
if(!(event->state & buttonMask)) break;
if(event->state & Button3Mask) keyFlags.right = true;
//*XUnlockDisplay(xGlobalDisplay);
incref window;
+ if(window == acquiredInputWindow)
+ {
+ lastMouse.x = event->x_root;
+ lastMouse.y = event->y_root;
+ }
window.MouseMessage(__ecereVMethodID___ecereNameSpace__ecere__gui__Window_OnMouseMove,
event->x_root, event->y_root, &keyFlags, false, false);
delete window;
{
XExposeEvent * event = (XExposeEvent *) thisEvent;
Box box;
- box.left = event->x - window.clientStart.x;
- box.top = event->y - window.clientStart.y;
+ box.left = event->x;
+ box.top = event->y;
box.right = box.left + event->width - 1;
box.bottom = box.top + event->height - 1;
- window.Update(box);
- box.left += window.clientStart.x;
- box.top += window.clientStart.y;
- box.right += window.clientStart.x;
- box.bottom += window.clientStart.y;
window.UpdateDirty(box);
break;
}
}
case FocusIn:
{
+ lastMouse = acquireStart;
+
+ guiApp.SetAppFocus(true);
+
+ X11UpdateState(window, null);
+
+ if(fullScreenMode)
+ {
+ if(acquiredInputWindow)
+ {
+ GetMousePosition(&guiApp.acquiredMouseX, &guiApp.acquiredMouseY);
+ lastMouse = { window.size.w/2, window.size.h/2 };
+ SetMousePosition(lastMouse.x, lastMouse.y);
+ }
+ XRaiseWindow(xGlobalDisplay, (X11Window)window.windowHandle);
+ SetNETWMState((X11Window)window.windowHandle, true, add, atoms[_net_wm_state_fullscreen], 0);
+ XGrabKeyboard(xGlobalDisplay, (X11Window)window.windowHandle, False, GrabModeAsync, GrabModeAsync, CurrentTime);
+ (xGlobalDisplay, (X11Window)window.windowHandle, RevertToParent, timeStamp);
+ XInterface::UpdateRootWindow(window);
+ break;
+ }
+
if(activeWindow != (X11Window)window.windowHandle)
{
XFocusChangeEvent *event = (XFocusChangeEvent *) thisEvent;
//printf("Processing a FocusOut Event for %s (%x)\n", window._class.name, window);
#endif
+ /*
if(XCheckTypedWindowEvent(xGlobalDisplay, thisEvent->window, FocusIn, (XEvent *)thisEvent))
{
break;
}
+ */
+
+ if(XCheckIfEvent(xGlobalDisplay, (XEvent *)thisEvent, (void *)FocusInChecker, null))
+ {
+ if(!fullScreenMode)
+ XPutBackEvent(xGlobalDisplay, (XEvent *)thisEvent);
+ break;
+ }
+
+
+ if(fullScreenMode || (X11Window)window.windowHandle == activeWindow)
+ guiApp.SetAppFocus(false);
+
+ if(fullScreenMode)
+ {
+ //XUngrabKeyboard(xGlobalDisplay, CurrentTime);
+ //SetNETWMState((X11Window)window.windowHandle, true, remove, atoms[_net_wm_state_fullscreen], 0);
+ //XIconifyWindow(xGlobalDisplay, (X11Window)window.windowHandle, DefaultScreen(xGlobalDisplay));
+ break;
+ }
+
if(thisEvent->window == activeWindow)
activeWindow = (X11Window)null;
#if 0
#endif
{
XFocusChangeEvent *event = (XFocusChangeEvent *) thisEvent;
- if(window != window.parent.activeChild && window != guiApp.interimWindow) break;
+ if(window.parent && window != window.parent.activeChild && window != guiApp.interimWindow) break;
incref window;
#ifdef _DEBUG
{
XConfigureEvent * event = (XConfigureEvent *) thisEvent;
bool unmaximized = false;
+ if(!window.visible || fullScreenMode) break;
while(XCheckIfEvent(xGlobalDisplay, (XEvent *)thisEvent, (void *)ConfigureNotifyChecker, (void *)window.windowHandle));
//if(event->x - desktopX != window.position.x || event->y - desktopY != window.position.y || event->width != window.size.w || event->height != window.size.h)
- if(atomsSupported[_net_wm_state]) //window.nativeDecorations)
- {
- int format;
- unsigned long len, fill;
- Atom type;
- char * data = null;
- if(XGetWindowProperty(xGlobalDisplay, (X11Window)window.systemHandle, atoms[_net_wm_state], 0, 32, False,
- XA_ATOM, &type, &format, &len, &fill, &data) == Success)
- {
- bool maxVert = false, maxHorz = false, isMinimized = false;
- Atom * hints = (Atom *)data;
- int c;
- for(c = 0; c < len && hints[c]; c++)
- {
- if(hints[c] == atoms[_net_wm_state_maximized_vert])
- maxVert = true;
- else if(hints[c] == atoms[_net_wm_state_maximized_horz])
- maxHorz = true;
- else if(hints[c] == atoms[_net_wm_state_hidden])
- isMinimized = true;
- }
- XFree(data);
-
- if(maxVert && maxHorz)
- {
- if(window.state != maximized)
- {
- *&window.state = maximized;
- if(!window.nativeDecorations)
- window.CreateSystemChildren();
- }
- }
- else if(isMinimized)
- {
- if(window.state != minimized)
- {
- *&window.state = minimized;
- if(!window.nativeDecorations)
- window.CreateSystemChildren();
- }
- }
- else if(window.state != normal)
- {
- if(window.state == maximized)
- unmaximized = true;
- *&window.state = normal;
- if(!window.nativeDecorations)
- window.CreateSystemChildren();
- }
- }
- }
+ X11UpdateState(window, &unmaximized);
{
bool offset = false;
int x, y, w, h;
- if(unmaximized)
+ if(unmaximized && window.nativeDecorations)
{
- if(window.nativeDecorations && RequestFrameExtents(window))
- WaitForFrameExtents(window);
+ if(window.nativeDecorations && RequestFrameExtents((X11Window)window.windowHandle))
+ WaitForFrameExtents(window, false);
// Ensure we set the normal size anchor when un-maximizing
window.ComputeAnchors(window.normalAnchor, window.normalSizeAnchor, &x, &y, &w, &h);
XTranslateCoordinates(xGlobalDisplay, event->window,
RootWindow(xGlobalDisplay, DefaultScreen(xGlobalDisplay)), 0, 0,
&rootX, &rootY, &rootChild);
+
if(x != rootX || y != rootY)
{
+ /*if(event->send_event)
+ offset = true;*/
x = rootX;
y = rootY;
- offset = true;
}
}
y -= windowData.decor.top;
w += windowData.decor.left + windowData.decor.right;
h += windowData.decor.top + windowData.decor.bottom;
-
- /*
- x -= window.clientStart.x;
- y -= window.clientStart.y - (window.hasMenuBar ? skinMenuHeight : 0);
- w += window.size.w - window.clientSize.w;
- h += window.size.h - window.clientSize.h;
- */
}
}
- window.Position(x, y, w, h, true, true, true, true, false, unmaximized);
+ window.Position(x, y, w, h, false /*true*/, true, true, true, false, unmaximized);
// Break the anchors for moveable/resizable windows
// Avoid doing this if the translation wasn't in sync as it will cause the window to move around
Window modalRoot;
XWindowData windowData;
bool laterFocus;
- activeWindow = (X11Window)window.windowHandle;
+
+ if(fullScreenMode)
+ {
+ XRaiseWindow(xGlobalDisplay, (X11Window)window.windowHandle);
+ XSetInputFocus(xGlobalDisplay, (X11Window)window.windowHandle, RevertToParent, timeStamp);
+ XGrabKeyboard(xGlobalDisplay, (X11Window)window.windowHandle, False, GrabModeAsync, GrabModeAsync, CurrentTime);
+ guiApp.SetAppFocus(true);
+ break;
+ }
+
+ //activeWindow = (X11Window)window.windowHandle;
timeStamp = (X11Time)event->data.l[1];
XFocusChangeEvent *event = (XFocusChangeEvent *) &checkEvent;
Window window;
XFindContext(xGlobalDisplay, event->window, windowContext, (XPointer *) &window);
- if(window != window.parent.activeChild) break;
+ if(window.parent && window != window.parent.activeChild) break;
incref window;
#ifdef _DEBUG
}
}
+ lastMouse = acquireStart;
modalRoot = window.FindModal();
windowData = modalRoot ? modalRoot.windowData : window.windowData;
if(windowData)
#endif
XSendEvent(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), bool::false, SubstructureRedirectMask | SubstructureNotifyMask, (union _XEvent *)&event);
- XSetInputFocus(xGlobalDisplay, (X11Window)modalRoot.windowHandle, RevertToPointerRoot, timeStamp);
+ XSetInputFocus(xGlobalDisplay, (X11Window)modalRoot.windowHandle, RevertToParent, timeStamp);
+ guiApp.SetAppFocus(true);
+ activeWindow = (X11Window)window.windowHandle;
//XFlush(xGlobalDisplay);
//printf("Done.\n");
}
else
{
- XSetInputFocus(xGlobalDisplay, (X11Window)window.windowHandle, RevertToPointerRoot, timeStamp);
+ XSetInputFocus(xGlobalDisplay, (X11Window)window.windowHandle, RevertToParent, timeStamp);
+ guiApp.SetAppFocus(true);
+ activeWindow = (X11Window)window.windowHandle;
window.ExternalActivate(true, true, window, null); // lastActive);
if(windowData && windowData.ic)
{
{
XWindowData windowData = window.windowData;
XPropertyEvent * event = (XPropertyEvent *) thisEvent;
- if(event->atom == atoms[_net_frame_extents] &&
+ if(!fullScreenMode && event->atom == atoms[_net_frame_extents] &&
event->state == PropertyNewValue && windowData)
{
if(!GetFrameExtents(window, true))
if(fullScreenMode)
{
- windowHandle = XCreateWindow(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay),
- 0,0,guiApp.desktop.size.w,guiApp.desktop.size.h,0, depth, InputOutput, visual ? visual : CopyFromParent,
- CWEventMask | (visual ? (CWColormap | CWBorderPixel) : 0)/*| CWOverrideRedirect*/, &attributes);
+ windowHandle = XCreateWindow(xGlobalDisplay,
+ DefaultRootWindow(xGlobalDisplay),
+ 0,0,
+ XDisplayWidth(xGlobalDisplay, DefaultScreen(xGlobalDisplay)),
+ XDisplayHeight(xGlobalDisplay, DefaultScreen(xGlobalDisplay)),
+ 0, depth, InputOutput, visual ? visual : CopyFromParent,
+ CWEventMask | (visual ? (CWColormap | CWBorderPixel) : 0) | CWOverrideRedirect,
+ &attributes);
+
+ {
+ XSizeHints hints = { 0 };
+ XSetWMNormalHints(xGlobalDisplay, windowHandle, &hints);
+ }
+
+ {
+ String caption = window.caption;
+ XChangeProperty(xGlobalDisplay, windowHandle, atoms[_net_wm_name],
+ atoms[utf8_string], 8, PropModeReplace, (byte *)window.caption, caption ? strlen(caption) : 0);
+ XChangeProperty(xGlobalDisplay, windowHandle, atoms[wm_name],
+ atoms[utf8_string], 8, PropModeReplace, (byte *)window.caption, caption ? strlen(caption) : 0);
+ }
+
+ SetNETWMState((X11Window)windowHandle, false, add, atoms[_net_wm_state_fullscreen], 0);
+ //SetNETWMState((X11Window)windowHandle, false, add, atoms[_net_wm_state_above], 0);
+ {
+ Atom hints[4];
+ int count;
+
+ hints[0] = atoms[_net_wm_window_type_normal];
+ count = 1;
+ XChangeProperty(xGlobalDisplay, windowHandle, atoms[_net_wm_window_type], XA_ATOM, 32,
+ PropModeReplace, (unsigned char*)&hints, count);
+ }
+
+ {
+ XWMHints xwmHints;
+ xwmHints.flags = InputHint;
+ xwmHints.input = 0;
+ XSetWMHints(xGlobalDisplay, windowHandle, &xwmHints);
+ }
+ {
+ Atom protocols[2] = { atoms[wm_delete_window], atoms[wm_take_focus] };
+ XSetWMProtocols(xGlobalDisplay, windowHandle, protocols, 2);
+ }
}
/*
Unsupported for now...
}
{
- Atom hints[2] =
+ Atom hints[4];
+ int count;
+ if(parentWindow && window.interim)
{
- parentWindow ? atoms[_net_wm_window_type_menu] : atoms[_net_wm_window_type_normal],
- parentWindow ? atoms[_net_wm_window_type_popup_menu] : 0
+ hints[0] = atoms[_net_wm_window_type_dropdown_menu];
+ hints[1] = atoms[_net_wm_window_type_popup_menu];
+ hints[2] = atoms[_net_wm_window_type_menu];
+ count = 3;
+ }
+ else if(parentWindow)
+ {
+ hints[0] = atoms[_net_wm_window_type_normal];
+ SetNETWMState(windowHandle, false, add, atoms[_net_wm_state_skip_taskbar], 0);
+
+ // Some WMs won't show a close button if dialog is set
+ // Additionally, this casues jumping of all dialog windows on Cinnamon
+ //hints[0] = atoms[_net_wm_window_type_dialog];
+ count = 1;
+ }
+ else
+ {
+ hints[0] = atoms[_net_wm_window_type_normal];
+ count = 1;
};
-#if defined(__APPLE__) || defined(__FreeBSD__)
- // Don't set this on non-interim windows for OS X...
- if(parentWindow && window.interim)
-#endif
+ XChangeProperty(xGlobalDisplay, windowHandle, atoms[_net_wm_window_type], XA_ATOM, 32,
+ PropModeReplace, (unsigned char*)&hints, count);
- XChangeProperty(xGlobalDisplay, windowHandle, atoms[_net_wm_window_type], XA_ATOM, 32,
- PropModeReplace, (unsigned char*)&hints, parentWindow ? 2 : 1);
{
XWMHints xwmHints;
xwmHints.flags = InputHint;
}
// Set Normal hints for minimum/maximum size
- if(true)
{
XSizeHints hints = { 0 };
hints.min_width = minW;
{
(window.nativeDecorations ? 0 : MWM_HINTS_DECORATIONS)|MWM_HINTS_FUNCTIONS,
(window.hasClose ? MWM_FUNC_CLOSE : 0) |
- (window.hasMaximize ? MWM_FUNC_MAXIMIZE : 0) |
- (window.hasMinimize ? MWM_FUNC_MINIMIZE : 0) |
- ((window.moveable || ((BorderBits)window.borderStyle).fixed) ? MWM_FUNC_MOVE : 0) |
- (((BorderBits)window.borderStyle).sizable ? MWM_FUNC_RESIZE : 0),
+ (fullScreenMode || window.hasMaximize ? MWM_FUNC_MAXIMIZE : 0) |
+ (fullScreenMode || window.hasMinimize ? MWM_FUNC_MINIMIZE : 0) |
+ ((fullScreenMode || window.moveable || ((BorderBits)window.borderStyle).fixed) ? MWM_FUNC_MOVE : 0) |
+ (fullScreenMode || ((BorderBits)window.borderStyle).sizable ? MWM_FUNC_RESIZE : 0),
0, 0, 0
};
XChangeProperty(xGlobalDisplay, windowHandle, atoms[_motif_wm_hints], atoms[_motif_wm_hints], 32,
}
}
- /*
{
- Atom protocolsAtom = XInternAtom(xGlobalDisplay, "WM_PROTOCOLS", False);
- if ( protocolsAtom != None )
- {
- MWM_Hints hints = { MWM_HINTS_DECORATIONS|MWM_HINTS_FUNCTIONS, 0, 0, 0, 0 };
- XChangeProperty(xGlobalDisplay, windowHandle, atoms[_motif_wm_hints], atoms[_motif_wm_hints], 32,
- PropModeReplace, (unsigned char*)&hints, sizeof(hints)/4);
- }
- }*/
+ XWMHints wmHints = { 0 };
+ wmHints.input = True;
+ XSetWMHints(xGlobalDisplay, windowHandle, &wmHints);
+ }
+
// XFlush(xGlobalDisplay);
window.windowData = XWindowData { visualInfo, ic };
XUngrabPointer(xGlobalDisplay, CurrentTime);
}
- if(!window.nativeDecorations || !RequestFrameExtents(window))
+ if(fullScreenMode || !window.nativeDecorations || !RequestFrameExtents(windowHandle))
((XWindowData)window.windowData).gotFrameExtents = true;
+
+ window.windowHandle = (void *)windowHandle;
+ if(window.state != maximized)
+ WaitForFrameExtents(window, true);
+
+ //GetFrameExtents(window, true);
+
+ if(fullScreenMode)
+ {
+ XMapWindow(xGlobalDisplay, windowHandle);
+ XGrabKeyboard(xGlobalDisplay, windowHandle, False, GrabModeAsync, GrabModeAsync, CurrentTime);
+ }
return (void *)windowHandle;
}
void DestroyRootWindow(Window window)
{
XEvent event;
+ if(window == acquiredInputWindow)
+ delete acquiredInputWindow;
XDeleteContext(xGlobalDisplay, (XID)window, windowContext);
XSaveContext(xGlobalDisplay, (X11Window)window.windowHandle, windowContext, null);
// && window.state != maximized -- required for Cinnamon on Mint 14/15
if(!windowData.gotFrameExtents && window.state != maximized)
{
- if(WaitForFrameExtents(window))
+ if(WaitForFrameExtents(window, false))
{
x += windowData.decor.left;
y += windowData.decor.top ;
x += desktopX;
y += desktopY;
- if(!atomsSupported[_net_wm_state] || window.state != maximized)
+ if(!fullScreenMode && (!atomsSupported[_net_wm_state] || window.state != maximized))
{
if(move && resize)
XMoveResizeWindow(xGlobalDisplay, (X11Window)window.windowHandle, x, y, w, h);
if(window.style.fixed && !window.style.sizable)
{
XSizeHints hints = { 0 };
+ long supplied;
+ XGetWMNormalHints(xGlobalDisplay, (X11Window)window.windowHandle, &hints, &supplied);
hints.min_width = hints.max_width = w;
hints.min_height = hints.max_height = h;
- hints.flags |= PMinSize|PMaxSize|PPosition|PSize;
+ hints.flags |= PMinSize|PMaxSize;
XSetWMNormalHints(xGlobalDisplay, (X11Window)window.windowHandle, &hints);
}
}
-#if defined(__APPLE__)
-// if(window.created && !visible)
- // XUnmapWindow(xGlobalDisplay, (X11Window)window.windowHandle);
-#endif
}
}
window.nativeDecorations = false;
if(!window.parent || !window.parent.display)
{
+ XWindowData windowData = window.windowData;
//Logf("Set root window state %d %s\n", state, window.name);
if(visible)
{
- XMapWindow(xGlobalDisplay, (X11Window)window.windowHandle);
- WaitForViewableWindow(window);
- if(window.creationActivation == activate && state != minimized)
- ActivateRootWindow(window);
+ if(!windowData.currentlyVisible)
+ {
+ XMapWindow(xGlobalDisplay, (X11Window)window.windowHandle);
+ windowData.currentlyVisible = true;
+ WaitForViewableWindow(window);
+ if(window.creationActivation == activate && state != minimized)
+ ActivateRootWindow(window);
+ }
+
+ if(fullScreenMode && state != minimized)
+ {
+ int w = XDisplayWidth(xGlobalDisplay, DefaultScreen(xGlobalDisplay));
+ int h = XDisplayHeight(xGlobalDisplay, DefaultScreen(xGlobalDisplay));
+ SetNETWMState((X11Window)window.windowHandle, true, add, atoms[_net_wm_state_fullscreen], 0);
+ XMoveResizeWindow(xGlobalDisplay, (X11Window)window.windowHandle, 0, 0, w, h);
+
+ guiApp.SetDesktopPosition(0, 0, w, h, true);
+ window.Position(0, 0, w, h, true, true, true, true, false, false);
+ }
if(state == minimized && atomsSupported[_net_wm_state])
{
*/
// printf("Attempting to minimize %s\n", window._class.name);
- XIconifyWindow(xGlobalDisplay, (X11Window)window.windowHandle, DefaultScreen(xGlobalDisplay));
+ if(!fullScreenMode)
+ XIconifyWindow(xGlobalDisplay, (X11Window)window.windowHandle, DefaultScreen(xGlobalDisplay));
}
- else
+ else if(!fullScreenMode)
{
//((XWindowData)window.windowData).gotFrameExtents && (!window.nativeDecorations || window.state == state))
if(!atomsSupported[_net_wm_state] || (!((XWindowData)window.windowData).gotFrameExtents && window.state == maximized))
if(atomsSupported[_net_wm_state])
{
// Maximize / Restore the window
- SetNETWMState((X11Window)window.windowHandle, true, state == maximized ? add: remove,
+ SetNETWMState((X11Window)window.windowHandle, true, state == maximized ? add : remove,
atoms[_net_wm_state_maximized_vert], atoms[_net_wm_state_maximized_horz]);
if(state == maximized)
{
}
}
else
+ {
XUnmapWindow(xGlobalDisplay, (X11Window)window.windowHandle);
+ windowData.currentlyVisible = false;
+ }
//XFlush(xGlobalDisplay);
}
}
{
if(!window.style.hidden && window.created)
{
+ XWindowData windowData = window.windowData;
//printf("Activate root window %s\n", window._class.name);
+ if(!windowData.currentlyVisible)
+ {
+ XMapWindow(xGlobalDisplay, (X11Window)window.windowHandle);
+ WaitForViewableWindow(window);
+ windowData.currentlyVisible = true;
+ }
XRaiseWindow(xGlobalDisplay, (X11Window)window.windowHandle);
- XMapWindow(xGlobalDisplay, (X11Window)window.windowHandle);
- WaitForViewableWindow(window);
if(atomsSupported[_net_active_window])
{
XClientMessageEvent event = { 0 };
XSendEvent(xGlobalDisplay, DefaultRootWindow(xGlobalDisplay), bool::false, SubstructureRedirectMask | SubstructureNotifyMask, (union _XEvent *)&event);
//#if defined(__APPLE__)
- XSetInputFocus(xGlobalDisplay, (X11Window)window.windowHandle, RevertToPointerRoot, CurrentTime);
+ XSetInputFocus(xGlobalDisplay, (X11Window)window.windowHandle, RevertToParent, CurrentTime);
//#endif
}
else
- XSetInputFocus(xGlobalDisplay, (X11Window)window.windowHandle, RevertToPointerRoot, CurrentTime);
+ XSetInputFocus(xGlobalDisplay, (X11Window)window.windowHandle, RevertToParent, CurrentTime);
}
}
}
void SetMousePosition(int x, int y)
{
-
+ XWarpPointer(xGlobalDisplay, None, DefaultRootWindow(xGlobalDisplay), 0, 0, 0, 0, x, y);
+ XFlush(xGlobalDisplay);
}
void SetMouseRange(Window window, Box box)
{
if(window.rootWindow.windowHandle)
XDefineCursor(xGlobalDisplay, (X11Window) window.rootWindow.windowHandle,
- cursor == -1 ? (X11Cursor)0 : systemCursors[(SystemCursor)cursor]);
+ (acquiredInputWindow || cursor == -1) ? nullCursor : systemCursors[(SystemCursor)cursor]);
}
// --- Caret ---
bool AcquireInput(Window window, bool state)
{
- return false;
+ if(state && window)
+ {
+ GetMousePosition(&acquireStart.x, &acquireStart.y);
+ lastMouse = acquireStart;
+ acquiredInputWindow = window;
+ incref acquiredInputWindow;
+ }
+ else if(acquiredInputWindow)
+ delete acquiredInputWindow;
+ return true;
}
bool GetMouseState(MouseButtons * buttons, int * x, int * y)
{
bool result = false;
- if(x) *x = 0;
- if(y) *y = 0;
+ if(acquiredInputWindow && guiApp.desktop.active)
+ {
+ if(x) *x = lastMouse.x - acquireStart.x;
+ if(y) *y = lastMouse.y - acquireStart.y;
+ *buttons = buttonsState;
+ SetMousePosition(acquireStart.x, acquireStart.y);
+ lastMouse = acquireStart;
+ result = true;
+ }
+ else
+ {
+ if(x) *x = 0;
+ if(y) *y = 0;
+ if(buttons) *buttons = 0;
+ }
return result;
}
bool GetKeyState(Key key)
{
- int keyState = 0;
- return keyState;
+ if(key == capsState || key == numState || key == scrollState)
+ {
+ Atom atom = None;
+ X11Bool state = 0;
+ int idx = 0;
+ switch(key)
+ {
+ case capsState: atom = atoms[capsLock]; idx = 0; break;
+ case numState: atom = atoms[numLock]; idx = 1; break;
+ case scrollState: atom = atoms[scrollLock]; idx = 2; break;
+ }
+ /*XkbGetIndicatorState(xGlobalDisplay, XkbUseCoreKbd, &state);
+ state = (state & (1 << idx)) ? 1 : 0;*/
+ XkbGetNamedIndicator(xGlobalDisplay, /*XkbUseCoreKbd,*/ atom, &idx, &state, NULL, NULL);
+ return (bool)state;
+ }
+ else
+ return keyStates[key.code];
}
void SetTimerResolution(uint hertz)