implemented preliminary WM_CONTEXT_HELP protocol. In combination with tomorrow's

Qt snapshot, you will see lovely question marks in the titlebar of dialogs that
invoke What's This help.

svn path=/trunk/kdebase/kwin/; revision=35618
This commit is contained in:
Matthias Ettrich 1999-12-01 22:09:32 +00:00
parent bf1a6485b9
commit 64acd7375d
7 changed files with 123 additions and 23 deletions

View file

@ -9,48 +9,51 @@ Atoms::Atoms()
char* names[max];
Atom atoms_return[max];
int n = 0;
atoms[n] = &wm_protocols;
names[n++] = "WM_PROTOCOLS";
atoms[n] = &wm_delete_window;
names[n++] = "WM_DELETE_WINDOW";
atoms[n] = &wm_take_focus;
names[n++] = "WM_TAKE_FOCUS";
atoms[n] = &wm_change_state;
names[n++] = "WM_CHANGE_STATE";
// compatibility
atoms[n] = &kwm_win_icon;
names[n++] = "KWM_WIN_ICON";
// compatibility
atoms[n] = &kwm_running;
names[n++] = "KWM_RUNNING";
atoms[n] = &net_number_of_desktops;
names[n++] = "_NET_NUMBER_OF_DESKTOPS";
atoms[n] = &net_current_desktop;
names[n++] = "_NET_CURRENT_DESKTOP";
atoms[n] = &net_active_window;
names[n++] = "_NET_ACTIVE_WINDOW";
atoms[n] = &net_wm_context_help;
names[n++] = "_NET_WM_CONTEXT_HELP";
atoms[n] = &net_client_list;
names[n++] = "_NET_CLIENT_LIST";
atoms[n] = &net_client_list_stacking;
names[n++] = "_NET_CLIENT_LIST_STACKING";
atoms[n] = &net_kde_docking_windows;
names[n++] = "_NET_KDE_DOCKING_WINDOWS";
XInternAtoms( qt_xdisplay(), names, n, FALSE, atoms_return );
for (int i = 0; i < n; i++ )
*atoms[i] = atoms_return[i];
}

View file

@ -18,7 +18,7 @@ public:
Atom net_active_window;
Atom net_client_list;
Atom net_client_list_stacking;
Atom net_wm_context_help;
Atom net_kde_docking_windows;
};

View file

