diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index cdbf68612..02554893e 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -10,10 +10,13 @@ #ifdef PLATFORM_WIN32 #define GUIPLATFORM_INCLUDE "Win32Gui.h" #else - #ifdef flagGTK - #define GUIPLATFORM_INCLUDE "Gtk.h" - #else + #ifdef flagX11 #define GUIPLATFORM_INCLUDE "X11Gui.h" + #else + #ifndef flagGTK + #define flagGTK + #endif + #define GUIPLATFORM_INCLUDE "Gtk.h" #endif #endif diff --git a/uppsrc/CtrlCore/CtrlCore.upp b/uppsrc/CtrlCore/CtrlCore.upp index afee7cbe1..55e827d39 100644 --- a/uppsrc/CtrlCore/CtrlCore.upp +++ b/uppsrc/CtrlCore/CtrlCore.upp @@ -13,7 +13,7 @@ library((LINUX | BSD) & GTK3) "gtk-3.0 gdk-3.0 atk-1.0 gdk_3.0 m pangocairo library(WIN32 !MSC8ARM) "user32 gdi32"; -library(LINUX !RAINBOW) "X11 Xrender"; +library(LINUX !RAINBOW) "X11 Xrender Xinerama"; library(LINUX !RAINBOW) dl; diff --git a/uppsrc/CtrlCore/X11App.cpp b/uppsrc/CtrlCore/X11App.cpp index 98ebcc617..378ad3377 100644 --- a/uppsrc/CtrlCore/X11App.cpp +++ b/uppsrc/CtrlCore/X11App.cpp @@ -455,16 +455,65 @@ void Ctrl::ExitX11() XCloseIM(xim); } +Vector FindScreensResolutions() +{ + Vector screensResolutions; + int event, error; + + if(XineramaQueryExtension(Xdisplay, &event, &error)) { + if(XineramaIsActive(Xdisplay)) { + int screensNumber = 0; + XineramaScreenInfo* info = XineramaQueryScreens(Xdisplay, &screensNumber); + for(int i = 0; i < screensNumber; i++) + screensResolutions.Add(Rect(info[i].x_org, info[i].y_org, info[i].x_org + info[i].width, info[i].y_org + info[i].height)); + XFree(info); + } + } + return screensResolutions; +} + +Vector FindScreensStruts() +{ + Vector struts; + + Vector clients = GetPropertyInts(Xroot, XAtom("_NET_CLIENT_LIST")); + for (int i = 0; i < clients.GetCount(); i++) { + Vector strut = GetPropertyInts(clients[i], XAtom("_NET_WM_STRUT")); + if(strut.GetCount() == 4) + struts.Add(Rect(strut[0], strut[2], strut[1], strut[3])); + } + return struts; +} + Rect Ctrl::GetDefaultWindowRect() { - GuiLock __; - static int pos = min(Xwidth / 10, 50); + GuiLock __; + + static int width = 0; + static int height = 0; + static int left = 0; + static int top = 0; + if (width == 0 && height == 0) { + Vector screens = FindScreensResolutions(); + if(screens.GetCount()) { + width = screens[0].Width(); + height = screens[0].Height(); + left = screens[0].left; + top = screens[0].top; + } + else { + width = Xwidth; + height = Xheight; + } + } + + static int pos = min(width / 10, 50); pos += 10; - int cx = Xwidth * 2 / 3; - int cy = Xheight * 2 / 3; - if(pos + cx + 50 > Xwidth || pos + cy + 50 > Xheight) + int cx = width * 2 / 3; + int cy = height * 2 / 3; + if(pos + cx + 50 > width || pos + cy + 50 > height) pos = 0; - return RectC(pos + 20, pos + 20, cx, cy); + return RectC(left + pos + 20, top + pos + 20, cx, cy); } void Ctrl::GetWorkArea(Array& out) @@ -489,17 +538,8 @@ Rect Ctrl::GetWorkArea(Point pt) Rect Ctrl::GetVirtualWorkArea() { - return GetPrimaryWorkArea(); -} - -Rect Ctrl::GetVirtualScreenArea() -{ - return GetPrimaryScreenArea(); -} - -Rect Ctrl::GetPrimaryWorkArea() -{ - GuiLock __; + GuiLock __; + static Rect r; if(r.right == 0) { Vector x = GetPropertyInts(Xroot, XAtom("_NET_WORKAREA")); @@ -511,11 +551,42 @@ Rect Ctrl::GetPrimaryWorkArea() return r; } -Rect Ctrl::GetPrimaryScreenArea() +Rect Ctrl::GetVirtualScreenArea() { return RectC(0, 0, Xwidth, Xheight); } +Rect Ctrl::GetPrimaryWorkArea() +{ + GuiLock __; + + static Rect r; + if(r.right == 0) { + Vector workAreas = FindScreensResolutions(); + Vector struts = FindScreensStruts(); + for (int i = 0; i < struts.GetCount() && i < workAreas.GetCount(); i++) { + workAreas[i].left += struts[i].left; + workAreas[i].right -= struts[i].right; + workAreas[i].top += struts[i].top; + workAreas[i].bottom -= struts[i].bottom; + } + workAreas.GetCount() ? r = workAreas[0] : r = GetVirtualScreenArea(); + } + return r; +} + +Rect Ctrl::GetPrimaryScreenArea() +{ + GuiLock __; + + static Rect r; + if(r.right == 0) { + Vector screens = FindScreensResolutions(); + screens.GetCount() ? r = screens[0] : r = GetVirtualScreenArea(); + } + return r; +} + int Ctrl::GetKbdDelay() { return 250; diff --git a/uppsrc/CtrlCore/X11Gui.h b/uppsrc/CtrlCore/X11Gui.h index 1bc6b55d9..51e6977b4 100644 --- a/uppsrc/CtrlCore/X11Gui.h +++ b/uppsrc/CtrlCore/X11Gui.h @@ -12,6 +12,7 @@ #include #include +#include #undef Picture #undef Time diff --git a/uppsrc/CtrlCore/X11Top.cpp b/uppsrc/CtrlCore/X11Top.cpp index 795cc169c..9cac72893 100644 --- a/uppsrc/CtrlCore/X11Top.cpp +++ b/uppsrc/CtrlCore/X11Top.cpp @@ -238,21 +238,20 @@ void TopWindow::CenterRect(Ctrl *owner) { GuiLock __; SetupRect(); - if(owner && center == 1 || center == 2) { - Size sz = GetRect().Size(); + if((owner&& center == 1) || center == 2) { Rect r, wr; wr = Ctrl::GetWorkArea(); - GuiLock __; + Size sz = GetRect().Size(); Rect fm = windowFrameMargin; if((fm.left|fm.right|fm.top|fm.bottom) == 0) fm = Rect(8, 32, 8, 8); - if(center == 1) + if(owner && center == 1) r = owner->GetRect(); else r = wr; Point p = r.CenterPos(sz); - if (p.x + sz.cx <= wr.Width() && p.y + sz.cy <= wr.Height()) { + if ((p.x + sz.cx <= wr.Width() + wr.left) && (p.y + sz.cy <= wr.Height() + wr.top)) { r = RectC(p.x, p.y, sz.cx, sz.cy); wr.left += fm.left; wr.right -= fm.right; @@ -267,7 +266,7 @@ void TopWindow::CenterRect(Ctrl *owner) minsize.cx = min(minsize.cx, r.GetWidth()); minsize.cy = min(minsize.cy, r.GetHeight()); SetRect(r); - } + } } } @@ -482,7 +481,7 @@ void TopWindow::SerializePlacement(Stream& s, bool reminimize) LLOG("rect = " << rect << ", overlapped = " << overlapped); if(s.IsLoading()) { if(mn) rect = overlapped; - Rect limit = GetWorkArea(); + Rect limit = GetVirtualWorkArea(); Rect fm = windowFrameMargin; if((fm.left|fm.right|fm.top|fm.bottom) == 0) fm = Rect(8, 32, 8, 8); diff --git a/uppsrc/ide/ide.lay b/uppsrc/ide/ide.lay index eff48db35..574f8e9c8 100644 --- a/uppsrc/ide/ide.lay +++ b/uppsrc/ide/ide.lay @@ -54,7 +54,7 @@ LAYOUT(CustomLayout, 608, 410) END_LAYOUT LAYOUT(RunLayout, 410, 148) - ITEM(Label, dv___0, SetLabel(t_("&Program arguments:")).LeftPosZ(4, 100).TopPosZ(4, 19)) + ITEM(Label, dv___0, SetLabel(t_("&Program arguments:")).LeftPosZ(4, 128).TopPosZ(4, 19)) ITEM(WithDropChoice, arg, HSizePosZ(106, 4).TopPosZ(4, 19)) ITEM(Label, dv___2, SetLabel(t_("&Working directory:")).LeftPosZ(4, 100).TopPosZ(28, 19)) ITEM(EditString, dir, HSizePosZ(106, 4).TopPosZ(28, 19))