summaryrefslogtreecommitdiff
authorsandman <sandman>2002-07-28 00:44:43 (UTC)
committer sandman <sandman>2002-07-28 00:44:43 (UTC)
commit72081cbfef03a69ed6f9ca7826854b6cf10dc2fe (patch) (side-by-side diff)
tree43e67bdc7cbb972f431b3912e2f068df3d2c97bf
parent4baf36396739502c5471950e29f18954cca4517b (diff)
downloadopie-72081cbfef03a69ed6f9ca7826854b6cf10dc2fe.zip
opie-72081cbfef03a69ed6f9ca7826854b6cf10dc2fe.tar.gz
opie-72081cbfef03a69ed6f9ca7826854b6cf10dc2fe.tar.bz2
Workaround for a weird Qt/E bug, resulting in qpe hanging if clipboard
applet is loaded and qpe is terminated via shutdown applet.
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/applets/clipboardapplet/clipboard.cpp15
-rw-r--r--core/applets/clipboardapplet/clipboard.h4
-rw-r--r--core/launcher/desktop.cpp6
3 files changed, 22 insertions, 3 deletions
diff --git a/core/applets/clipboardapplet/clipboard.cpp b/core/applets/clipboardapplet/clipboard.cpp
index 5848d0f..4fbdf6f 100644
--- a/core/applets/clipboardapplet/clipboard.cpp
+++ b/core/applets/clipboardapplet/clipboard.cpp
@@ -29,205 +29,214 @@
#include <qclipboard.h>
#include <qtimer.h>
//===========================================================================
/* XPM */
static const char * paste_xpm[] = {
"14 16 64 1",
" c None",
". c #020202",
"+ c #867616",
"@ c #A69A42",
"# c #BAB676",
"$ c #060606",
"% c #EAD2AA",
"& c #F6F6DA",
"* c #222212",
"= c #86761E",
"- c #868686",
"; c #5A5202",
"> c #8A7E2E",
", c #2C2C2C",
"' c #9A9A9A",
") c #F6EADA",
"! c #AAA262",
"~ c #323232",
"{ c #726A32",
"] c #6E6E6E",
"^ c #C2B69E",
"/ c #9E9E9E",
"( c #EED6BA",
"_ c #F2DEC2",
": c #D2CE8E",
"< c #3A3A3A",
"[ c #EACAA2",
"} c #3E3E3E",
"| c #727272",
"1 c #CECECE",
"2 c #929292",
"3 c #4A462A",
"4 c #424242",
"5 c #666666",
"6 c #C2AE96",
"7 c #767676",
"8 c #D6D6D6",
"9 c #C2C2C2",
"0 c #BFA681",
"a c #1E1E1E",
"b c #FAF6F3",
"c c #AEAEAE",
"d c #C29A6A",
"e c #FEFEFE",
"f c #B6B6B6",
"g c #7E7E7E",
"h c #FAF2E6",
"i c #8E8E8E",
"j c #C6BCAE",
"k c #DEDEDE",
"l c #BEBEBE",
"m c #464646",
"n c #BEAE92",
"o c #262626",
"p c #F2E2CE",
"q c #C2A175",
"r c #CACACA",
"s c #969696",
"t c #8A8A8A",
"u c #828282",
"v c #6A6A6A",
"w c #BEB6AE",
"x c #E2E0E0",
"y c #7A7A7A",
" *{>; ",
" }}}@e:!;}}} ",
"<x8=&:#@+;ll, ",
"}k/=;;3}337|o ",
"<k's24444m45o ",
"}8'ss4xkkk]}a ",
"<1s224keee|b4 ",
"}r2itmkeee]]44",
"<9iitmkeeehkw.",
"<lt-u4keeb)pn.",
"<fu-umkebhp(0.",
"<cugg4kbh)_(q.",
"<cyyymk))p(%q.",
",5vvv4k)p_%[q.",
" ...$mljnn0qd.",
" 4.......,"};
ClipboardApplet::ClipboardApplet( QWidget *parent, const char *name ) : QWidget( parent, name )
{
setFixedWidth ( 14 );
setFixedHeight ( 18 );
m_clipboardPixmap = QPixmap ( paste_xpm );
- QTimer *timer = new QTimer ( this );
+ m_timer = new QTimer ( this );
connect ( QApplication::clipboard ( ), SIGNAL( dataChanged ( )), this, SLOT( newData ( )));
- connect ( timer, SIGNAL( timeout ( )), this, SLOT( newData ( )));
+ connect ( m_timer, SIGNAL( timeout ( )), this, SLOT( newData ( )));
+ connect ( qApp, SIGNAL( aboutToQuit ( )), this, SLOT( shutdown ( )));
- timer-> start ( 1000 );
+ m_timer-> start ( 1500 );
m_menu = 0;
m_dirty = true;
m_lasttext = QString::null;
}
ClipboardApplet::~ClipboardApplet ( )
{
}
+void ClipboardApplet::shutdown ( )
+{
+ // the timer has to be stopped, or Qt/E will hang on quit()
+ // see launcher/desktop.cpp
+
+ m_timer-> stop ( );
+}
+
void ClipboardApplet::mousePressEvent ( QMouseEvent *)
{
if ( m_dirty ) {
delete m_menu;
m_menu = new QPopupMenu ( this );
m_menu-> setCheckable ( true );
if ( m_history. count ( )) {
for ( unsigned int i = 0; i < m_history. count ( ); i++ ) {
QString str = m_history [i];
if ( str. length ( ) > 20 )
str = str. left ( 20 ) + "...";
m_menu-> insertItem ( QString ( "%1: %2" ). arg ( i + 1 ). arg ( str ), i );
m_menu-> setItemChecked ( i, false );
}
m_menu-> setItemChecked ( m_history. count ( ) - 1, true );
m_menu-> insertSeparator ( );
}
m_menu-> insertItem ( QIconSet ( Resource::loadPixmap ( "cut" )), tr( "Cut" ), 100 );
m_menu-> insertItem ( QIconSet ( Resource::loadPixmap ( "copy" )), tr( "Copy" ), 101 );
m_menu-> insertItem ( QIconSet ( Resource::loadPixmap ( "paste" )), tr( "Paste" ), 102 );
connect ( m_menu, SIGNAL( activated ( int )), this, SLOT( action ( int )));
m_dirty = false;
}
QPoint p = mapToGlobal ( QPoint ( 0, 0 ));
QSize s = m_menu-> sizeHint ( );
m_menu-> popup ( QPoint ( p. x ( ) + ( width ( ) / 2 ) - ( s. width ( ) / 2 ), p. y ( ) - s. height ( )));
}
void ClipboardApplet::action(int id)
{
ushort unicode = 0;
int scan = 0;
switch ( id ) {
case 100:
unicode = 'X' - '@';
scan = Key_X; // Cut
break;
case 101:
unicode = 'C' - '@';
scan = Key_C; // Copy
break;
case 102:
unicode = 'V' - '@';
scan = Key_V; // Paste
break;
default:
if (( id >= 0 ) && ( uint( id ) < m_history. count ( ))) {
QApplication::clipboard ( )-> setText ( m_history [id] );
for ( uint i = 0; i < m_history. count ( ); i++ )
m_menu-> setItemChecked ( i, i == uint( id ));
unicode = 'V' - '@';
scan = Key_V;
}
break;
}
if ( scan ) {
qwsServer-> sendKeyEvent ( unicode, scan, ControlButton, true, false );
qwsServer-> sendKeyEvent ( unicode, scan, ControlButton, false, false );
}
}
void ClipboardApplet::paintEvent ( QPaintEvent* )
{
QPainter p ( this );
p. drawPixmap ( 0, 1, m_clipboardPixmap );
}
void ClipboardApplet::newData ( )
{
QCString type = "plain";
QString txt = QApplication::clipboard ( )-> text ( type );
if ( !txt. isEmpty ( ) && !m_history. contains ( txt )) {
m_history. append ( txt );
if ( m_history. count ( ) > 5 )
m_history. remove ( m_history. begin ( ));
m_dirty = true;
}
}
diff --git a/core/applets/clipboardapplet/clipboard.h b/core/applets/clipboardapplet/clipboard.h
index 84743d9..ec87d39 100644
--- a/core/applets/clipboardapplet/clipboard.h
+++ b/core/applets/clipboardapplet/clipboard.h
@@ -1,53 +1,57 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef __CLIPBOARD_APPLET_H__
#define __CLIPBOARD_APPLET_H__
#include <qwidget.h>
#include <qpixmap.h>
#include <qstringlist.h>
+class QTimer;
+
class ClipboardApplet : public QWidget
{
Q_OBJECT
public:
ClipboardApplet ( QWidget *parent = 0, const char *name=0 );
~ClipboardApplet ( );
protected:
void mousePressEvent ( QMouseEvent *);
void paintEvent ( QPaintEvent* );
private slots:
void action ( int );
void newData ( );
+ void shutdown ( );
private:
QPopupMenu * m_menu;
QStringList m_history;
bool m_dirty;
QString m_lasttext;
+ QTimer * m_timer;
QPixmap m_clipboardPixmap;
};
#endif // __CLIPBOARD_APPLET_H__
diff --git a/core/launcher/desktop.cpp b/core/launcher/desktop.cpp
index e58b08c..f90da1a 100644
--- a/core/launcher/desktop.cpp
+++ b/core/launcher/desktop.cpp
@@ -593,192 +593,198 @@ static void blankScreen()
delete g;
*/
blanked = TRUE;
}
static void darkScreen()
{
extern void qpe_setBacklight(int);
qpe_setBacklight(0); // force off
}
void Desktop::togglePower()
{
bool wasloggedin = loggedin;
loggedin=0;
suspendTime = QDateTime::currentDateTime();
darkScreen();
if ( wasloggedin )
blankScreen();
system("apm --suspend");
QWSServer::screenSaverActivate( FALSE );
{
QCopEnvelope("QPE/Card", "mtabChanged()" ); // might have changed while asleep
QCopEnvelope e("QPE/System", "setBacklight(int)");
e << -3; // Force on
}
if ( wasloggedin ) {
login(TRUE);
}
sleep(1);
execAutoStart();
//qcopBridge->closeOpenConnections();
//qDebug("called togglePower()!!!!!!");
}
void Desktop::toggleLight()
{
QCopEnvelope e("QPE/System", "setBacklight(int)");
e << -2; // toggle
}
void Desktop::toggleSymbolInput()
{
tb->toggleSymbolInput();
}
void Desktop::toggleNumLockState()
{
tb->toggleNumLockState();
}
void Desktop::toggleCapsLockState()
{
tb->toggleCapsLockState();
}
void Desktop::styleChange( QStyle &s )
{
QWidget::styleChange( s );
int displayw = qApp->desktop()->width();
int displayh = qApp->desktop()->height();
QSize sz = tb->sizeHint();
tb->setGeometry( 0, displayh-sz.height(), displayw, sz.height() );
}
void DesktopApplication::shutdown()
{
if ( type() != GuiServer )
return;
ShutdownImpl *sd = new ShutdownImpl( 0, 0, WDestructiveClose );
connect( sd, SIGNAL(shutdown(ShutdownImpl::Type)),
this, SLOT(shutdown(ShutdownImpl::Type)) );
sd->showMaximized();
}
void DesktopApplication::shutdown( ShutdownImpl::Type t )
{
switch ( t ) {
case ShutdownImpl::ShutdownSystem:
execlp("shutdown", "shutdown", "-h", "now", (void*)0);
break;
case ShutdownImpl::RebootSystem:
execlp("shutdown", "shutdown", "-r", "now", (void*)0);
break;
case ShutdownImpl::RestartDesktop:
restart();
break;
case ShutdownImpl::TerminateDesktop:
prepareForTermination(FALSE);
+
+ // This is a workaround for a Qt bug
+ // clipboard applet has to stop its poll timer, or Qt/E
+ // will hang on quit() right before it emits aboutToQuit()
+ emit aboutToQuit ( );
+
quit();
break;
}
}
void DesktopApplication::restart()
{
prepareForTermination(TRUE);
#ifdef Q_WS_QWS
for ( int fd = 3; fd < 100; fd++ )
close( fd );
#if defined(QT_DEMO_SINGLE_FLOPPY)
execl( "/sbin/init", "qpe", 0 );
#elif defined(QT_QWS_CASSIOPEIA)
execl( "/bin/sh", "sh", 0 );
#else
execl( (qpeDir()+"/bin/qpe").latin1(), "qpe", 0 );
#endif
exit(1);
#endif
}
void Desktop::startTransferServer()
{
// start qcop bridge server
qcopBridge = new QCopBridge( 4243 );
if ( !qcopBridge->ok() ) {
delete qcopBridge;
qcopBridge = 0;
}
// start transfer server
transferServer = new TransferServer( 4242 );
if ( !transferServer->ok() ) {
delete transferServer;
transferServer = 0;
}
if ( !transferServer || !qcopBridge )
startTimer( 2000 );
}
void Desktop::timerEvent( QTimerEvent *e )
{
killTimer( e->timerId() );
startTransferServer();
}
void Desktop::terminateServers()
{
delete transferServer;
delete qcopBridge;
transferServer = 0;
qcopBridge = 0;
}
void Desktop::rereadVolumes()
{
Config cfg("qpe");
cfg.setGroup("Volume");
touchclick = cfg.readBoolEntry("TouchSound");
keyclick = cfg.readBoolEntry("KeySound");
alarmsound = cfg.readBoolEntry("AlarmSound");
// Config cfg("Sound");
// cfg.setGroup("System");
// touchclick = cfg.readBoolEntry("Touch");
// keyclick = cfg.readBoolEntry("Key");
}
void Desktop::keyClick()
{
if ( keyclick )
ODevice::inst ( )-> keySound ( );
}
void Desktop::screenClick()
{
if ( touchclick )
ODevice::inst ( )-> touchSound ( );
}
void Desktop::soundAlarm()
{
if ( qpedesktop-> alarmsound )
ODevice::inst ( )-> alarmSound ( );
}
bool Desktop::eventFilter( QObject *, QEvent *ev )
{
if ( ev-> type ( ) == QEvent::KeyPress ) {
QKeyEvent *ke = (QKeyEvent *) ev;
if ( ke-> key ( ) == Qt::Key_F11 ) { // menu key
QWidget *active = qApp-> activeWindow ( );
if ( active && active-> isPopup ( ))
active->close();