CtrlCore: X11 xinerama support #587 (thanks Klugier!), GTK backend now default

git-svn-id: svn://ultimatepp.org/upp/trunk@6695 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2013-12-26 10:31:14 +00:00
parent 2fbcc5d08a
commit d5b1c4a2c4
6 changed files with 104 additions and 30 deletions

View file

@ -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

View file

@ -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;

View file

@ -455,16 +455,65 @@ void Ctrl::ExitX11()
XCloseIM(xim);
}
Vector<Rect> FindScreensResolutions()
{
Vector<Rect> 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<Rect> FindScreensStruts()
{
Vector<Rect> struts;
Vector<int> clients = GetPropertyInts(Xroot, XAtom("_NET_CLIENT_LIST"));
for (int i = 0; i < clients.GetCount(); i++) {
Vector<int> 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<Rect> 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<Rect>& 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<int> 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<Rect> workAreas = FindScreensResolutions();
Vector<Rect> 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<Rect> screens = FindScreensResolutions();
screens.GetCount() ? r = screens[0] : r = GetVirtualScreenArea();
}
return r;
}
int Ctrl::GetKbdDelay()
{
return 250;

View file

@ -12,6 +12,7 @@
#include <X11/Xft/Xft.h>
#include <X11/extensions/Xrender.h>
#include <X11/extensions/Xinerama.h>
#undef Picture
#undef Time

View file

@ -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);

View file

@ -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<EditString>, 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))