Update twin with initial framework for application suspend/resume

This needs some additional work before it can be enabled
pull/2/head
Timothy Pearson 12 years ago
parent a515552a21
commit d160a6fc01

@ -13,6 +13,8 @@ class KWinInterface : virtual public DCOPObject
virtual ASYNC unclutterDesktop() = 0;
virtual ASYNC reconfigure() = 0;
virtual ASYNC killWindow() = 0;
virtual ASYNC suspendWindow() = 0;
virtual ASYNC resumeWindow() = 0;
virtual void refresh() = 0;
virtual void doNotManage(TQString)= 0;
virtual void showWindowMenuAt(unsigned long winId, int x, int y)= 0;

@ -1834,6 +1834,124 @@ void Client::killProcess( bool ask, Time timestamp )
}
}
bool Client::isSuspendable() const
{
TQCString machine = wmClientMachine( true );
pid_t pid = info->pid();
if( pid <= 0 || machine.isEmpty()) // needed properties missing
return false;
kdDebug( 1212 ) << "Suspend process:" << pid << "(" << machine << ")" << endl;
if( machine != "localhost" )
{
return false;
}
else
{
FILE *procfile;
if(chdir(TQString("/proc/%1").arg(pid).ascii()) == 0)
{
procfile = fopen("stat", "r");
}
if(!procfile)
{
return false;
}
else
{
long long int procpid;
char tcomm[PATH_MAX];
char state;
fscanf(procfile, "%lld ", &procpid);
fscanf(procfile, "%s ", tcomm);
fscanf(procfile, "%c ", &state);
if( state != 'T' )
{
fclose(procfile);
return true;
}
else
{
fclose(procfile);
return false;
}
}
}
}
bool Client::isResumeable() const
{
TQCString machine = wmClientMachine( true );
pid_t pid = info->pid();
if( pid <= 0 || machine.isEmpty()) // needed properties missing
return false;
kdDebug( 1212 ) << "Suspend process:" << pid << "(" << machine << ")" << endl;
if( machine != "localhost" )
{
return false;
}
else
{
FILE *procfile;
if(chdir(TQString("/proc/%1").arg(pid).ascii()) == 0)
{
procfile = fopen("stat", "r");
}
if(!procfile)
{
return false;
}
else
{
long long int procpid;
char tcomm[PATH_MAX];
char state;
fscanf(procfile, "%lld ", &procpid);
fscanf(procfile, "%s ", tcomm);
fscanf(procfile, "%c ", &state);
if( state == 'T' )
{
fclose(procfile);
return true;
}
else
{
fclose(procfile);
return false;
}
}
}
}
void Client::suspendWindow()
{
TQCString machine = wmClientMachine( true );
pid_t pid = info->pid();
if( pid <= 0 || machine.isEmpty()) // needed properties missing
return;
kdDebug( 1212 ) << "Suspend process:" << pid << "(" << machine << ")" << endl;
if( machine != "localhost" )
{
return;
}
else
::kill( pid, SIGSTOP );
}
void Client::resumeWindow()
{
TQCString machine = wmClientMachine( true );
pid_t pid = info->pid();
if( pid <= 0 || machine.isEmpty()) // needed properties missing
return;
kdDebug( 1212 ) << "Resume process:" << pid << "(" << machine << ")" << endl;
if( machine != "localhost" )
{
return;
}
else
::kill( pid, SIGCONT );
}
void Client::processKillerExited()
{
kdDebug( 1212 ) << "Killer exited" << endl;

@ -113,6 +113,9 @@ class Client : public TQObject, public KDecorationDefines
bool isActive() const;
void setActive( bool, bool updateOpacity = true );
bool isSuspendable() const;
bool isResumeable() const;
int desktop() const;
void setDesktop( int );
bool isOnDesktop( int d ) const;
@ -297,6 +300,8 @@ class Client : public TQObject, public KDecorationDefines
void unminimize( bool avoid_animation = false );
void closeWindow();
void killWindow();
void suspendWindow();
void resumeWindow();
void maximize( MaximizeMode );
void toggleShade();
void showContextHelp();

@ -100,7 +100,9 @@ public:
NoOp,
SetupWindowShortcutOp,
ApplicationRulesOp, ///< @since 3.5
ShadowOp ///< @since 3.5.12
ShadowOp, ///< @since 3.5.12
SuspendWindowOp, ///< @since R14.0
ResumeWindowOp ///< @since R14.0
};
/**
* Basic color types that should be recognized by all decoration styles.

@ -68,6 +68,10 @@ TQPopupMenu* Workspace::clientPopup()
advanced_popup->insertItem( i18n("Shad&ow"), Options::ShadowOp );
advanced_popup->insertItem( SmallIconSet("key_bindings"),
i18n("Window &Shortcut...")+'\t'+keys->shortcut("Setup Window Shortcut").seq(0).toString(), Options::SetupWindowShortcutOp );
// FIXME
// Uncomment these actions when twin can handle suspended applications in a user friendly manner
// advanced_popup->insertItem( SmallIconSet( "suspend" ), i18n("&Suspend Application"), Options::SuspendWindowOp );
// advanced_popup->insertItem( SmallIconSet( "exec" ), i18n("&Resume Application"), Options::ResumeWindowOp );
advanced_popup->insertItem( SmallIconSet( "wizard" ), i18n("&Special Window Settings..."), Options::WindowRulesOp );
advanced_popup->insertItem( SmallIconSet( "wizard" ), i18n("&Special Application Settings..."), Options::ApplicationRulesOp );
@ -171,6 +175,8 @@ void Workspace::clientPopupAboutToShow()
advanced_popup->setItemChecked( Options::KeepBelowOp, active_popup_client->keepBelow() );
advanced_popup->setItemChecked( Options::FullScreenOp, active_popup_client->isFullScreen() );
advanced_popup->setItemEnabled( Options::FullScreenOp, active_popup_client->userCanSetFullScreen() );
advanced_popup->setItemEnabled( Options::SuspendWindowOp, active_popup_client->isSuspendable() );
advanced_popup->setItemEnabled( Options::ResumeWindowOp, active_popup_client->isResumeable() );
advanced_popup->setItemChecked( Options::NoBorderOp, active_popup_client->noBorder() );
advanced_popup->setItemEnabled( Options::NoBorderOp, active_popup_client->userCanSetNoBorder() );
@ -436,6 +442,12 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
case Options::OperationsOp:
c->performMouseCommand( Options::MouseShade, TQCursor::pos());
break;
case Options::SuspendWindowOp:
c->suspendWindow();
break;
case Options::ResumeWindowOp:
c->resumeWindow();
break;
case Options::WindowRulesOp:
editWindowRules( c, false );
break;
@ -991,6 +1003,22 @@ void Workspace::slotKillWindow()
kill.start();
}
/*!
Suspend Window feature
*/
void Workspace::slotSuspendWindow()
{
active_popup_client->suspendWindow();
}
/*!
Resume Window feature
*/
void Workspace::slotResumeWindow()
{
active_popup_client->resumeWindow();
}
/*!
Sends the popup client to desktop \a desk

@ -1909,6 +1909,60 @@ void Workspace::killWindowId( Window window_to_kill )
XKillClient( qt_xdisplay(), window_to_kill );
}
void Workspace::suspendWindowId( Window window_to_suspend )
{
if( window_to_suspend == None )
return;
Window window = window_to_suspend;
Client* client = NULL;
for(;;)
{
client = findClient( FrameIdMatchPredicate( window ));
if( client != NULL ) // found the client
break;
Window parent, root;
Window* children;
unsigned int children_count;
XQueryTree( qt_xdisplay(), window, &root, &parent, &children, &children_count );
if( children != NULL )
XFree( children );
if( window == root ) // we didn't find the client, probably an override-redirect window
break;
window = parent; // go up
}
if( client != NULL )
client->suspendWindow();
else
return;
}
void Workspace::resumeWindowId( Window window_to_resume )
{
if( window_to_resume == None )
return;
Window window = window_to_resume;
Client* client = NULL;
for(;;)
{
client = findClient( FrameIdMatchPredicate( window ));
if( client != NULL ) // found the client
break;
Window parent, root;
Window* children;
unsigned int children_count;
XQueryTree( qt_xdisplay(), window, &root, &parent, &children, &children_count );
if( children != NULL )
XFree( children );
if( window == root ) // we didn't find the client, probably an override-redirect window
break;
window = parent; // go up
}
if( client != NULL )
client->resumeWindow();
else
return;
}
void Workspace::sendPingToWindow( Window window, Time timestamp )
{

@ -97,8 +97,12 @@ class Workspace : public TQObject, public KWinInterface, public KDecorationDefin
* @internal
*/
void killWindowId( Window window);
void suspendWindowId( Window window);
void resumeWindowId( Window window);
void killWindow() { slotKillWindow(); }
void suspendWindow() { slotSuspendWindow(); }
void resumeWindow() { slotResumeWindow(); }
WId rootWin() const;
@ -369,6 +373,8 @@ class Workspace : public TQObject, public KWinInterface, public KDecorationDefin
void slotReconfigure();
void slotKillWindow();
void slotSuspendWindow();
void slotResumeWindow();
void slotGrabWindow();
void slotGrabDesktop();

Loading…
Cancel
Save