Add basic multihead support to kwin
For now there is autostart support on all screens and support for different resolutions on different screens. Keyboard shortcuts are still TODO REVIEW: 101125 BUG: 256242icc-effect-5.14.5
parent
2534acc961
commit
9bbed0335a
65
geometry.cpp
65
geometry.cpp
|
@ -56,6 +56,9 @@ namespace KWin
|
|||
// Workspace
|
||||
//********************************************
|
||||
|
||||
extern int screen_number;
|
||||
extern bool is_multihead;
|
||||
|
||||
/*!
|
||||
Resizes the workspace after an XRANDR screen size change
|
||||
*/
|
||||
|
@ -236,6 +239,7 @@ void Workspace::updateClientArea()
|
|||
|
||||
\sa geometry()
|
||||
*/
|
||||
|
||||
QRect Workspace::clientArea(clientAreaOption opt, int screen, int desktop) const
|
||||
{
|
||||
if (desktop == NETWinInfo::OnAllDesktops || desktop == 0)
|
||||
|
@ -243,49 +247,82 @@ QRect Workspace::clientArea(clientAreaOption opt, int screen, int desktop) const
|
|||
if (screen == -1)
|
||||
screen = activeScreen();
|
||||
|
||||
QRect sarea = (!screenarea.isEmpty()
|
||||
QRect sarea, warea;
|
||||
|
||||
if (is_multihead) {
|
||||
sarea = (!screenarea.isEmpty()
|
||||
&& screen < screenarea[ desktop ].size()) // screens may be missing during KWin initialization or screen config changes
|
||||
? screenarea[ desktop ][ screen ]
|
||||
: Kephal::ScreenUtils::screenGeometry(screen);
|
||||
QRect warea = workarea[ desktop ].isNull()
|
||||
? Kephal::ScreenUtils::desktopGeometry()
|
||||
: workarea[ desktop ];
|
||||
? screenarea[ desktop ][ screen_number ]
|
||||
: Kephal::ScreenUtils::screenGeometry(screen_number);
|
||||
warea = workarea[ desktop ].isNull()
|
||||
? Kephal::ScreenUtils::screenGeometry(screen_number)
|
||||
: workarea[ desktop ];
|
||||
} else {
|
||||
sarea = (!screenarea.isEmpty()
|
||||
&& screen < screenarea[ desktop ].size()) // screens may be missing during KWin initialization or screen config changes
|
||||
? screenarea[ desktop ][ screen ]
|
||||
: Kephal::ScreenUtils::screenGeometry(screen);
|
||||
warea = workarea[ desktop ].isNull()
|
||||
? Kephal::ScreenUtils::desktopGeometry()
|
||||
: workarea[ desktop ];
|
||||
}
|
||||
|
||||
switch(opt) {
|
||||
case MaximizeArea:
|
||||
if (options->xineramaMaximizeEnabled)
|
||||
if (is_multihead)
|
||||
return sarea;
|
||||
else if (options->xineramaMaximizeEnabled)
|
||||
return sarea;
|
||||
else
|
||||
return warea;
|
||||
case MaximizeFullArea:
|
||||
if (options->xineramaMaximizeEnabled)
|
||||
if (is_multihead)
|
||||
return Kephal::ScreenUtils::screenGeometry(screen_number);
|
||||
else if (options->xineramaMaximizeEnabled)
|
||||
return Kephal::ScreenUtils::screenGeometry(screen);
|
||||
else
|
||||
return Kephal::ScreenUtils::desktopGeometry();
|
||||
case FullScreenArea:
|
||||
if (options->xineramaFullscreenEnabled)
|
||||
if (is_multihead)
|
||||
return Kephal::ScreenUtils::screenGeometry(screen_number);
|
||||
else if (options->xineramaFullscreenEnabled)
|
||||
return Kephal::ScreenUtils::screenGeometry(screen);
|
||||
else
|
||||
return Kephal::ScreenUtils::desktopGeometry();
|
||||
case PlacementArea:
|
||||
if (options->xineramaPlacementEnabled)
|
||||
if (is_multihead)
|
||||
return sarea;
|
||||
else if (options->xineramaPlacementEnabled)
|
||||
return sarea;
|
||||
else
|
||||
return warea;
|
||||
case MovementArea:
|
||||
if (options->xineramaMovementEnabled)
|
||||
if (is_multihead)
|
||||
return Kephal::ScreenUtils::screenGeometry(screen_number);
|
||||
else if (options->xineramaMovementEnabled)
|
||||
return Kephal::ScreenUtils::screenGeometry(screen);
|
||||
else
|
||||
return Kephal::ScreenUtils::desktopGeometry();
|
||||
case WorkArea:
|
||||
return warea;
|
||||
if (is_multihead)
|
||||
return sarea;
|
||||
else
|
||||
return warea;
|
||||
case FullArea:
|
||||
return Kephal::ScreenUtils::desktopGeometry();
|
||||
if (is_multihead)
|
||||
return Kephal::ScreenUtils::screenGeometry(screen_number);
|
||||
else
|
||||
return Kephal::ScreenUtils::desktopGeometry();
|
||||
case ScreenArea:
|
||||
return Kephal::ScreenUtils::screenGeometry(screen);
|
||||
if (is_multihead)
|
||||
return Kephal::ScreenUtils::screenGeometry(screen_number);
|
||||
else
|
||||
return Kephal::ScreenUtils::screenGeometry(screen);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
QRect Workspace::clientArea(clientAreaOption opt, const QPoint& p, int desktop) const
|
||||
{
|
||||
int screen = Kephal::ScreenUtils::screenId(p);
|
||||
|
|
80
main.cpp
80
main.cpp
|
@ -74,6 +74,7 @@ Options* options;
|
|||
Atoms* atoms;
|
||||
|
||||
int screen_number = -1;
|
||||
bool is_multihead = false;
|
||||
|
||||
bool initting = false;
|
||||
|
||||
|
@ -407,50 +408,45 @@ KDE_EXPORT int kdemain(int argc, char * argv[])
|
|||
// or command line settings to raster or OpenGL.
|
||||
QApplication::setGraphicsSystem("native");
|
||||
|
||||
if (!restored) {
|
||||
// We only do the multihead fork if we are not restored by the session
|
||||
// manager, since the session manager will register multiple kwins,
|
||||
// one for each screen...
|
||||
QByteArray multiHead = qgetenv("KDE_MULTIHEAD");
|
||||
if (multiHead.toLower() == "true") {
|
||||
Display* dpy = XOpenDisplay(NULL);
|
||||
if (!dpy) {
|
||||
fprintf(stderr, "%s: FATAL ERROR while trying to open display %s\n",
|
||||
argv[0], XDisplayName(NULL));
|
||||
exit(1);
|
||||
Display* dpy = XOpenDisplay(NULL);
|
||||
if (!dpy) {
|
||||
fprintf(stderr, "%s: FATAL ERROR while trying to open display %s\n",
|
||||
argv[0], XDisplayName(NULL));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int number_of_screens = ScreenCount(dpy);
|
||||
|
||||
// multi head
|
||||
if (number_of_screens != 1) {
|
||||
KWin::is_multihead = true;
|
||||
KWin::screen_number = DefaultScreen(dpy);
|
||||
int pos; // Temporarily needed to reconstruct DISPLAY var if multi-head
|
||||
QByteArray display_name = XDisplayString(dpy);
|
||||
XCloseDisplay(dpy);
|
||||
dpy = 0;
|
||||
|
||||
if ((pos = display_name.lastIndexOf('.')) != -1)
|
||||
display_name.remove(pos, 10); // 10 is enough to be sure we removed ".s"
|
||||
|
||||
QString envir;
|
||||
for (int i = 0; i < number_of_screens; i++) {
|
||||
// If execution doesn't pass by here, then kwin
|
||||
// acts exactly as previously
|
||||
if (i != KWin::screen_number && fork() == 0) {
|
||||
KWin::screen_number = i;
|
||||
// Break here because we are the child process, we don't
|
||||
// want to fork() anymore
|
||||
break;
|
||||
}
|
||||
}
|
||||
// In the next statement, display_name shouldn't contain a screen
|
||||
// number. If it had it, it was removed at the "pos" check
|
||||
envir.sprintf("DISPLAY=%s.%d", display_name.data(), KWin::screen_number);
|
||||
|
||||
int number_of_screens = ScreenCount(dpy);
|
||||
KWin::screen_number = DefaultScreen(dpy);
|
||||
int pos; // Temporarily needed to reconstruct DISPLAY var if multi-head
|
||||
QByteArray display_name = XDisplayString(dpy);
|
||||
XCloseDisplay(dpy);
|
||||
dpy = 0;
|
||||
|
||||
if ((pos = display_name.lastIndexOf('.')) != -1)
|
||||
display_name.remove(pos, 10); // 10 is enough to be sure we removed ".s"
|
||||
|
||||
QString envir;
|
||||
if (number_of_screens != 1) {
|
||||
for (int i = 0; i < number_of_screens; i++) {
|
||||
// If execution doesn't pass by here, then kwin
|
||||
// acts exactly as previously
|
||||
if (i != KWin::screen_number && fork() == 0) {
|
||||
KWin::screen_number = i;
|
||||
// Break here because we are the child process, we don't
|
||||
// want to fork() anymore
|
||||
break;
|
||||
}
|
||||
}
|
||||
// In the next statement, display_name shouldn't contain a screen
|
||||
// number. If it had it, it was removed at the "pos" check
|
||||
envir.sprintf("DISPLAY=%s.%d", display_name.data(), KWin::screen_number);
|
||||
|
||||
if (putenv(strdup(envir.toAscii()))) {
|
||||
fprintf(stderr, "%s: WARNING: unable to set DISPLAY environment variable\n", argv[0]);
|
||||
perror("putenv()");
|
||||
}
|
||||
}
|
||||
if (putenv(strdup(envir.toAscii()))) {
|
||||
fprintf(stderr, "%s: WARNING: unable to set DISPLAY environment variable\n", argv[0]);
|
||||
perror("putenv()");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue