Commit aba27511 authored by Lamarque Souza's avatar Lamarque Souza
Browse files

Fix can't switch back to laptop display when external display gets

disconnected.

REVIEW: 6513
BUG: 257642
BUG: 265955
FIXED-IN: 4.7.0
(cherry picked from commit 505c9e0c)
parent 50f1bf7a
......@@ -33,10 +33,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <qtimer.h>
#include <qx11info_x11.h>
#include <randrdisplay.h>
#include <randrscreen.h>
#include <randroutput.h>
K_PLUGIN_FACTORY(RandrMonitorModuleFactory,
registerPlugin<RandrMonitorModule>();
)
......@@ -48,6 +44,7 @@ RandrMonitorModule::RandrMonitorModule( QObject* parent, const QList<QVariant>&
{
setModuleName( "randrmonitor" );
initRandr();
QDBusConnection::sessionBus().connect("org.kde.Solid.PowerManagement", "/org/kde/Solid/PowerManagement", "org.kde.Solid.PowerManagement", "resumingFromSuspend", this, SLOT(resumedFromSuspend()));
}
RandrMonitorModule::~RandrMonitorModule()
......@@ -159,20 +156,22 @@ void RandrMonitorModule::switchDisplay()
{
QList< RandROutput* > outputs;
RandRDisplay display;
for( int scr = 0;
scr < display.numScreens();
++scr )
outputs = connectedOutputs( display );
if( outputs.count() == 0 ) // nothing connected, do nothing
return;
if( outputs.count() == 1 ) // just one, enable it
{
foreach( RandROutput* output, display.screen( scr )->outputs())
enableOutput( outputs[0], true );
for( int scr = 0; scr < display.numScreens(); ++scr )
{
if( !output->isConnected())
continue;
if( !outputs.contains( output ))
outputs.append( output );
foreach( RandROutput* output, display.screen( scr )->outputs())
{
if( !output->isConnected())
enableOutput( output, false ); // switch off every output that's not connected
}
}
}
if( outputs.count() <= 1 ) // just one, do nothing
return;
}
if( outputs.count() == 2 ) // alternative between one, second, both
{
if( outputs[ 0 ]->isActive() && !outputs[ 1 ]->isActive())
......@@ -196,11 +195,73 @@ void RandrMonitorModule::switchDisplay()
KToolInvocation::kdeinitExec( "kcmshell4", QStringList() << "display" );
}
void RandrMonitorModule::resumedFromSuspend()
{
RandRDisplay display;
QList< RandROutput* > m_connectedOutputs, m_validCrtcOutputs;
m_connectedOutputs = connectedOutputs( display );
m_validCrtcOutputs = validCrtcOutputs( display );
if( m_connectedOutputs.count() == 0 )
return;
// We have at least one connected output.
// We check all outputs with valid crtc if they are still connected.
// If not, we are going to disable them.
QList<RandROutput*> outputsToDisable;
foreach( RandROutput* output, m_validCrtcOutputs )
{
if( !output->isConnected() )
outputsToDisable.append( output );
}
// If no active output is still connected we are going to enable the first connected output.
if( outputsToDisable.size() == m_validCrtcOutputs.size() )
enableOutput( m_connectedOutputs[0], true);
// Now we can disable the disconnected outputs
foreach( RandROutput* output, outputsToDisable)
{
enableOutput( output, false );
}
}
void RandrMonitorModule::enableOutput( RandROutput* output, bool enable )
{ // a bit lame, but I don't know how to do this easily with this codebase :-/
KProcess::execute( QStringList() << "xrandr" << "--output" << output->name() << ( enable ? "--auto" : "--off" ));
}
QList< RandROutput* > RandrMonitorModule::connectedOutputs( RandRDisplay &display )
{
return outputs( display, true, false, false );
}
QList< RandROutput* > RandrMonitorModule::activeOutputs( RandRDisplay &display )
{
return outputs( display, false, true, false );
}
QList< RandROutput* > RandrMonitorModule::validCrtcOutputs( RandRDisplay &display )
{
return outputs( display, false, false, true );
}
QList< RandROutput* > RandrMonitorModule::outputs( RandRDisplay &display, bool connected, bool active, bool validCrtc )
{
QList< RandROutput* > outputs;
for( int scr = 0; scr < display.numScreens(); ++scr )
{
foreach( RandROutput* output, display.screen( scr )->outputs() )
{
if( !output->isConnected() && connected )
continue;
if( !output->isActive() && active )
continue;
if( !output->crtc()->isValid() && validCrtc )
continue;
if( !outputs.contains( output ) )
outputs.append( output );
}
}
return outputs;
}
bool RandrMonitorHelper::x11Event( XEvent* e )
{
module->processX11Event( e );
......
......@@ -27,6 +27,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <X11/extensions/Xrandr.h>
#include <fixx11h.h>
#include <randrdisplay.h>
#include <randrscreen.h>
#include <randroutput.h>
#include <randrcrtc.h>
class RandROutput;
class RandrMonitorHelper;
......@@ -42,11 +47,16 @@ class RandrMonitorModule
private slots:
void poll();
void switchDisplay();
void resumedFromSuspend();
private:
void initRandr();
void getRandrInfo( XRROutputChangeNotifyEvent* e, QString* change, QRect* rect );
QStringList connectedMonitors() const;
void enableOutput( RandROutput* output, bool enable );
QList< RandROutput* > connectedOutputs( RandRDisplay &display );
QList< RandROutput* > activeOutputs( RandRDisplay &display );
QList< RandROutput* > validCrtcOutputs( RandRDisplay &display );
QList< RandROutput* > outputs( RandRDisplay &display, bool connected = false, bool active = false, bool validCrtc = false );
bool have_randr;
int randr_base;
int randr_error;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment