summaryrefslogtreecommitdiff
authorsandman <sandman>2002-12-22 23:59:13 (UTC)
committer sandman <sandman>2002-12-22 23:59:13 (UTC)
commitc513f413c7d901cc9945714c8e7eb47292f63306 (patch) (unidiff)
tree9ce6af28225f006dffbeb536eb2fd520e903e08d
parent5c7694a7baadec8afe128ad2541e0a8acfc23737 (diff)
downloadopie-c513f413c7d901cc9945714c8e7eb47292f63306.zip
opie-c513f413c7d901cc9945714c8e7eb47292f63306.tar.gz
opie-c513f413c7d901cc9945714c8e7eb47292f63306.tar.bz2
Totally reworked the key grabbing, which always had problems:
- applications get *all* key events now, as long as they have the focus - an application decides if it has the keyboard grabbed or not - if it's grabbed, the app consumes the key press - if it's not grabbed and a F1-F29 key is pressed, the app sends a QCop call to the launcher (deviceButtonPressed(...)) - when the launcher receives a QCop deviceButtonPressed it simply sends the configured QCopEnvelope - all "special" actions (like menu, home) are now accessible via QCop calls (see buttonsettings)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/qpeapplication.cpp121
-rw-r--r--library/qpeapplication.h1
-rw-r--r--library/qpemenubar.cpp4
3 files changed, 54 insertions, 72 deletions
diff --git a/library/qpeapplication.cpp b/library/qpeapplication.cpp
index b26933b..e7e210a 100644
--- a/library/qpeapplication.cpp
+++ b/library/qpeapplication.cpp
@@ -83,40 +83,39 @@
83 83
84#include <unistd.h> 84#include <unistd.h>
85#include <sys/file.h> 85#include <sys/file.h>
86#include <sys/ioctl.h> 86#include <sys/ioctl.h>
87#include <sys/soundcard.h> 87#include <sys/soundcard.h>
88 88
89#include "qt_override_p.h" 89#include "qt_override_p.h"
90 90
91 91
92class QPEApplicationData 92class QPEApplicationData
93{ 93{
94public: 94public:
95 QPEApplicationData() : presstimer( 0 ), presswidget( 0 ), kbgrabber( 0 ), 95 QPEApplicationData ( )
96 rightpressed( FALSE ), kbregrab( FALSE ), notbusysent( FALSE ), preloaded( FALSE ), 96 : presstimer( 0 ), presswidget( 0 ), rightpressed( false ), kbgrabbed( false ),
97 forceshow( FALSE ), nomaximize( FALSE ), keep_running( TRUE ), qpe_main_widget( 0 ) 97 notbusysent( false ), preloaded( false ), forceshow( false ), nomaximize( false ),
98 keep_running( true ), qpe_main_widget( 0 )
98 99
99 { 100 {
100 qcopq.setAutoDelete( TRUE ); 101 qcopq.setAutoDelete( TRUE );
101 } 102 }
102 103
103 int presstimer; 104 int presstimer;
104 QWidget* presswidget; 105 QWidget* presswidget;
105 int kbgrabber;
106 QString kbgrabber_appname;
107 QPoint presspos; 106 QPoint presspos;
108 107
109 bool rightpressed : 1; 108 bool rightpressed : 1;
110 bool kbregrab : 1; 109 bool kbgrabbed : 1;
111 bool notbusysent : 1; 110 bool notbusysent : 1;
112 bool preloaded : 1; 111 bool preloaded : 1;
113 bool forceshow : 1; 112 bool forceshow : 1;
114 bool nomaximize : 1; 113 bool nomaximize : 1;
115 bool keep_running : 1; 114 bool keep_running : 1;
116 115
117 QString appName; 116 QString appName;
118 struct QCopRec 117 struct QCopRec
119 { 118 {
120 QCopRec( const QCString &ch, const QCString &msg, 119 QCopRec( const QCString &ch, const QCString &msg,
121 const QByteArray &d ) : 120 const QByteArray &d ) :
122 channel( ch ), message( msg ), data( d ) 121 channel( ch ), message( msg ), data( d )
@@ -746,26 +745,24 @@ bool QPEApplication::qwsEventFilter( QWSEvent * e )
746 } 745 }
747 if ( type() == GuiServer ) { 746 if ( type() == GuiServer ) {
748 switch ( e->type ) { 747 switch ( e->type ) {
749 case QWSEvent::Mouse: 748 case QWSEvent::Mouse:
750 if ( e->asMouse() ->simpleData.state && !QWidget::find( e->window() ) ) 749 if ( e->asMouse() ->simpleData.state && !QWidget::find( e->window() ) )
751 emit clientMoused(); 750 emit clientMoused();
752 break; 751 break;
753 default: 752 default:
754 break; 753 break;
755 } 754 }
756 } 755 }
757 if ( e->type == QWSEvent::Key ) { 756 if ( e->type == QWSEvent::Key ) {
758 if ( d->kbgrabber == 1 )
759 return TRUE;
760 QWSKeyEvent *ke = ( QWSKeyEvent * ) e; 757 QWSKeyEvent *ke = ( QWSKeyEvent * ) e;
761 if ( ke->simpleData.keycode == Qt::Key_F33 ) { 758 if ( ke->simpleData.keycode == Qt::Key_F33 ) {
762 // Use special "OK" key to press "OK" on top level widgets 759 // Use special "OK" key to press "OK" on top level widgets
763 QWidget * active = activeWindow(); 760 QWidget * active = activeWindow();
764 QWidget *popup = 0; 761 QWidget *popup = 0;
765 if ( active && active->isPopup() ) { 762 if ( active && active->isPopup() ) {
766 popup = active; 763 popup = active;
767 active = active->parentWidget(); 764 active = active->parentWidget();
768 } 765 }
769 if ( active && ( int ) active->winId() == ke->simpleData.window && 766 if ( active && ( int ) active->winId() == ke->simpleData.window &&
770 !active->testWFlags( WStyle_Customize | WType_Popup | WType_Desktop ) ) { 767 !active->testWFlags( WStyle_Customize | WType_Popup | WType_Desktop ) ) {
771 if ( ke->simpleData.is_press ) { 768 if ( ke->simpleData.is_press ) {
@@ -800,57 +797,72 @@ bool QPEApplication::qwsEventFilter( QWSEvent * e )
800 ( int ) active->winId() == ke->simpleData.window && 797 ( int ) active->winId() == ke->simpleData.window &&
801 !active->testWFlags( WStyle_Dialog | WStyle_Customize | WType_Popup | WType_Desktop ) ) { 798 !active->testWFlags( WStyle_Dialog | WStyle_Customize | WType_Popup | WType_Desktop ) ) {
802 if ( active->inherits( "QDialog" ) ) { 799 if ( active->inherits( "QDialog" ) ) {
803 HackDialog * d = ( HackDialog * ) active; 800 HackDialog * d = ( HackDialog * ) active;
804 d->rejectIt(); 801 d->rejectIt();
805 return TRUE; 802 return TRUE;
806 } 803 }
807 else if ( strcmp( argv() [ 0 ], "embeddedkonsole" ) != 0 ) { 804 else if ( strcmp( argv() [ 0 ], "embeddedkonsole" ) != 0 ) {
808 active->close(); 805 active->close();
809 } 806 }
810 } 807 }
811 } 808 }
812 809 else if ( ke->simpleData.keycode >= Qt::Key_F1 && ke->simpleData.keycode <= Qt::Key_F29 ) {
813#if QT_VERSION < 231 810 // this should be if ( ODevice::inst ( )-> buttonForKeycode ( ... ))
814 // Filter out the F4/Launcher key from apps 811 // but we cannot access libopie function within libqpe :(
815 // ### The launcher key may not always be F4 on all devices 812
816 if ( ( ( QWSKeyEvent * ) e ) ->simpleData.keycode == Qt::Key_F4 ) 813 QWidget * active = activeWindow ( );
817 return TRUE; 814 if ( active && ((int) active-> winId ( ) == ke-> simpleData.window )) {
818#endif 815 if ( d-> kbgrabbed ) { // we grabbed the keyboard
819 816 QChar ch ( ke-> simpleData.unicode );
817 QKeyEvent qke ( ke-> simpleData. is_press ? QEvent::KeyPress : QEvent::KeyRelease,
818 ke-> simpleData.keycode,
819 ch. latin1 ( ),
820 ke-> simpleData.modifiers,
821 QString ( ch ),
822 ke-> simpleData.is_auto_repeat, 1 );
823
824 QObject *which = QWidget::keyboardGrabber ( );
825 if ( !which )
826 which = QApplication::focusWidget ( );
827 if ( !which )
828 which = QApplication::activeWindow ( );
829 if ( !which )
830 which = qApp;
831
832 QApplication::sendEvent ( which, &qke );
833 }
834 else { // we didn't grab the keyboard, so send the event to the launcher
835 QCopEnvelope e ( "QPE/Launcher", "deviceButton(int,int,int)" );
836 e << int( ke-> simpleData.keycode ) << int( ke-> simpleData. is_press ) << int( ke-> simpleData.is_auto_repeat );
837 }
838 }
839 return true;
840 }
820 } 841 }
821 if ( e->type == QWSEvent::Focus ) { 842 if ( e->type == QWSEvent::Focus ) {
822 QWSFocusEvent * fe = ( QWSFocusEvent* ) e; 843 QWSFocusEvent * fe = ( QWSFocusEvent* ) e;
823 QWidget* nfw = QWidget::find( e->window() );
824 if ( !fe->simpleData.get_focus ) { 844 if ( !fe->simpleData.get_focus ) {
825 QWidget * active = activeWindow(); 845 QWidget * active = activeWindow();
826 while ( active && active->isPopup() ) { 846 while ( active && active->isPopup() ) {
827 active->close(); 847 active->close();
828 active = activeWindow(); 848 active = activeWindow();
829 } 849 }
830 if ( !nfw && d->kbgrabber == 2 ) {
831 ungrabKeyboard();
832 d->kbregrab = TRUE; // want kb back when we're active
833 }
834 } 850 }
835 else { 851 else {
836 // make sure our modal widget is ALWAYS on top 852 // make sure our modal widget is ALWAYS on top
837 QWidget *topm = activeModalWidget(); 853 QWidget *topm = activeModalWidget();
838 if ( topm ) { 854 if ( topm ) {
839 topm->raise(); 855 topm->raise();
840 } 856 }
841 if ( d->kbregrab ) {
842 grabKeyboard();
843 d->kbregrab = FALSE;
844 }
845 } 857 }
846 if ( fe->simpleData.get_focus && inputMethodDict ) { 858 if ( fe->simpleData.get_focus && inputMethodDict ) {
847 InputMethodHint m = inputMethodHint( QWidget::find( e->window() ) ); 859 InputMethodHint m = inputMethodHint( QWidget::find( e->window() ) );
848 if ( m == AlwaysOff ) 860 if ( m == AlwaysOff )
849 Global::hideInputMethod(); 861 Global::hideInputMethod();
850 if ( m == AlwaysOn ) 862 if ( m == AlwaysOn )
851 Global::showInputMethod(); 863 Global::showInputMethod();
852 } 864 }
853 } 865 }
854 return QApplication::qwsEventFilter( e ); 866 return QApplication::qwsEventFilter( e );
855} 867}
856#endif 868#endif
@@ -1024,59 +1036,61 @@ void QPEApplication::applyStyle()
1024 // revert to global blocking policy ... 1036 // revert to global blocking policy ...
1025 Opie::force_appearance = config. readBoolEntry ( "ForceStyle", false ) ? Opie::Force_All : Opie::Force_None; 1037 Opie::force_appearance = config. readBoolEntry ( "ForceStyle", false ) ? Opie::Force_All : Opie::Force_None;
1026 Opie::force_appearance &= ~nostyle; 1038 Opie::force_appearance &= ~nostyle;
1027} 1039}
1028 1040
1029void QPEApplication::systemMessage( const QCString& msg, const QByteArray& data ) 1041void QPEApplication::systemMessage( const QCString& msg, const QByteArray& data )
1030{ 1042{
1031#ifdef Q_WS_QWS 1043#ifdef Q_WS_QWS
1032 QDataStream stream( data, IO_ReadOnly ); 1044 QDataStream stream( data, IO_ReadOnly );
1033 if ( msg == "applyStyle()" ) { 1045 if ( msg == "applyStyle()" ) {
1034 applyStyle(); 1046 applyStyle();
1035 } 1047 }
1048 else if ( msg == "toggleApplicationMenu()" ) {
1049 QWidget *active = activeWindow ( );
1050
1051 if ( active ) {
1052 QPEMenuToolFocusManager *man = QPEMenuToolFocusManager::manager ( );
1053 bool oldactive = man-> isActive ( );
1054
1055 man-> setActive( !man-> isActive() );
1056
1057 if ( !oldactive && !man-> isActive ( )) { // no menubar to toggle -> try O-Menu
1058 QCopEnvelope e ( "QPE/TaskBar", "toggleStartMenu()" );
1059 }
1060 }
1061 }
1036 else if ( msg == "setDefaultRotation(int)" ) { 1062 else if ( msg == "setDefaultRotation(int)" ) {
1037 if ( type() == GuiServer ) { 1063 if ( type() == GuiServer ) {
1038 int r; 1064 int r;
1039 stream >> r; 1065 stream >> r;
1040 setDefaultRotation( r ); 1066 setDefaultRotation( r );
1041 } 1067 }
1042 } 1068 }
1043 else if ( msg == "shutdown()" ) { 1069 else if ( msg == "shutdown()" ) {
1044 if ( type() == GuiServer ) 1070 if ( type() == GuiServer )
1045 shutdown(); 1071 shutdown();
1046 } 1072 }
1047 else if ( msg == "quit()" ) { 1073 else if ( msg == "quit()" ) {
1048 if ( type() != GuiServer ) 1074 if ( type() != GuiServer )
1049 tryQuit(); 1075 tryQuit();
1050 } 1076 }
1051 else if ( msg == "forceQuit()" ) { 1077 else if ( msg == "forceQuit()" ) {
1052 if ( type() != GuiServer ) 1078 if ( type() != GuiServer )
1053 quit(); 1079 quit();
1054 } 1080 }
1055 else if ( msg == "restart()" ) { 1081 else if ( msg == "restart()" ) {
1056 if ( type() == GuiServer ) 1082 if ( type() == GuiServer )
1057 restart(); 1083 restart();
1058 } 1084 }
1059 else if ( msg == "grabKeyboard(QString)" ) {
1060 QString who;
1061 stream >> who;
1062 if ( who.isEmpty() )
1063 d->kbgrabber = 0;
1064 else if ( who != d->appName )
1065 d->kbgrabber = 1;
1066 else
1067 d->kbgrabber = 2;
1068
1069 d-> kbgrabber_appname = who;
1070 }
1071 else if ( msg == "language(QString)" ) { 1085 else if ( msg == "language(QString)" ) {
1072 if ( type() == GuiServer ) { 1086 if ( type() == GuiServer ) {
1073 QString l; 1087 QString l;
1074 stream >> l; 1088 stream >> l;
1075 QString cl = getenv( "LANG" ); 1089 QString cl = getenv( "LANG" );
1076 if ( cl != l ) { 1090 if ( cl != l ) {
1077 if ( l.isNull() ) 1091 if ( l.isNull() )
1078 unsetenv( "LANG" ); 1092 unsetenv( "LANG" );
1079 else 1093 else
1080 setenv( "LANG", l.latin1(), 1 ); 1094 setenv( "LANG", l.latin1(), 1 );
1081 restart(); 1095 restart();
1082 } 1096 }
@@ -1615,76 +1629,49 @@ void QPEApplication::removeSenderFromStylusDict()
1615{ 1629{
1616 stylusDict->remove 1630 stylusDict->remove
1617 ( ( void* ) sender() ); 1631 ( ( void* ) sender() );
1618 if ( d->presswidget == sender() ) 1632 if ( d->presswidget == sender() )
1619 d->presswidget = 0; 1633 d->presswidget = 0;
1620} 1634}
1621 1635
1622/*! 1636/*!
1623 \internal 1637 \internal
1624*/ 1638*/
1625bool QPEApplication::keyboardGrabbed() const 1639bool QPEApplication::keyboardGrabbed() const
1626{ 1640{
1627 return d->kbgrabber; 1641 return d->kbgrabbed;
1628}
1629
1630/*!
1631 \internal
1632*/
1633QString QPEApplication::keyboardGrabbedBy() const
1634{
1635 return d->kbgrabber_appname;
1636} 1642}
1637 1643
1638 1644
1639/*! 1645/*!
1640 Reverses the effect of grabKeyboard(). This is called automatically 1646 Reverses the effect of grabKeyboard(). This is called automatically
1641 on program exit. 1647 on program exit.
1642*/ 1648*/
1643void QPEApplication::ungrabKeyboard() 1649void QPEApplication::ungrabKeyboard()
1644{ 1650{
1645 QPEApplicationData * d = ( ( QPEApplication* ) qApp ) ->d; 1651 ((QPEApplication *) qApp )-> d-> kbgrabbed = false;
1646 if ( d->kbgrabber == 2 ) {
1647#ifndef QT_NO_COP
1648 QCopEnvelope e( "QPE/System", "grabKeyboard(QString)" );
1649 e << QString::null;
1650#endif
1651
1652 d->kbregrab = FALSE;
1653 d->kbgrabber = 0;
1654 }
1655} 1652}
1656 1653
1657/*! 1654/*!
1658 Grabs the physical keyboard keys, e.g. the application's launching 1655 Grabs the physical keyboard keys, e.g. the application's launching
1659 keys. Instead of launching applications when these keys are pressed 1656 keys. Instead of launching applications when these keys are pressed
1660 the signals emitted are sent to this application instead. Some games 1657 the signals emitted are sent to this application instead. Some games
1661 programs take over the launch keys in this way to make interaction 1658 programs take over the launch keys in this way to make interaction
1662 easier. 1659 easier.
1663 1660
1664 \sa ungrabKeyboard() 1661 \sa ungrabKeyboard()
1665*/ 1662*/
1666void QPEApplication::grabKeyboard() 1663void QPEApplication::grabKeyboard()
1667{ 1664{
1668 QPEApplicationData * d = ( ( QPEApplication* ) qApp ) ->d; 1665 ((QPEApplication *) qApp )-> d-> kbgrabbed = true;
1669 if ( qApp->type() == QApplication::GuiServer )
1670 d->kbgrabber = 0;
1671 else {
1672#ifndef QT_NO_COP
1673 QCopEnvelope e( "QPE/System", "grabKeyboard(QString)" );
1674 e << d->appName;
1675#endif
1676
1677 d->kbgrabber = 2; // me
1678 }
1679} 1666}
1680 1667
1681/*! 1668/*!
1682 \reimp 1669 \reimp
1683*/ 1670*/
1684int QPEApplication::exec() 1671int QPEApplication::exec()
1685{ 1672{
1686#ifndef QT_NO_COP 1673#ifndef QT_NO_COP
1687 d->sendQCopQ(); 1674 d->sendQCopQ();
1688#endif 1675#endif
1689 1676
1690 if ( d->keep_running ) 1677 if ( d->keep_running )
diff --git a/library/qpeapplication.h b/library/qpeapplication.h
index f712077..7d956a3 100644
--- a/library/qpeapplication.h
+++ b/library/qpeapplication.h
@@ -74,25 +74,24 @@ public:
74 static void setInputMethodHint( QWidget *, InputMethodHint ); 74 static void setInputMethodHint( QWidget *, InputMethodHint );
75 static InputMethodHint inputMethodHint( QWidget * ); 75 static InputMethodHint inputMethodHint( QWidget * );
76 76
77 void showMainWidget( QWidget*, bool nomax=FALSE ); 77 void showMainWidget( QWidget*, bool nomax=FALSE );
78 void showMainDocumentWidget( QWidget*, bool nomax=FALSE ); 78 void showMainDocumentWidget( QWidget*, bool nomax=FALSE );
79 static void showDialog( QDialog*, bool nomax=FALSE ); 79 static void showDialog( QDialog*, bool nomax=FALSE );
80 static int execDialog( QDialog*, bool nomax=FALSE ); 80 static int execDialog( QDialog*, bool nomax=FALSE );
81 81
82 static void setKeepRunning(); 82 static void setKeepRunning();
83 bool keepRunning() const; 83 bool keepRunning() const;
84 84
85 bool keyboardGrabbed() const; 85 bool keyboardGrabbed() const;
86 QString keyboardGrabbedBy ( ) const;
87 86
88 int exec(); 87 int exec();
89 88
90signals: 89signals:
91 void clientMoused(); 90 void clientMoused();
92 void timeChanged(); 91 void timeChanged();
93 void clockChanged( bool pm ); 92 void clockChanged( bool pm );
94 void micChanged( bool muted ); 93 void micChanged( bool muted );
95 void volumeChanged( bool muted ); 94 void volumeChanged( bool muted );
96 void appMessage( const QCString& msg, const QByteArray& data); 95 void appMessage( const QCString& msg, const QByteArray& data);
97 void weekChanged( bool startOnMonday ); 96 void weekChanged( bool startOnMonday );
98 void dateFormatChanged( DateFormat ); 97 void dateFormatChanged( DateFormat );
diff --git a/library/qpemenubar.cpp b/library/qpemenubar.cpp
index 4aa0bf3..3e5bad5 100644
--- a/library/qpemenubar.cpp
+++ b/library/qpemenubar.cpp
@@ -216,28 +216,24 @@ bool QPEMenuToolFocusManager::eventFilter( QObject *object, QEvent *event )
216 mb->goodbye(); 216 mb->goodbye();
217 moveFocus( FALSE ); 217 moveFocus( FALSE );
218 return TRUE; 218 return TRUE;
219 } 219 }
220 QMenuItem *mi = mb->findItem( mb->idAt(i) ); 220 QMenuItem *mi = mb->findItem( mb->idAt(i) );
221 if ( mi->isEnabled() && !mi->isSeparator() ) { 221 if ( mi->isEnabled() && !mi->isSeparator() ) {
222 break; 222 break;
223 } 223 }
224 } 224 }
225 } 225 }
226 } 226 }
227 } 227 }
228 if ( ke->key() == Key_F11 ) {
229 setActive( !isActive() );
230 return TRUE;
231 }
232 } else if ( event->type() == QEvent::KeyRelease ) { 228 } else if ( event->type() == QEvent::KeyRelease ) {
233 QKeyEvent *ke = (QKeyEvent *)event; 229 QKeyEvent *ke = (QKeyEvent *)event;
234 if ( isActive() ) { 230 if ( isActive() ) {
235 if ( object->inherits( "QButton" ) ) { 231 if ( object->inherits( "QButton" ) ) {
236 // Deactivate when a button is selected 232 // Deactivate when a button is selected
237 if ( ke->key() == Key_Space ) 233 if ( ke->key() == Key_Space )
238 QTimer::singleShot( 0, this, SLOT(deactivate()) ); 234 QTimer::singleShot( 0, this, SLOT(deactivate()) );
239 } 235 }
240 } 236 }
241 } else if ( event->type() == QEvent::FocusIn ) { 237 } else if ( event->type() == QEvent::FocusIn ) {
242 if ( isActive() ) { 238 if ( isActive() ) {
243 // A non-menu/tool widget has been selected - we're deactivated 239 // A non-menu/tool widget has been selected - we're deactivated