@ -6,6 +6,7 @@
#include <qwmatrix.h>
#include <qlayout.h>
#include <qpainter.h>
#include <qwhatsthis.h>
#include "workspace.h"
#include "client.h"
#include "atoms.h"
@ -1455,6 +1456,7 @@ void Client::getWindowProtocols(){
Pdeletewindow = 0;
Ptakefocus = 0;
Pcontexthelp = 0;
if (XGetWMProtocols(qt_xdisplay(), win, &p, &n)){
for (i = 0; i < n; i++)
@ -1462,6 +1464,8 @@ void Client::getWindowProtocols(){
Pdeletewindow = 1;
else if (p[i] == atoms->wm_take_focus)
Ptakefocus = 1;
else if (p[i] == atoms->net_wm_context_help)
Pcontexthelp = 1;
if (n>0)
XFree(p);
}
@ -1509,6 +1513,33 @@ Client* Client::mainClient()
}
/*!
Returns whether the window provides context help or not. If it does,
you should show a help menu item or a help button lie '?' and call
contextHelp() if this is invoked.
\sa contextHelp()
*/
bool Client::providesContextHelp() const
{
return Pcontexthelp;
}
/*!
Invokes context help on the window. Only works if the window
actually provides context help.
\sa providesContextHelp()
*/
void Client::contextHelp()
{
if ( Pcontexthelp ) {
sendClientMessage(win, atoms->wm_protocols, atoms->net_wm_context_help);
QWhatsThis::enterWhatsThisMode();
}
}
bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPos)
{

View file

@ -129,6 +129,8 @@ public:
virtual bool wantsTabFocus() const { return TRUE;} //### just for now
bool providesContextHelp() const;
bool performMouseCommand( Options::MouseCommand, QPoint globalPos );
@ -138,6 +140,7 @@ public slots:
void maximize( MaximizeMode );
void maximize();
void toggleSticky();
void contextHelp();
protected:
void paintEvent( QPaintEvent * );
@ -215,6 +218,7 @@ private:
void getWindowProtocols();
uint Pdeletewindow :1; // does the window understand the DeleteWindow protocol?
uint Ptakefocus :1;// does the window understand the TakeFocus protocol?
uint Pcontexthelp : 1; // does the window understand the ContextHelp protocol?
uint input :1; // does the window want input in its wm_hints
uint mapped :1; // keeps track of our visiblity within the asynchronous event flow
QPixmap icon_pix;

View file

@ -28,6 +28,34 @@ static QPixmap* dis_pinup_pix = 0;
static QPixmap* dis_pindown_pix = 0;
static QPixmap* dis_menu_pix = 0;
static QPixmap* question_mark_pix = 0;
/* XPM */
static const char *question_mark[] = {
/* width height ncolors chars_per_pixel */
"16 16 2 1",
/* colors */
" c #000000",
"X c None",
/* pixels */
"XXXXXXXXXXXXXXXX",
"XXXXX XXX",
"XXXX XXXXX XX",
"XXX XXXXXXX XX",
"XXX XXXXXXX XX",
"XXXXXXXXXXX XX",
"XXXXXXXXXX XXX",
"XXXXXXXXX XXXX",
"XXXXXXXX XXXXXX",
"XXXXXXX XXXXXXX",
"XXXXXXX XXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXXXXXXXXXXXX",
"XXXXXXX XXXXXXX",
"XXXXXXX XXXXXXX",
"XXXXXXXXXXXXXXXX"
};
static bool pixmaps_created = FALSE;
@ -183,6 +211,8 @@ static void create_pixmaps()
bitmap = QBitmap(16, 16, pindown_mask_bits, true);
pindown_pix->setMask(bitmap); dis_pindown_pix->setMask(bitmap);
question_mark_pix = new QPixmap(question_mark );
}
@ -220,11 +250,22 @@ StdClient::StdClient( Workspace *ws, WId w, QWidget *parent, const char *name )
QSizePolicy::Minimum );
hb->addItem( titlebar );
button[6] = 0;
if ( providesContextHelp() ) {
button[6] = new QToolButton( this );
hb->addWidget( button[6] ); // help button
hb->addItem( new QSpacerItem( 5, 0, QSizePolicy::Fixed, QSizePolicy::Expanding ) );
button[6]->setIconSet( *question_mark_pix );
connect( button[6], SIGNAL( clicked() ), this, ( SLOT( contextHelp() ) ) );
}
hb->addWidget( button[3] );
hb->addWidget( button[4] );
hb->addWidget( button[5] );
for ( int i = 0; i < 6; i++) {
for ( int i = 0; i < 7; i++) {
if ( !button[i] )
continue;
button[i]->setBackgroundMode( PaletteBackground );
button[i]->setMouseTracking( TRUE );
button[i]->setFixedSize( 20, 20 );
@ -250,6 +291,10 @@ StdClient::StdClient( Workspace *ws, WId w, QWidget *parent, const char *name )
connect( button[4], SIGNAL( clicked(int) ), this, ( SLOT( maxButtonClicked(int) ) ) );
button[5]->setIconSet(isActive() ? *close_pix : *dis_close_pix);
connect( button[5], SIGNAL( clicked() ), this, ( SLOT( closeWindow() ) ) );
if ( button[6] ) {
}
if ( isTransient() ) {
// lighter decoration for transient windows

View file

@ -28,14 +28,14 @@ private slots:
void maxButtonClicked( int );
private:
QToolButton* button[6];
QToolButton* button[7];
QSpacerItem* titlebar;
};
/*
Like QToolButton, but provides a clicked(int) signals that
Like QToolButton, but provides a clicked(int) signals that
has the last pressed mouse button as argument
*/
class ThreeButtonButton: public QToolButton
@ -47,12 +47,12 @@ public:
{
connect( this, SIGNAL( clicked() ), this, SLOT( handleClicked() ) );
}
~ThreeButtonButton ()
~ThreeButtonButton ()
{}
signals:
void clicked( int );
protected:
void mousePressEvent( QMouseEvent* e )
{
@ -60,7 +60,7 @@ protected:
QMouseEvent me ( e->type(), e->pos(), e->globalPos(), LeftButton, e->state() );
QToolButton::mousePressEvent( &me );
}
void mouseReleaseEvent( QMouseEvent* e )
{
QMouseEvent me ( e->type(), e->pos(), e->globalPos(), LeftButton, e->state() );
@ -72,10 +72,10 @@ private slots:
{
emit clicked( last_button );
}
private:
int last_button;
};

View file

@ -2,6 +2,7 @@
#include <kglobal.h>
#include <kglobalaccel.h>
#include <klocale.h>
#include <qwhatsthis.h>
#include <kwin.h>
#include "workspace.h"
@ -305,6 +306,22 @@ bool Workspace::workspaceEvent( XEvent * e )
return result;
}
break;
case EnterNotify:
if ( !QWhatsThis::inWhatsThisMode() )
break;
{
QWidget* w = QWidget::find( e->xcrossing.window );
if ( w && w->inherits("WindowWrapper" ) )
QWhatsThis::leaveWhatsThisMode();
}
break;
case LeaveNotify:
if ( !QWhatsThis::inWhatsThisMode() )
break;
c = findClientWidthId( e->xcrossing.window );
if ( c && e->xcrossing.detail != NotifyInferior )
QWhatsThis::leaveWhatsThisMode();
break;
case ConfigureRequest:
c = findClient( e->xconfigurerequest.window );
if ( c )