Merged in remaining kdebase bugfixes from the Chakra project

git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1172677 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
v3.5.13-sru
tpearson 14 years ago
parent eaa51fec10
commit 9cc1e2c1aa

@ -153,10 +153,10 @@ KMemoryWidget::KMemoryWidget(TQWidget * parent, const char *name)
break;
case SWAP_MEM:
vbox->addSpacing(SPACING);
title = i18n("Total swap memory:");
title = i18n("Total swap space:");
break;
case FREESWAP_MEM:
title = i18n("Free swap memory:");
title = i18n("Free swap space:");
break;
default:
title = "";
@ -197,27 +197,26 @@ KMemoryWidget::KMemoryWidget(TQWidget * parent, const char *name)
case MEM_RAM_AND_HDD:
title = i18n("Total Memory");
hint = i18n("This graph gives you an overview of the "
"<b>total sum of physical and virtual memory</b> "
"in your system.");
"usage of <b>all available memory</b> (the sum of "
"physical memory and swap space) in your system.");
break;
case MEM_RAM:
title = i18n("Physical Memory");
hint = i18n("This graph gives you an overview of "
"the <b>usage of physical memory</b> in your system."
"the usage of <b>physical memory</b> in your system."
"<p>Most operating systems (including Linux) "
"will use as much of the available physical "
"memory as possible as disk cache, "
"to speed up the system performance. "
"<p>This means that if you have a small amount "
"memory as possible for a disk cache, "
"to speed up the reading and writing of files. "
"<p>This means that if you are seeing a small amount "
"of <b>Free Physical Memory</b> and a large amount of "
"<b>Disk Cache Memory</b>, your system is well "
"configured.");
"<b>Disk Cache</b>, your system is well configured.");
break;
case MEM_HDD:
title = i18n("Swap Space");
hint = i18n("The swap space is the <b>virtual memory</b> "
hint = i18n("Swap space is the <b>virtual memory</b> "
"available to the system. "
"<p>It will be used on demand and is provided "
"<p>It will be used when needed, and is provided "
"through one or more swap partitions and/or swap files.");
break;
default:
@ -312,10 +311,10 @@ bool KMemoryWidget::Display_Graph(int widgetindex,
last_used = *used;
#ifdef HAVE_LONG_LONG
percent = (((long long)last_used) * 100) / total;
percent = (((long long)last_used) * 1000 + 5) / (total * 10);
#else
/* prevent integer overflow with usage of double type */
percent = (int) ((((double)last_used) * 100) / total);
percent = (int) ((((double)last_used) * 1000 + 5) / (total * 10));
#endif
if (count)
@ -400,11 +399,11 @@ void KMemoryWidget::update_Values()
if (!ram_colors_initialized) {
ram_colors_initialized = true;
ram_text[0] = i18n("Application Data");
ram_colors[0] = COLOR_USED_MEMORY; /* used+shared */
ram_colors[0] = COLOR_USED_DATA; /* used+shared */
ram_text[1] = i18n("Disk Buffers");
ram_colors[1] = TQColor(24,131,5); /* buffer */
ram_colors[1] = COLOR_USED_BUFFER; /* buffers */
ram_text[2] = i18n("Disk Cache");
ram_colors[2] = TQColor(33,180,7); /* cached */
ram_colors[2] = COLOR_USED_CACHE; /* cached */
ram_text[3] = i18n("Free Physical Memory");
ram_colors[3] = COLOR_FREE_MEMORY; /* free */
}
@ -425,24 +424,20 @@ void KMemoryWidget::update_Values()
used, swap_colors, swap_text);
/* RAM + SWAP usage: */
if (Memory_Info[SWAP_MEM] == NO_MEMORY_INFO ||
Memory_Info[FREESWAP_MEM] == NO_MEMORY_INFO)
Memory_Info[SWAP_MEM] = Memory_Info[FREESWAP_MEM] = 0;
used[1] = Memory_Info[SWAP_MEM] - Memory_Info[FREESWAP_MEM];
used[2] = Memory_Info[FREE_MEM] + Memory_Info[FREESWAP_MEM];
used[0] = (Memory_Info[TOTAL_MEM]+Memory_Info[SWAP_MEM])-used[1]-used[2];
/* used[0] already contains the amount of used swap */
used[2] = Memory_Info[FREE_MEM] + ZERO_IF_NO_INFO(Memory_Info[FREESWAP_MEM]);
used[1] = Memory_Info[TOTAL_MEM] - Memory_Info[FREE_MEM];
if (!all_colors_initialized) {
all_colors_initialized = true;
all_text[0] = i18n("Used Physical Memory");
all_colors[0] = COLOR_USED_MEMORY; /* used ram */
all_text[1] = i18n("Used Swap");
all_colors[1] = COLOR_USED_SWAP; /* used swap */
all_text[2] = i18n("Total Free Memory");
all_text[0] = i18n("Used Memory (swap part)");
all_colors[0] = COLOR_USED_SWAP; /* used swap */
all_text[1] = i18n("Used Memory (physical part)");
all_colors[1] = COLOR_USED_RAM; /* used ram */
all_text[2] = i18n("Free Memory (total)");
all_colors[2] = COLOR_FREE_MEMORY; /* free ram+swap*/
}
Display_Graph(MEM_RAM_AND_HDD, 3,
ok1 ? Memory_Info[TOTAL_MEM] + Memory_Info[SWAP_MEM]
ok1 ? Memory_Info[TOTAL_MEM] + ZERO_IF_NO_INFO(Memory_Info[SWAP_MEM])
: NO_MEMORY_INFO,
used, all_colors, all_text);
}

@ -20,8 +20,11 @@ typedef unsigned long long t_memsize;
typedef unsigned long t_memsize;
#endif
#define COLOR_USED_MEMORY TQColor(255,0,0)
#define COLOR_USED_SWAP TQColor(255,134,64)
#define COLOR_USED_SWAP TQColor(255,0,0)
#define COLOR_USED_DATA TQColor(255,180,88)
#define COLOR_USED_BUFFER TQColor(184,200,0)
#define COLOR_USED_CACHE TQColor(156,192,0)
#define COLOR_USED_RAM TQColor(220,200,88)
#define COLOR_FREE_MEMORY TQColor(127,255,212)
class KMemoryWidget:public KCModule {

@ -131,7 +131,10 @@ KRootWm::KRootWm(KDesktop* _desktop) : TQObject(_desktop)
if (kapp->authorize("run_command"))
{
new KAction(i18n("Run Command..."), "run", 0, m_pDesktop, TQT_SLOT( slotExecuteCommand() ), m_actionCollection, "exec" );
new KAction(i18n("Konsole ..." ), "terminal", CTRL+Key_T, this, TQT_SLOT( slotOpenTerminal() ),
m_actionCollection, "open_terminal" );
}
if (!KGlobal::config()->isImmutable())
{
new KAction(i18n("Configure Desktop..."), "configure", 0, this, TQT_SLOT( slotConfigureDesktop() ),
@ -322,6 +325,12 @@ void KRootWm::buildMenus()
file->insertSeparator();
}
action = m_actionCollection->action("open_terminal");
if (action)
{
action->plug( file );
}
action = m_actionCollection->action("lock");
if (action)
action->plug( file );
@ -396,6 +405,10 @@ void KRootWm::buildMenus()
needSeparator = true;
}
action = m_actionCollection->action("open_terminal");
if (action)
action->plug( desktopMenu );
if (needSeparator)
{
desktopMenu->insertSeparator();
@ -723,6 +736,22 @@ TQStringList KRootWm::configModules() {
return args;
}
void KRootWm::slotOpenTerminal()
{
// kdDebug() << "KRootWm::slotOpenTerminal" << endl;
KProcess* p = new KProcess;
Q_CHECK_PTR(p);
KConfigGroupSaver gs(KGlobal::config(), "General");
TQString terminal = KGlobal::config()->readPathEntry("TerminalApplication", "konsole");
*p << terminal;
p->start(KProcess::DontCare);
delete p;
}
void KRootWm::slotConfigureDesktop() {
if (!m_configDialog)
{

@ -119,6 +119,7 @@ public slots:
void slotPopulateSessions();
void slotSessionActivated( int );
void slotNewSession();
void slotOpenTerminal();
void slotLockNNewSession();
private:

@ -8,6 +8,7 @@
<Action name="newsubmenu" />
<Separator/>
<Action name="file_save"/>
<Action name="file_save_and_quit"/>
<Separator/>
<Action name="file_quit"/>
</Menu>

@ -67,6 +67,8 @@ void KMenuEdit::setupActions()
if (!m_controlCenter)
(void)new KAction(i18n("New S&eparator"), "menu_new_sep", 0, actionCollection(), "newsep");
(void)new KAction(i18n("Save && Quit"), "filesave_and_close", 0, this, TQT_SLOT( slotSave_and_close()), actionCollection(), "file_save_and_quit");
m_actionDelete = 0;
KStdAction::save(this, TQT_SLOT( slotSave() ), actionCollection());
@ -141,6 +143,12 @@ void KMenuEdit::slotSave()
m_tree->save();
}
void KMenuEdit::slotSave_and_close()
{
if (m_tree->save())
close();
}
bool KMenuEdit::queryClose()
{
if (!m_tree->dirty()) return true;

@ -46,6 +46,7 @@ protected:
protected slots:
void slotSave();
void slotSave_and_close();
void slotChangeView();
void slotConfigureToolbars();
protected:

@ -9,6 +9,7 @@
<Action name="newsep" />
<Separator/>
<Action name="file_save"/>
<Action name="file_save_and_quit"/>
<Separator/>
<Action name="file_quit"/>
</Menu>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -395,6 +395,11 @@ void TEmulation::copySelection() {
TQApplication::clipboard()->setText(t);
}
TQString TEmulation::getSelection() {
if (connected) return scr->getSelText(true);
return TQString::null;
}
void TEmulation::streamHistory(TQTextStream* stream) {
scr->streamHistory(stream);
}

@ -59,6 +59,7 @@ public slots: // signals incoming from TEWidget
virtual void clearSelection();
virtual void copySelection();
virtual TQString getSelection();
virtual void onSelectionBegin(const int x, const int y, const bool columnmode);
virtual void onSelectionExtend(const int x, const int y);
virtual void setSelection(const bool preserve_line_breaks);

@ -114,6 +114,7 @@ Time to start a requirement list.
#include <knotifydialog.h>
#include <kprinter.h>
#include <kaccelmanager.h>
#include <kurifilter.h>
#include <kaction.h>
#include <kshell.h>
@ -268,6 +269,7 @@ Konsole::Konsole(const char* name, int histon, bool menubaron, bool tabbaron, bo
,sessionNumberMapper(0)
,sl_sessionShortCuts(0)
,s_workDir(workdir)
,m_filterData(0)
{
isRestored = b_inRestore;
connect( &m_closeTimeout, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotCouldNotClose()));
@ -346,6 +348,8 @@ Konsole::Konsole(const char* name, int histon, bool menubaron, bool tabbaron, bo
Konsole::~Konsole()
{
delete m_filterData;
sessions.first();
while(sessions.current())
{
@ -718,6 +722,11 @@ void Konsole::makeGUI()
m_copyClipboard->plug(m_rightButton);
m_pasteClipboard->plug(m_rightButton);
m_openSelection = new KPopupMenu(this);
m_rightButton->insertItem( i18n("&Open.."), m_openSelection );
connect(m_openSelection, TQT_SIGNAL(aboutToShow()), TQT_SLOT(slotOpenSelection()));
if (m_signals)
m_rightButton->insertItem(i18n("&Send Signal"), m_signals);
@ -3950,6 +3959,34 @@ void Konsole::slotFindHistory()
m_finddialog->result();
}
void Konsole::slotOpenSelection()
{
delete m_filterData;
m_openSelection->clear();
disconnect(m_openSelection, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotOpenURI(int)));
TQString selection = se->getEmulation()->getSelection();
TQString curdir = baseURL().path();
if ( TQFile::exists( curdir + selection ) ) {
selectedURL = TQString(curdir + selection);
} else {
selectedURL = TQString(selection);
}
m_filterData = new KURIFilterData( selectedURL );
KURIFilter::self()->filterURI( *(m_filterData) );
m_openSelection->insertItem( SmallIconSet( m_filterData->iconName() ),i18n( "%1" ).arg(m_filterData->uri().url()), 1 );
connect(m_openSelection, TQT_SIGNAL(activated(int)), TQT_SLOT(slotOpenURI(int)));
}
void Konsole::slotOpenURI(int)
{
(void) new KRun( m_filterData->uri() );
}
void Konsole::slotFindNext()
{
if( !m_finddialog ) {

@ -61,6 +61,7 @@ class KSelectAction;
class KRadioAction;
class KTabWidget;
class TQToolButton;
class KURIFilterData;
// Defined in main.C
const char *konsole_shell(TQStrList &args);
@ -200,6 +201,9 @@ private slots:
void loadScreenSessions();
void updateFullScreen(bool on);
void slotOpenSelection();
void slotOpenURI(int n);
void slotSaveSettings();
void slotSaveSessionsProfile();
void slotConfigureNotifications();
@ -362,6 +366,7 @@ private:
KAction *m_print;
KAction *m_quit;
KAction *m_tabDetachSession;
KPopupMenu *m_openSelection;
KActionCollection *m_shortcuts;
@ -372,6 +377,7 @@ private:
bool m_find_first;
bool m_find_found;
TQString m_find_pattern;
TQString selectedURL;
int cmd_serial;
int cmd_first_screen;
@ -435,6 +441,7 @@ private:
TQString s_workDir;
TQColor m_tabColor;
KURIFilterData* m_filterData;
};
class TQSpinBox;

@ -220,7 +220,7 @@ void KSMServer::storeLegacySession( KConfig* config )
for (WindowMap::ConstIterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) {
if ( (*it).type != SM_ERROR) {
if( excludeApps.contains( (*it).wmclass1.lower())
|| excludeApps.contains( (*it).wmclass2.lower()))
|| excludeApps.contains( (*it).wmclass2.lower()) || (*it).wmCommand[0] == "compiz" || (*it).wmCommand[0] == "beryl" || (*it).wmCommand[0] == "aquamarine" || (*it).wmCommand[0] == "beryl-manager" || (*it).wmCommand[0] == "beryl-settings" || (*it).wmCommand[0] == "kde-window-decorator" || (*it).wmCommand[0] == "emerald")
continue;
if ( !(*it).wmCommand.isEmpty() && !(*it).wmClientMachine.isEmpty() ) {
count++;

@ -35,65 +35,85 @@
#define MON_SIZE 128
#define CALC( a, b, c, d, e ) \
#define CALC( a, b, c, d, e, f ) \
{ \
NetDevs[ i ].a = a - NetDevs[ i ].Old##a; \
NetDevs[ i ].Old##a = a; \
if (f){ \
NetDevs[ i ].a = a - NetDevs[ i ].Old##a; \
NetDevs[ i ].Old##a = a; \
} \
else{ \
NetDevs[ i ].a = a; \
} \
}
#define REGISTERSENSOR( a, b, c, d, e ) \
#define REGISTERSENSOR( a, b, c, d, e, f ) \
{ \
snprintf( mon, MON_SIZE, "network/interfaces/%s/%s", tag, b ); \
registerMonitor( mon, "integer", printNetDev##a, printNetDev##a##Info, NetDevSM ); \
}
#define UNREGISTERSENSOR( a, b, c, d, e ) \
#define UNREGISTERSENSOR( a, b, c, d, e, f ) \
{ \
snprintf( mon, MON_SIZE, "network/interfaces/%s/%s", NetDevs[ i ].name, b ); \
removeMonitor( mon ); \
}
#define DEFMEMBERS( a, b, c, d, e ) \
unsigned long long Old##a; \
unsigned long long a; \
unsigned long a##Scale;
#define DEFMEMBERS( a, b, c, d, e, f ) \
signed long long Old##a; \
signed long long a; \
signed long a##Scale;
#define DEFVARS( a, b, c, d, e ) \
unsigned long long a;
#define DEFVARS( a, b, c, d, e, f ) \
signed long long a;
/*The sixth variable is 1 if the quantity variation must be provided, 0 if the absolute value must be provided */
#define FORALL( a ) \
a( recBytes, "receiver/data", "Received Data", "kBytes/s", 1024 ) \
a( recPacks, "receiver/packets", "Received Packets", "1/s", 1 ) \
a( recErrs, "receiver/errors", "Receiver Errors", "1/s", 1 ) \
a( recDrop, "receiver/drops", "Receiver Drops", "1/s", 1 ) \
a( recFifo, "receiver/fifo", "Receiver FIFO Overruns", "1/s", 1 ) \
a( recFrame, "receiver/frame", "Receiver Frame Errors", "1/s", 1 ) \
a( recCompressed, "receiver/compressed", "Received Compressed Packets", "1/s", 1 ) \
a( recMulticast, "receiver/multicast", "Received Multicast Packets", "1/s", 1 ) \
a( sentBytes, "transmitter/data", "Sent Data", "kBytes/s", 1024 ) \
a( sentPacks, "transmitter/packets", "Sent Packets", "1/s", 1 ) \
a( sentErrs, "transmitter/errors", "Transmitter Errors", "1/s", 1 ) \
a( sentDrop, "transmitter/drops", "Transmitter Drops", "1/s", 1 ) \
a( sentFifo, "transmitter/fifo", "Transmitter FIFO overruns", "1/s", 1 ) \
a( sentColls, "transmitter/collisions", "Transmitter Collisions", "1/s", 1 ) \
a( sentCarrier, "transmitter/carrier", "Transmitter Carrier losses", "1/s", 1 ) \
a( sentCompressed, "transmitter/compressed", "Transmitter Compressed Packets", "1/s", 1 )
#define SETZERO( a, b, c, d, e ) \
a( recBytes, "receiver/data", "Received Data", "kBytes/s", 1024, 1) \
a( recPacks, "receiver/packets", "Received Packets", "1/s", 1, 1 ) \
a( recErrs, "receiver/errors", "Receiver Errors", "1/s", 1, 1 ) \
a( recDrop, "receiver/drops", "Receiver Drops", "1/s", 1, 1 ) \
a( recFifo, "receiver/fifo", "Receiver FIFO Overruns", "1/s", 1, 1 ) \
a( recFrame, "receiver/frame", "Receiver Frame Errors", "1/s", 1, 1 ) \
a( recCompressed, "receiver/compressed", "Received Compressed Packets", "1/s", 1, 1 ) \
a( recMulticast, "receiver/multicast", "Received Multicast Packets", "1/s", 1, 1 ) \
a( sentBytes, "transmitter/data", "Sent Data", "kBytes/s", 1024, 1 ) \
a( sentPacks, "transmitter/packets", "Sent Packets", "1/s", 1, 1 ) \
a( sentErrs, "transmitter/errors", "Transmitter Errors", "1/s", 1, 1 ) \
a( sentDrop, "transmitter/drops", "Transmitter Drops", "1/s", 1, 1 ) \
a( sentFifo, "transmitter/fifo", "Transmitter FIFO overruns", "1/s", 1, 1 ) \
a( sentColls, "transmitter/collisions", "Transmitter Collisions", "1/s", 1, 1 ) \
a( sentCarrier, "transmitter/carrier", "Transmitter Carrier losses", "1/s", 1, 1 ) \
a( sentCompressed, "transmitter/compressed", "Transmitter Compressed Packets", "1/s", 1, 1 )
#define FORALLWIFI( a ) \
a( linkQuality, "wifi/quality", "Link Quality", "", 1, 0) \
a( signalLevel, "wifi/signal", "Signal Level", "dBm", 1, 0) \
a( noiseLevel, "wifi/noise", "Noise Level", "dBm", 1, 0) \
a( nwid, "wifi/nwid", "Rx Invalid Nwid Packets", "1/s", 1, 1) \
a( RxCrypt, "wifi/crypt", "Rx Invalid Crypt Packets", "1/s", 1, 1) \
a( frag, "wifi/frag", "Rx Invalid Frag Packets", "1/s", 1, 1) \
a( retry, "wifi/retry", "Tx Excessive Retries Packets", "1/s", 1, 1) \
a( misc, "wifi/misc", "Invalid Misc Packets", "1/s", 1, 1) \
a( beacon, "wifi/beacon", "Missed Beacon", "1/s", 1, 1)
#define SETZERO( a, b, c, d, e, f ) \
a = 0;
#define SETMEMBERZERO( a, b, c, d, e ) \
#define SETMEMBERZERO( a, b, c, d, e, f ) \
NetDevs[ i ].a = 0; \
NetDevs[ i ].a##Scale = e;
#define DECLAREFUNC( a, b, c, d, e ) \
#define DECLAREFUNC( a, b, c, d, e, f ) \
void printNetDev##a( const char* cmd ); \
void printNetDev##a##Info( const char* cmd );
typedef struct
{
FORALL( DEFMEMBERS )
FORALLWIFI( DEFMEMBERS )
char name[ 32 ];
int wifi;
} NetDevInfo;
/* We have observed deviations of up to 5% in the accuracy of the timer
@ -106,6 +126,7 @@ static struct SensorModul* NetDevSM;
#define NETDEVBUFSIZE 4096
static char NetDevBuf[ NETDEVBUFSIZE ];
static char NetDevWifiBuf[ NETDEVBUFSIZE ];
static int NetDevCnt = 0;
static int Dirty = 0;
static int NetDevOk = 0;
@ -117,15 +138,17 @@ static NetDevInfo NetDevs[ MAXNETDEVS ];
void processNetDev( void );
FORALL( DECLAREFUNC )
FORALLWIFI( DECLAREFUNC )
static int processNetDev_( void )
{
int i;
int i,j;
char format[ 32 ];
char devFormat[ 16 ];
char buf[ 1024 ];
char tag[ 64 ];
char* netDevBufP = NetDevBuf;
char* netDevWifiBufP = NetDevWifiBuf;
sprintf( format, "%%%d[^\n]\n", (int)sizeof( buf ) - 1 );
sprintf( devFormat, "%%%ds", (int)sizeof( tag ) - 1 );
@ -147,8 +170,8 @@ static int processNetDev_( void )
FORALL( DEFVARS );
*pos = '\0';
FORALL( SETZERO );
sscanf( buf + 7, "%llu %llu %llu %llu %llu %llu %llu %llu "
"%llu %llu %llu %llu %llu %llu %llu %llu",
sscanf( buf + 7, "%lli %lli %lli %lli %lli %lli %lli %lli "
"%lli %lli %lli %lli %lli %lli %lli %lli",
&recBytes, &recPacks, &recErrs, &recDrop, &recFifo,
&recFrame, &recCompressed, &recMulticast,
&sentBytes, &sentPacks, &sentErrs, &sentDrop,
@ -168,6 +191,44 @@ static int processNetDev_( void )
if ( i != NetDevCnt )
return -1;
/*Update the values for the wifi interfaces*/
if ( *netDevWifiBufP=='\0') /*there is no /proc/net/wireless file*/
return 0;
/* skip 2 first lines */
for ( i = 0; i < 2; i++ ) {
sscanf( netDevWifiBufP, format, buf );
buf[ sizeof( buf ) - 1 ] = '\0';
netDevWifiBufP += strlen( buf ) + 1; /* move netDevWifiBufP to next line */
}
for ( j = 0; sscanf( netDevWifiBufP, format, buf ) == 1; ++j ) {
buf[ sizeof( buf ) - 1 ] = '\0';
netDevWifiBufP += strlen( buf ) + 1; /* move netDevWifiBufP to next line */
if ( sscanf( buf, devFormat, tag ) ) {
char* pos = strchr( tag, ':' );
if ( pos ) {
FORALLWIFI( DEFVARS );
*pos = '\0';
for (i = 0 ; i < NetDevCnt ; ++i){ /*find the corresponding interface*/
if ( strcmp(tag,NetDevs[ i ].name)==0){
break;
}
}
sscanf( buf + 12, " %lli. %lli. %lli. %lli %lli %lli %lli %lli %lli",
&linkQuality, &signalLevel, &noiseLevel, &nwid,
&RxCrypt, &frag, &retry, &misc, &beacon );
signalLevel -= 256; /*the units are dBm*/
noiseLevel -= 256;
FORALLWIFI( CALC );
}
}
}
/* save exact time inverval between this and the last read of
* /proc/net/dev */
timeInterval = currSampling.tv_sec - lastSampling.tv_sec +
@ -200,12 +261,13 @@ void processNetDev( void )
void initNetDev( struct SensorModul* sm )
{
int i;
int i,j;
char format[ 32 ];
char devFormat[ 16 ];
char buf[ 1024 ];
char tag[ 64 ];
char* netDevBufP = NetDevBuf;
char* netDevWifiBufP = NetDevWifiBuf;
NetDevSM = sm;
@ -233,8 +295,8 @@ void initNetDev( struct SensorModul* sm )
*pos = '\0';
strlcpy( NetDevs[ i ].name, tag, sizeof( NetDevs[ i ].name ) );
FORALL( REGISTERSENSOR );
sscanf( pos + 1, "%llu %llu %llu %llu %llu %llu %llu %llu"
"%llu %llu %llu %llu %llu %llu %llu %llu",
sscanf( pos + 1, "%lli %lli %lli %lli %lli %lli %lli %lli"
"%lli %lli %lli %lli %lli %lli %lli %lli",
&NetDevs[ i ].recBytes, &NetDevs[ i ].recPacks,
&NetDevs[ i ].recErrs, &NetDevs[ i ].recDrop,
&NetDevs[ i ].recFifo, &NetDevs[ i ].recFrame,
@ -247,6 +309,39 @@ void initNetDev( struct SensorModul* sm )
}
FORALL( SETMEMBERZERO );
}
}
/* detect the wifi interfaces*/
/* skip 2 first lines */
for ( i = 0; i < 2; i++ ) {
sscanf( netDevWifiBufP, format, buf );
buf[ sizeof( buf ) - 1 ] = '\0';
netDevWifiBufP += strlen( buf ) + 1; /* move netDevWifiBufP to next line */
}
for ( j = 0; sscanf( netDevWifiBufP, format, buf ) == 1; ++j ) {
buf[ sizeof( buf ) - 1 ] = '\0';
netDevWifiBufP += strlen( buf ) + 1; /* move netDevWifiBufP to next line */
if ( sscanf( buf, devFormat, tag ) ) {
char * pos = strchr( tag, ':' );
if ( pos ) {
char mon[ MON_SIZE ];
*pos = '\0';
/*find and tag the corresponding NetDev as wifi enabled.
At the end of the loop, i is the index of the device.
This variable i is used in some macro */
for (i = 0 ; i < NetDevCnt ; ++i){
if ( strcmp(tag,NetDevs[ i ].name)==0){
NetDevs[ i ].wifi = 1;
break;
}
}
FORALLWIFI( REGISTERSENSOR );
}
FORALLWIFI( SETMEMBERZERO ); /* the variable i must point to the corrrect NetDevs[i]*/
}
}
/* Call processNetDev to elimitate initial peek values. */
@ -260,6 +355,8 @@ void exitNetDev( void )
for ( i = 0; i < NetDevCnt; ++i ) {
char mon[ MON_SIZE ];
FORALL( UNREGISTERSENSOR );
if (NetDevs[ i ].wifi)
FORALLWIFI( UNREGISTERSENSOR );
}
NetDevCnt = 0;
}
@ -320,6 +417,20 @@ int updateNetDev( void )
Dirty = 1;
/* We read the informations about the wifi from /proc/net/wireless and store it into NetDevWifiBuf */
if ( ( fd = open( "/proc/net/wireless", O_RDONLY ) ) < 0 ) {
/* /proc/net/wireless may not exist on some machines. */
NetDevWifiBuf[0]='\0';
}
if ( ( n = read( fd, NetDevWifiBuf, NETDEVBUFSIZE - 1 ) ) == NETDEVBUFSIZE - 1 ) {
log_error( "Internal buffer too small to read \'/proc/net/wireless\'" );
close( fd );
return -1;
}
close( fd );
NetDevWifiBuf[ n ] = '\0';
return 0;
}
@ -331,7 +442,7 @@ void checkNetDev( void )
initNetDev( NetDevSM );
}
#define PRINTFUNC( a, b, c, d, e ) \
#define PRINTFUNC( a, b, c, d, e, f ) \
void printNetDev##a( const char* cmd ) \
{ \
int i; \
@ -350,8 +461,11 @@ void printNetDev##a( const char* cmd ) \
\
for ( i = 0; i < MAXNETDEVS; ++i ) \
if ( strcmp( NetDevs[ i ].name, dev ) == 0) { \
fprintf( CurrentClient, "%lu\n", (unsigned long) \
if (f) \
fprintf( CurrentClient, "%li\n", (long) \
( NetDevs[ i ].a / ( NetDevs[ i ].a##Scale * timeInterval ) ) ); \
else \
fprintf( CurrentClient, "%li\n", (long) NetDevs[ i ].a ); \
return; \
} \
\
@ -365,3 +479,4 @@ void printNetDev##a##Info( const char* cmd ) \
}
FORALL( PRINTFUNC )
FORALLWIFI( PRINTFUNC )

@ -23,6 +23,9 @@ class KWinInterface : virtual public DCOPObject
virtual void nextDesktop() = 0;
virtual void previousDesktop() = 0;
virtual void circulateDesktopApplications() = 0;
virtual void updateOverlappingShadows(unsigned long window) = 0;
virtual void setShadowed(unsigned long window, bool shadowed) = 0;
// kompmgr stuff
virtual void startKompmgr() = 0;
virtual void stopKompmgr() = 0;

@ -227,6 +227,13 @@ void Workspace::setActiveClient( Client* c, allowed_t )
active_client->setActive( false, !c || !c->isModal() || c != active_client->transientFor() );
}
active_client = c;
if (set_active_client_recursion == 1)
{
// Only unset next_active_client if activateClient() wasn't called by
// Client::setActive() to set the active window to null before
// activating another window.
next_active_client = NULL;
}
Q_ASSERT( c == NULL || c->isActive());
if( active_client != NULL )
last_active_client = active_client;
@ -324,6 +331,7 @@ void Workspace::takeActivity( Client* c, int flags, bool handled )
Client* modal = c->findModal();
if( modal != NULL && modal != c )
{
next_active_client = modal;
if( !modal->isOnDesktop( c->desktop()))
{
modal->setDesktop( c->desktop());
@ -351,11 +359,14 @@ void Workspace::takeActivity( Client* c, int flags, bool handled )
c->setActive( true );
focusToNull();
}
if( c->wantsInput())
next_active_client = c;
flags &= ~ActivityFocus;
handled = false; // no point, can't get clicks
}
if( !c->isShown( true )) // shouldn't happen, call activateClient() if needed
{
next_active_client = c;
kdWarning( 1212 ) << "takeActivity: not shown" << endl;
return;
}
@ -856,7 +867,45 @@ void Client::setActive( bool act, bool updateOpacity_)
updateShadowSize();
if ( active )
{
Notify::raise( Notify::Activate );
if (options->shadowEnabled(true))
{
if (options->shadowEnabled(false))
{
// Wait for inactive shadow to expose occluded windows and give
// them a chance to redraw before painting the active shadow
removeShadow();
drawDelayedShadow();
if (!isDesktop() &&
this != workspace()->topClientOnDesktop(desktop()))
// If the newly activated window's isn't the desktop, wait
// for its shadow to draw, then redraw any shadows
// overlapping it.
drawOverlappingShadows(true);
}
else
drawShadow();
}
}
else
{
removeShadow();
if (options->shadowEnabled(false))
if (this == workspace()->topClientOnDesktop(desktop()))
{
/* If the newly deactivated window is the top client on the
* desktop, then the newly activated window is below it; ensure
* that the deactivated window's shadow draws after the
* activated window's shadow.
*/
if ((shadowAfterClient = workspace()->activeClient()))
drawShadowAfter(shadowAfterClient);
}
else
drawDelayedShadow();
}
if( !active )
cancelAutoRaise();

@ -11,9 +11,12 @@ License. See the file "COPYING" for the exact licensing terms.
#include "client.h"
#include <math.h>
#include <tqapplication.h>
#include <tqpainter.h>
#include <tqdatetime.h>
#include <tqimage.h>
#include <kprocess.h>
#include <unistd.h>
#include <kstandarddirs.h>
@ -39,9 +42,25 @@ extern Time qt_x_time;
extern Atom qt_window_role;
extern Atom qt_sm_client_id;
// wait 200 ms before drawing shadow after move/resize
static const int SHADOW_DELAY = 200;
namespace KWinInternal
{
/* TODO: Remove this once X has real translucency.
*
* A list of the regions covered by all shadows and the Clients to which they
* belong. Used to redraw shadows when a window overlapping or underlying a
* shadow is moved, resized, or hidden.
*/
struct ShadowRegion
{
TQRegion region;
Client *client;
};
static TQValueList<ShadowRegion> shadowRegions;
/*
Creating a client:
@ -100,6 +119,13 @@ Client::Client( Workspace *ws )
autoRaiseTimer = 0;
shadeHoverTimer = 0;
shadowDelayTimer = new TQTimer(this);
opacityCache = &activeOpacityCache;
shadowAfterClient = NULL;
shadowWidget = NULL;
shadowMe = true;
connect(shadowDelayTimer, TQT_SIGNAL(timeout()), TQT_SLOT(drawShadow()));
// set the initial mapping state
mapping_state = WithdrawnState;
desk = 0; // no desktop yet
@ -145,7 +171,7 @@ Client::Client( Workspace *ws )
maxmode_restore = MaximizeRestore;
cmap = None;
frame_geometry = TQRect( 0, 0, 100, 100 ); // so that decorations don't start with size being (0,0)
client_size = TQSize( 100, 100 );
custom_opacity = false;
@ -188,6 +214,8 @@ void Client::releaseWindow( bool on_shutdown )
if (!custom_opacity) setOpacity(FALSE);
if (moveResizeMode)
leaveMoveResize();
removeShadow();
drawIntersectingShadows();
finishWindowRules();
++postpone_geometry_updates;
// grab X during the release to make removing of properties, setting to withdrawn state
@ -248,6 +276,8 @@ void Client::destroyClient()
StackingUpdatesBlocker blocker( workspace());
if (moveResizeMode)
leaveMoveResize();
removeShadow();
drawIntersectingShadows();
finishWindowRules();
++postpone_geometry_updates;
setModal( false );
@ -304,6 +334,7 @@ void Client::updateDecoration( bool check_workspace_pos, bool force )
if( do_show )
decoration->widget()->show();
updateFrameExtents();
updateOpacityCache();
}
void Client::destroyDecoration()
@ -434,6 +465,12 @@ void Client::resizeDecoration( const TQSize& s )
TQResizeEvent e( s, oldsize );
TQApplication::sendEvent( decoration->widget(), &e );
}
if (!moveResizeMode && options->shadowEnabled(isActive()))
{
// If the user is manually resizing, let Client::leaveMoveResize()
// decide when to redraw the shadow
updateOpacityCache();
}
}
bool Client::noBorder() const
@ -471,6 +508,7 @@ void Client::updateShape()
noborder = true;
updateDecoration( true );
}
updateOpacityCache();
if ( shape() )
{
XShapeCombineShape(qt_xdisplay(), frameId(), ShapeBounding,
@ -862,6 +900,16 @@ void Client::setShade( ShadeMode mode )
XMapWindow( qt_xdisplay(), wrapperId());
XMapWindow( qt_xdisplay(), window());
XDeleteProperty (qt_xdisplay(), client, atoms->net_wm_window_shade);
if (options->shadowEnabled(false))
{
for (ClientList::ConstIterator it = transients().begin();
it != transients().end(); ++it)
{
(*it)->removeShadow();
(*it)->drawDelayedShadow();
}
}
if ( isActive() )
workspace()->requestFocus( this );
}
@ -946,6 +994,589 @@ void Client::updateVisibility()
}
}
void Client::setShadowed(bool shadowed)
{
bool wasShadowed;
wasShadowed = isShadowed();
shadowMe = options->shadowEnabled(isActive()) ? shadowed : false;
if (shadowMe) {
if (!wasShadowed)
drawShadow();
}
else {
if (wasShadowed) {
removeShadow();
if (!activeOpacityCache.isNull())
activeOpacityCache.resize(0);
if (!inactiveOpacityCache.isNull())
inactiveOpacityCache.resize(0);
}
}
}
void Client::updateOpacityCache()
{
if (!activeOpacityCache.isNull())
activeOpacityCache.resize(0);
if (!inactiveOpacityCache.isNull())
inactiveOpacityCache.resize(0);
if (!moveResizeMode) {
// If the user is manually resizing, let Client::finishMoveResize()
// decide when to redraw the shadow
removeShadow();
drawIntersectingShadows();
if (options->shadowEnabled(isActive()))
drawDelayedShadow();
}
}
/*!
Redraw shadows that were previously occluding or occluded by this window,
to avoid visual glitches.
*/
void Client::drawIntersectingShadows() {
//Client *reshadowClient;
TQRegion region;
//TQPtrList<Client> reshadowClients;
TQValueList<Client *> reshadowClients;
TQValueListIterator<ShadowRegion> it;
TQValueListIterator<Client *> it2;
if (!options->shadowEnabled(false))
// No point in redrawing overlapping/overlapped shadows if only the
// active window has a shadow.
return;
region = shapeBoundingRegion;
// Generate list of Clients whose shadows need to be redrawn. That is,
// those that are currently intersecting or intersected by other windows or
// shadows.
for (it = shadowRegions.begin(); it != shadowRegions.end(); ++it)
if ((isOnAllDesktops() || (*it).client->isOnCurrentDesktop()) &&
!(*it).region.intersect(region).isEmpty())
reshadowClients.append((*it).client);
// Redraw shadows for each of the Clients in the list generated above
for (it2 = reshadowClients.begin(); it2 != reshadowClients.end();
++it2) {
(*it2)->removeShadow();
(*it2)->drawDelayedShadow();
}
}
/*!
Redraw shadows that are above the current window in the stacking order.
Furthermore, redraw them in the same order as they come in the stacking order
from bottom to top.
*/
void Client::drawOverlappingShadows(bool waitForMe)
{
Client *aClient;
TQRegion region;
TQValueList<Client *> reshadowClients;
ClientList stacking_order;
ClientList::ConstIterator it;
TQValueListIterator<ShadowRegion> it2;
TQValueListIterator<Client *> it3;
if (!options->shadowEnabled(false))
// No point in redrawing overlapping/overlapped shadows if only the
// active window has a shadow.
return;
region = shapeBoundingRegion;
stacking_order = workspace()->stackingOrder();
for (it = stacking_order.fromLast(); it != stacking_order.end(); --it) {
// Find the position of this window in the stacking order.
if ((*it) == this)
break;
}
++it;
while (it != stacking_order.end()) {
if ((*it)->windowType() == NET::Dock) {
// This function is only interested in windows whose shadows don't
// have weird stacking rules.
++it;
continue;
}
// Generate list of Clients whose shadows need to be redrawn. That is,
// those that are currently overlapping or overlapped by other windows
// or shadows. The list should be in order from bottom to top in the
// stacking order.
for (it2 = shadowRegions.begin(); it2 != shadowRegions.end(); ++it2) {
if ((*it2).client == (*it)) {
if ((isOnAllDesktops() || (*it2).client->isOnCurrentDesktop())
&& !(*it2).region.intersect(region).isEmpty())
reshadowClients.append((*it2).client);
}
}
++it;
}
// Redraw shadows for each of the Clients in the list generated above
for (it3 = reshadowClients.begin(); it3 != reshadowClients.end(); ++it3) {
(*it3)->removeShadow();
if (it3 == reshadowClients.begin()) {
if (waitForMe)
(*it3)->drawShadowAfter(this);
else
(*it3)->drawDelayedShadow();
}
else {
--it3;
aClient = (*it3);
++it3;
(*it3)->drawShadowAfter(aClient);
}
}
}
/*!
Draw shadow after some time has elapsed, to give recently exposed windows a
chance to repaint before a shadow gradient is drawn over them.
*/
void Client::drawDelayedShadow()
{
shadowDelayTimer->stop();
shadowDelayTimer->start(SHADOW_DELAY, true);
}
/*!
Draw shadow immediately after the specified Client's shadow finishes drawing.
*/
void Client::drawShadowAfter(Client *after)
{
shadowAfterClient = after;
connect(after, TQT_SIGNAL(shadowDrawn()), TQT_SLOT(drawShadow()));
}
/*!
Draw a shadow under this window and XShape the shadow accordingly.
*/
void Client::drawShadow()
{
Window shadows[2];
XRectangle *shapes;
int i, count, ordering;
// If we are waiting for another Client's shadow to be drawn, stop waiting now
if (shadowAfterClient != NULL) {
disconnect(shadowAfterClient, TQT_SIGNAL(shadowDrawn()), this, TQT_SLOT(drawShadow()));
shadowAfterClient = NULL;
}
if (!isOnCurrentDesktop())
return;
/* Store this window's ShapeBoundingRegion even if shadows aren't drawn for
* this type of window. Otherwise, drawIntersectingShadows() won't update
* properly when this window is moved/resized/hidden/closed.
*/
shapes = XShapeGetRectangles(qt_xdisplay(), frameId(), ShapeBounding,
&count, &ordering);
if (!shapes)
// XShape extension not supported
shapeBoundingRegion = TQRegion(x(), y(), width(), height());
else {
shapeBoundingRegion = TQRegion();
for (i = 0; i < count; i++) {
// Translate XShaped window into a TQRegion
TQRegion shapeRectangle(shapes[i].x, shapes[i].y, shapes[i].width,
shapes[i].height);
shapeBoundingRegion += shapeRectangle;
}
if (isShade())
// Since XResize() doesn't change a window's XShape regions, ensure that
// shapeBoundingRegion is not taller than the window's shaded height,
// or the bottom shadow will appear to be missing
shapeBoundingRegion &= TQRegion(0, 0, width(), height());
shapeBoundingRegion.translate(x(), y());
}
if (!isShadowed() || hidden || isMinimized() ||
maximizeMode() == MaximizeFull ||
!options->shadowWindowType(windowType())) {
XFree(shapes);
// Tell whatever Clients are listening that this Client's shadow has been drawn.
// It hasn't, but there's no sense waiting for something that won't happen.
emit shadowDrawn();
return;
}
removeShadow();
TQMemArray<QRgb> pixelData;
TQPixmap shadowPixmap;
TQRect shadow;
TQRegion exposedRegion;
ShadowRegion shadowRegion;
int thickness, xOffset, yOffset;
thickness = options->shadowThickness(isActive());
xOffset = options->shadowXOffset(isActive());
yOffset = options->shadowYOffset(isActive());
opacityCache = active? &activeOpacityCache : &inactiveOpacityCache;
shadow.setRect(x() - thickness + xOffset, y() - thickness + yOffset,
width() + thickness * 2, height() + thickness * 2);
shadowPixmap.resize(shadow.size());
// Create a fake drop-down shadow effect via blended Xwindows
shadowWidget = new TQWidget(0, 0, WStyle_Customize | WX11BypassWM);
shadowWidget->setGeometry(shadow);
XSelectInput(qt_xdisplay(), shadowWidget->winId(),
ButtonPressMask | ButtonReleaseMask | StructureNotifyMask);
shadowWidget->installEventFilter(this);
if (!shapes) {
// XShape extension not supported
exposedRegion = getExposedRegion(shapeBoundingRegion, shadow.x(),
shadow.y(), shadow.width(), shadow.height(), thickness,
xOffset, yOffset);
shadowRegion.region = exposedRegion;
shadowRegion.client = this;
shadowRegions.append(shadowRegion);
if (opacityCache->isNull())
imposeRegionShadow(shadowPixmap, shapeBoundingRegion,
exposedRegion, thickness,
options->shadowOpacity(isActive()));
else
imposeCachedShadow(shadowPixmap, exposedRegion);
}
else {
TQMemArray<TQRect> exposedRects;
TQMemArray<TQRect>::Iterator it, itEnd;
XRectangle *shadowShapes;
exposedRegion = getExposedRegion(shapeBoundingRegion, shadow.x(),
shadow.y(), shadow.width(), shadow.height(), thickness,
xOffset, yOffset);
shadowRegion.region = exposedRegion;
shadowRegion.client = this;
shadowRegions.append(shadowRegion);
// XShape the shadow
exposedRects = exposedRegion.rects();
i = 0;
itEnd = exposedRects.end();
shadowShapes = new XRectangle[exposedRects.count()];
for (it = exposedRects.begin(); it != itEnd; ++it) {
shadowShapes[i].x = (*it).x();
shadowShapes[i].y = (*it).y();
shadowShapes[i].width = (*it).width();
shadowShapes[i].height = (*it).height();
i++;
}
XShapeCombineRectangles(qt_xdisplay(), shadowWidget->winId(),
ShapeBounding, -x() + thickness - xOffset,
-y() + thickness - yOffset, shadowShapes, i, ShapeSet,
Unsorted);
delete [] shadowShapes;
if (opacityCache->isNull())
imposeRegionShadow(shadowPixmap, shapeBoundingRegion,
exposedRegion, thickness,
options->shadowOpacity(isActive()));
else
imposeCachedShadow(shadowPixmap, exposedRegion);
}
XFree(shapes);
// Set the background pixmap
//shadowPixmap.convertFromImage(shadowImage);
shadowWidget->setErasePixmap(shadowPixmap);
// Restack shadows under this window so that shadows drawn for a newly
// focused (but not raised) window don't overlap any windows above it.
if (isDock()) {
ClientList stacking_order = workspace()->stackingOrder();
for (ClientList::ConstIterator it = stacking_order.begin(); it != stacking_order.end(); ++it)
if ((*it)->isDesktop())
{
++it;
shadows[0] = (*it)->frameId();
shadows[1] = shadowWidget->winId();
}
}
else {
shadows[0] = frameId();
if (shadowWidget != NULL)
shadows[1] = shadowWidget->winId();
}
XRestackWindows(qt_xdisplay(), shadows, 2);
// Don't use TQWidget::show() so we don't confuse QEffects, thus causing
// broken focus.
XMapWindow(qt_xdisplay(), shadowWidget->winId());
// Tell whatever Clients are listening that this Client's shadow has been drawn.
emit shadowDrawn();
}
/*!
Remove shadow under this window.
*/
void Client::removeShadow()
{
TQValueList<ShadowRegion>::Iterator it;
shadowDelayTimer->stop();
if (shadowWidget != NULL) {
for (it = shadowRegions.begin(); it != shadowRegions.end(); ++it)
if ((*it).client == this) {
shadowRegions.remove(it);
break;
}
delete shadowWidget;
shadowWidget = NULL;
}
}
/*!
Calculate regions in which the shadow will be visible given the window's
origin, height and width and the shadow's thickness, and X- and Y-offsets.
*/
TQRegion Client::getExposedRegion(TQRegion occludedRegion, int x, int y, int w,
int h, int thickness, int xOffset, int yOffset)
{
TQRegion exposedRegion;
exposedRegion = TQRegion(x, y, w, h);
exposedRegion -= occludedRegion;
if (thickness > 0) {
// Limit exposedRegion to include only where a shadow of the specified
// thickness will be drawn
TQMemArray<TQRect> occludedRects;
TQMemArray<TQRect>::Iterator it, itEnd;
TQRegion shadowRegion;
occludedRects = occludedRegion.rects();
itEnd = occludedRects.end();
for (it = occludedRects.begin(); it != itEnd; ++it) {
// Expand each of the occluded region's shape rectangles to contain
// where a shadow of the specified thickness will be drawn. Create
// a new TQRegion that contains the expanded occluded region
it->setTop(it->top() - thickness + yOffset);
it->setLeft(it->left() - thickness + xOffset);
it->setRight(it->right() + thickness + xOffset);
it->setBottom(it->bottom() + thickness + yOffset);
shadowRegion += TQRegion(*it);
}
exposedRegion -= exposedRegion - shadowRegion;
}
return exposedRegion;
}
/*!
Draw shadow gradient around this window using cached opacity values.
*/
void Client::imposeCachedShadow(TQPixmap &pixmap, TQRegion exposed)
{
QRgb pixel;
double opacity;
int red, green, blue, pixelRed, pixelGreen, pixelBlue;
int subW, subH, w, h, x, y, zeroX, zeroY;
TQImage image;
TQMemArray<TQRect>::Iterator it, itEnd;
TQMemArray<TQRect> rectangles;
TQPixmap subPixmap;
Window rootWindow;
int thickness, windowX, windowY, xOffset, yOffset;
rectangles = exposed.rects();
rootWindow = qt_xrootwin();
thickness = options->shadowThickness(isActive());
windowX = this->x();
windowY = this->y();
xOffset = options->shadowXOffset(isActive());
yOffset = options->shadowYOffset(isActive());
options->shadowColour(isActive()).rgb(&red, &green, &blue);
w = pixmap.width();
h = pixmap.height();
itEnd = rectangles.end();
for (it = rectangles.begin(); it != itEnd; ++it) {
subW = (*it).width();
subH = (*it).height();
subPixmap = TQPixmap::grabWindow(rootWindow, (*it).x(), (*it).y(),
subW, subH);
zeroX = (*it).x() - windowX + thickness - xOffset;
zeroY = (*it).y() - windowY + thickness - yOffset;
image = subPixmap.convertToImage();
for (x = 0; x < subW; x++) {
for (y = 0; y < subH; y++) {
opacity = (*(opacityCache))[(zeroY + y) * w + zeroX + x];
pixel = image.pixel(x, y);
pixelRed = qRed(pixel);
pixelGreen = qGreen(pixel);
pixelBlue = qBlue(pixel);
image.setPixel(x, y,
qRgb((int)(pixelRed + (red - pixelRed) * opacity),
(int)(pixelGreen + (green - pixelGreen) * opacity),
(int)(pixelBlue + (blue - pixelBlue) * opacity)));
}
}
subPixmap.convertFromImage(image);
bitBlt(&pixmap, zeroX, zeroY, &subPixmap);
}
}
/*!
Draw shadow around this window using calculated opacity values.
*/
void Client::imposeRegionShadow(TQPixmap &pixmap, TQRegion occluded,
TQRegion exposed, int thickness, double maxOpacity)
{
register int distance, intersectCount, i, j, x, y;
QRgb pixel;
double decay, factor, opacity;
int red, green, blue, pixelRed, pixelGreen, pixelBlue;
int halfMaxIntersects, lineIntersects, maxIntersects, maxY;
int irBottom, irLeft, irRight, irTop, yIncrement;
int subW, subH, w, h, zeroX, zeroY;
TQImage image;
TQMemArray<TQRect>::Iterator it, itEnd;
TQMemArray<TQRect> rectangles;
TQPixmap subPixmap;
Window rootWindow;
int windowX, windowY, xOffset, yOffset;
rectangles = exposed.rects();
rootWindow = qt_xrootwin();
windowX = this->x();
windowY = this->y();
xOffset = options->shadowXOffset(isActive());
yOffset = options->shadowYOffset(isActive());
options->shadowColour(isActive()).rgb(&red, &green, &blue);
maxIntersects = thickness * thickness * 4 + (thickness * 4) + 1;
halfMaxIntersects = maxIntersects / 2;
lineIntersects = thickness * 2 + 1;
factor = maxIntersects / maxOpacity;
decay = (lineIntersects / 0.0125 - factor) / pow((double)maxIntersects, 3.0);
w = pixmap.width();
h = pixmap.height();
xOffset = options->shadowXOffset(isActive());
yOffset = options->shadowYOffset(isActive());
opacityCache->resize(0);
opacityCache->resize(w * h);
occluded.translate(-windowX + thickness, -windowY + thickness);
itEnd = rectangles.end();
for (it = rectangles.begin(); it != itEnd; ++it) {
subW = (*it).width();
subH = (*it).height();
subPixmap = TQPixmap::grabWindow(rootWindow, (*it).x(), (*it).y(),
subW, subH);
maxY = subH;
zeroX = (*it).x() - windowX + thickness - xOffset;
zeroY = (*it).y() - windowY + thickness - yOffset;
image = subPixmap.convertToImage();
intersectCount = 0;
opacity = -1;
y = 0;
yIncrement = 1;
for (x = 0; x < subW; x++) {
irLeft = zeroX + x - thickness;
irRight = zeroX + x + thickness;
while (y != maxY) {
// horizontal row about to leave the intersect region, not
// necessarily the top row
irTop = zeroY + y - thickness * yIncrement;
// horizontal row that just came into the intersect region,
// not necessarily the bottom row
irBottom = zeroY + y + thickness * yIncrement;
if (opacity == -1) {
// If occluded pixels caused an intersect count to be
// skipped, recount it
intersectCount = 0;
for (j = irTop; j != irBottom; j += yIncrement) {
// irTop is not necessarily larger than irBottom and
// yIncrement isn't necessarily positive
for (i = irLeft; i <= irRight; i++) {
if (occluded.contains(TQPoint(i, j)))
intersectCount++;
}
}
}
else {
if (intersectCount < 0)
intersectCount = 0;
for (i = irLeft; i <= irRight; i++) {
if (occluded.contains(TQPoint(i, irBottom)))
intersectCount++;
}
}
distance = maxIntersects - intersectCount;
opacity = intersectCount / (factor + pow((double)distance, 3.0) * decay);
(*(opacityCache))[(zeroY + y) * w + zeroX + x] = opacity;
pixel = image.pixel(x, y);
pixelRed = qRed(pixel);
pixelGreen = qGreen(pixel);
pixelBlue = qBlue(pixel);
image.setPixel(x, y,
qRgb((int)(pixelRed + (red - pixelRed) * opacity),
(int)(pixelGreen + (green - pixelGreen) * opacity),
(int)(pixelBlue + (blue - pixelBlue) * opacity)));
for (i = irLeft; i <= irRight; i++) {
if (occluded.contains(TQPoint(i, irTop)))
intersectCount--;
}
y += yIncrement;
}
y -= yIncrement;
irTop += yIncrement;
for (j = irTop; j != irBottom; j += yIncrement) {
if (occluded.contains(TQPoint(irLeft, j)))
intersectCount--;
}
irRight++;
for (j = irTop; j != irBottom; j += yIncrement) {
if (occluded.contains(TQPoint(irRight, j)))
intersectCount++;
}
yIncrement *= -1;
if (yIncrement < 0)
// Scan Y-axis bottom-up for next X-coordinate iteration
maxY = -1;
else
// Scan Y-axis top-down for next X-coordinate iteration
maxY = subH;
}
subPixmap.convertFromImage(image);
bitBlt(&pixmap, zeroX, zeroY, &subPixmap);
}
}
/*!
Sets the client window's mapping state. Possible values are
WithdrawnState, IconicState, NormalState.
@ -989,6 +1620,8 @@ void Client::rawShow()
XMapWindow( qt_xdisplay(), wrapper );
XMapWindow( qt_xdisplay(), client );
}
if (options->shadowEnabled(isActive()))
drawDelayedShadow();
}
/*!
@ -1004,6 +1637,8 @@ void Client::rawHide()
// which won't be missed, so this shouldn't be a problem. The chance the real UnmapNotify
// will be missed is also very minimal, so I don't think it's needed to grab the server
// here.
removeShadow();
drawIntersectingShadows();
XSelectInput( qt_xdisplay(), wrapper, ClientWinMask ); // avoid getting UnmapNotify
XUnmapWindow( qt_xdisplay(), frame );
XUnmapWindow( qt_xdisplay(), wrapper );

@ -200,6 +200,19 @@ class Client : public TQObject, public KDecorationDefines
void updateDecoration( bool check_workspace_pos, bool force = false );
void checkBorderSizes();
// drop shadow
bool isShadowed() const;
void setShadowed(bool shadowed);
Window shadowId() const;
// Aieee, a friend function! Unpleasant, yes, but it's needed by
// raiseClient() to redraw a window's shadow when it is active prior to
// being raised.
friend void Workspace::raiseClient(Client *);
// Wouldn't you know it, friend functions breed. This one's needed to
// enable a DCOP function that causes all shadows obscuring a changed
// window to be redrawn.
friend void Workspace::updateOverlappingShadows(WId);
// shape extensions
bool shape() const;
void updateShape();
@ -312,6 +325,8 @@ class Client : public TQObject, public KDecorationDefines
void autoRaise();
void shadeHover();
void shortcutActivated();
void updateOpacityCache();
private:
friend class Bridge; // FRAME
@ -348,12 +363,29 @@ class Client : public TQObject, public KDecorationDefines
bool buttonReleaseEvent( Window w, int button, int state, int x, int y, int x_root, int y_root );
bool motionNotifyEvent( Window w, int state, int x, int y, int x_root, int y_root );
// drop shadows
void drawIntersectingShadows();
void drawOverlappingShadows(bool waitForMe);
TQRegion getExposedRegion(TQRegion occludedRegion, int x, int y,
int w, int h, int thickness, int xOffset, int yOffset);
void imposeCachedShadow(TQPixmap &pixmap, TQRegion exposed);
void imposeRegionShadow(TQPixmap &pixmap, TQRegion occluded,
TQRegion exposed, int thickness, double maxOpacity = 0.75);
void processDecorationButtonPress( int button, int state, int x, int y, int x_root, int y_root );
private slots:
void pingTimeout();
void processKillerExited();
void demandAttentionKNotify();
void drawShadow();
void drawShadowAfter(Client *after);
void drawDelayedShadow();
void removeShadow();
signals:
void shadowDrawn();
private:
// ICCCM 4.1.3.1, 4.1.4 , NETWM 2.5.1
@ -531,6 +563,16 @@ class Client : public TQObject, public KDecorationDefines
bool pending_geometry_update;
bool shade_geometry_change;
int border_left, border_right, border_top, border_bottom;
Client* shadowAfterClient;
TQWidget* shadowWidget;
TQMemArray<double> activeOpacityCache;
TQMemArray<double> inactiveOpacityCache;
TQMemArray<double>* opacityCache;
TQRegion shapeBoundingRegion;
TQTimer* shadowDelayTimer;
bool shadowMe;
TQRegion _mask;
static bool check_active_modal; // see Client::checkActiveModal()
KShortcut _shortcut;
@ -880,6 +922,16 @@ inline void Client::plainResize( const TQSize& s, ForceGeometry_t force )
plainResize( s.width(), s.height(), force );
}
inline bool Client::isShadowed() const
{
return shadowMe;
}
inline Window Client::shadowId() const
{
return shadowWidget != NULL ? shadowWidget->winId() : None;
}
inline void Client::resizeWithChecks( const TQSize& s, ForceGeometry_t force )
{
resizeWithChecks( s.width(), s.height(), force );

@ -1078,6 +1078,217 @@ int qtToX11State( Qt::ButtonState state )
// for the decoration window cannot be (easily) intercepted as X11 events
bool Client::eventFilter( TQObject* o, TQEvent* e )
{
if (o == shadowWidget)
{
if (e->type() == TQEvent::MouseButtonRelease)
{
int buttonMask, buttonPressed, x, y, x_root, y_root;
unsigned int mask;
TQMouseEvent *qe = (TQMouseEvent *)e;
Window inner_window, parent_window, pointer_window, root_window;
XButtonEvent xe;
removeShadow();
switch (qe->button())
{
case Qt::MidButton:
buttonMask = Button2Mask;
buttonPressed = Button2;
break;
case Qt::RightButton:
buttonMask = Button3Mask;
buttonPressed = Button3;
break;
default:
buttonMask = Button1Mask;
buttonPressed = Button1;
break;
}
// find the window under the cursor that should receive the
// simulated events
root_window = qt_xrootwin();
XQueryPointer(qt_xdisplay(), root_window, &root_window,
&pointer_window, &x_root, &y_root, &x, &y, &mask);
if (pointer_window != None)
{
// Save the child window immediately under the window
// decoration, if any. This is so that we can send an event to
// the immediate descendant of a window's window decoration,
// which causes KWin to refocus windows properly
parent_window = pointer_window;
XQueryPointer(qt_xdisplay(), parent_window, &root_window,
&pointer_window, &x_root, &y_root, &x, &y, &mask);
inner_window = pointer_window;
while (pointer_window != None)
{
// Recursively query for the child window under the pointer,
// using the returned child window as the parent window for
// the subsequent query. When no child window is left, we've
// found the child that will receive the simulated event
parent_window = pointer_window;
XQueryPointer(qt_xdisplay(), parent_window, &root_window,
&pointer_window, &x_root, &y_root, &x, &y, &mask);
}
pointer_window = parent_window;
}
else
inner_window = None;
// simulate a mouse button press
xe.type = ButtonPress;
xe.display = qt_xdisplay();
xe.root = qt_xrootwin();
xe.subwindow = None;
xe.time = CurrentTime;
xe.x = x;
xe.y = y;
xe.x_root = x_root;
xe.y_root = y_root;
xe.state = 0;
xe.button = buttonPressed;
xe.same_screen = True;
if (inner_window != None && inner_window != pointer_window)
{
xe.window = inner_window;
XSendEvent(qt_xdisplay(), inner_window, True, ButtonPressMask,
(XEvent *)&xe);
}
xe.window = pointer_window;
XSendEvent(qt_xdisplay(), pointer_window, True, ButtonPressMask,
(XEvent *)&xe);
// simulate a mouse button release
xe.type = ButtonRelease;
xe.display = qt_xdisplay();
xe.root = qt_xrootwin();
xe.subwindow = None;
xe.time = CurrentTime;
xe.x = x;
xe.y = y;
xe.x_root = x_root;
xe.y_root = y_root;
xe.state = buttonMask;
xe.button = buttonPressed;
xe.same_screen = True;
if (inner_window != None && inner_window != pointer_window)
{
xe.window = inner_window;
XSendEvent(qt_xdisplay(), inner_window, True, ButtonReleaseMask,
(XEvent *)&xe);
}
xe.window = pointer_window;
XSendEvent(qt_xdisplay(), pointer_window, True, ButtonReleaseMask,
(XEvent *)&xe);
drawDelayedShadow();
return true;
}
else if (e->type() == TQEvent::Wheel)
{
int x, y, x_root, y_root;
unsigned int buttonMask, buttonPressed, mask;
TQWheelEvent *wheelEvent = (TQWheelEvent *)e;
Window inner_window, parent_window, pointer_window,
root_window;
XButtonEvent xe;
removeShadow();
// state and button parameters passed to XSendEvent depend on the
// direction in which the mouse wheel was rolled
buttonMask = wheelEvent->delta() > 0 ? Button4Mask : Button5Mask;
buttonPressed = wheelEvent->delta() > 0 ? Button4 : Button5;
// find the window under the cursor that should receive the
// simulated events
root_window = qt_xrootwin();
XQueryPointer(qt_xdisplay(), root_window, &root_window,
&pointer_window, &x_root, &y_root, &x, &y, &mask);
if (pointer_window != None)
{
// Save the child window immediately under the window
// decoration, if any. This is so that we can send an event to
// the immediate descendant of a window's window decoration,
// which causes KWin to refocus windows properly
parent_window = pointer_window;
XQueryPointer(qt_xdisplay(), parent_window, &root_window,
&pointer_window, &x_root, &y_root, &x, &y, &mask);
inner_window = pointer_window;
while (pointer_window != None)
{
// Recursively query for the child window under the pointer,
// using the returned child window as the parent window for
// the subsequent query. When no child window is left, we've
// found the child that will receive the simulated event
parent_window = pointer_window;
XQueryPointer(qt_xdisplay(), parent_window, &root_window,
&pointer_window, &x_root, &y_root, &x, &y, &mask);
}
pointer_window = parent_window;
}
else
inner_window = None;
// simulate a mouse button press
xe.type = ButtonPress;
xe.display = qt_xdisplay();
xe.root = qt_xrootwin();
xe.subwindow = None;
xe.time = CurrentTime;
xe.x = x;
xe.y = y;
xe.x_root = x_root;
xe.y_root = y_root;
xe.state = 0;
xe.same_screen = True;
if (inner_window != None && inner_window != pointer_window)
{
xe.button = buttonPressed;
xe.window = inner_window;
XSendEvent(qt_xdisplay(), inner_window, True, ButtonPressMask,
(XEvent *)&xe);
}
xe.button = buttonPressed;
xe.window = pointer_window;
XSendEvent(qt_xdisplay(), pointer_window, True, ButtonPressMask,
(XEvent *)&xe);
// simulate a mouse button release
xe.type = ButtonRelease;
xe.display = qt_xdisplay();
xe.root = qt_xrootwin();
xe.subwindow = None;
xe.time = CurrentTime;
xe.x = x;
xe.y = y;
xe.x_root = x_root;
xe.y_root = y_root;
xe.same_screen = True;
if (inner_window != None && inner_window != pointer_window)
{
xe.window = inner_window;
xe.state = buttonMask;
xe.button = buttonPressed;
XSendEvent(qt_xdisplay(), inner_window, True, ButtonReleaseMask,
(XEvent *)&xe);
}
xe.state = buttonMask;
xe.button = buttonPressed;
xe.window = pointer_window;
XSendEvent(qt_xdisplay(), pointer_window, True, ButtonReleaseMask,
(XEvent *)&xe);
drawDelayedShadow();
return true;
}
}
if( decoration == NULL
|| o != decoration->widget())
return false;

@ -1063,6 +1063,15 @@ void Client::checkDirection( int new_diff, int old_diff, TQRect& rect, const TQR
rect.moveLeft( area.right() - 5 );
}
}
if (!moveResizeMode && options->shadowEnabled(isActive()))
{
// If the user is manually resizing, let Client::leaveMoveResize()
// decide when to redraw the shadow
removeShadow();
drawIntersectingShadows();
if (options->shadowEnabled(isActive()))
drawDelayedShadow();
}
}
/*!
@ -2322,6 +2331,7 @@ bool Client::startMoveResize()
}
if ( maximizeMode() != MaximizeRestore )
resetMaximize();
removeShadow();
moveResizeMode = true;
workspace()->setClientIsMoving(this);
initialMoveResizeGeom = moveResizeGeom = geometry();
@ -2390,6 +2400,11 @@ void Client::leaveMoveResize()
moveResizeMode = false;
delete eater;
eater = 0;
if (options->shadowEnabled(isActive()))
{
drawIntersectingShadows();
updateOpacityCache();
}
}
// This function checks if it actually makes sense to perform a restricted move/resize.

@ -28,6 +28,8 @@
*/
#include <assert.h>
#include <math.h>
#include <tqdir.h>
#include <tqfileinfo.h>
#include <tqlayout.h>
@ -39,8 +41,10 @@
#include <tqlabel.h>
#include <tqfile.h>
#include <tqslider.h>
#include <tqspinbox.h>
#include <kapplication.h>
#include <kcolorbutton.h>
#include <kcombobox.h>
#include <kdebug.h>
#include <kdesktopfile.h>
@ -153,6 +157,164 @@ KWinDecorationModule::KWinDecorationModule(TQWidget* parent, const char* name, c
preview->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Expanding);
tabWidget->setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Maximum);
// Page 3 (Window Shadows)
TQHBox *inactiveShadowColourHBox, *shadowColourHBox;
TQHBox *inactiveShadowOpacityHBox, *shadowOpacityHBox;
TQHBox *inactiveShadowXOffsetHBox, *shadowXOffsetHBox;
TQHBox *inactiveShadowYOffsetHBox, *shadowYOffsetHBox;
TQHBox *inactiveShadowThicknessHBox, *shadowThicknessHBox;
TQLabel *inactiveShadowColourLabel, *shadowColourLabel;
TQLabel *inactiveShadowOpacityLabel, *shadowOpacityLabel;
TQLabel *inactiveShadowXOffsetLabel, *shadowXOffsetLabel;
TQLabel *inactiveShadowYOffsetLabel, *shadowYOffsetLabel;
TQLabel *inactiveShadowThicknessLabel, *shadowThicknessLabel;
shadowPage = new TQVBox(tabWidget);
shadowPage->setSpacing(KDialog::spacingHint());
shadowPage->setMargin(KDialog::marginHint());
cbWindowShadow = new TQCheckBox(
i18n("&Draw a drop shadow under windows"), shadowPage);
TQWhatsThis::add(cbWindowShadow,
i18n("Enabling this checkbox will allow you to choose a kind of "
"drop shadow to draw under each window."));
activeShadowSettings = new TQGroupBox(1, Qt::Horizontal,
i18n("Active Window Shadow"), shadowPage);
inactiveShadowSettings = new TQGroupBox(1, Qt::Horizontal,
i18n("Inactive Window Shadows"), shadowPage);
whichShadowSettings = new TQGroupBox(3, Qt::Horizontal,
i18n("Draw Shadow Under Normal Windows And..."), shadowPage);
cbShadowDocks = new TQCheckBox(i18n("Docks and &panels"),
whichShadowSettings);
connect(cbShadowDocks, TQT_SIGNAL(toggled(bool)),
TQT_SLOT(slotSelectionChanged()));
cbShadowOverrides = new TQCheckBox(i18n("O&verride windows"),
whichShadowSettings);
connect(cbShadowOverrides, TQT_SIGNAL(toggled(bool)),
TQT_SLOT(slotSelectionChanged()));
cbShadowTopMenus = new TQCheckBox(i18n("&Top menu"),
whichShadowSettings);
connect(cbShadowTopMenus, TQT_SIGNAL(toggled(bool)),
TQT_SLOT(slotSelectionChanged()));
cbInactiveShadow = new TQCheckBox(
i18n("Draw shadow under &inactive windows"), inactiveShadowSettings);
connect(cbInactiveShadow, TQT_SIGNAL(toggled(bool)),
TQT_SLOT(slotSelectionChanged()));
shadowColourHBox = new TQHBox(activeShadowSettings);
shadowColourHBox->setSpacing(KDialog::spacingHint());
shadowColourLabel = new TQLabel(i18n("Colour:"), shadowColourHBox);
shadowColourButton = new KColorButton(shadowColourHBox);
connect(shadowColourButton, TQT_SIGNAL(changed(const TQColor &)), TQT_SLOT(slotSelectionChanged()));
inactiveShadowColourHBox = new TQHBox(inactiveShadowSettings);
inactiveShadowColourHBox->setSpacing(KDialog::spacingHint());
inactiveShadowColourLabel = new TQLabel(i18n("Colour:"), inactiveShadowColourHBox);
inactiveShadowColourButton = new KColorButton(inactiveShadowColourHBox);
connect(inactiveShadowColourButton, TQT_SIGNAL(changed(const TQColor &)), TQT_SLOT(slotSelectionChanged()));
shadowOpacityHBox = new TQHBox(activeShadowSettings);
shadowOpacityHBox->setSpacing(KDialog::spacingHint());
shadowOpacityLabel = new TQLabel(i18n("Maximum opacity:"), shadowOpacityHBox);
shadowOpacitySlider = new TQSlider(1, 100, 10, 50, Qt::Horizontal,
shadowOpacityHBox);
shadowOpacitySlider->setTickmarks(TQSlider::Below);
shadowOpacitySlider->setTickInterval(10);
shadowOpacitySpinBox = new TQSpinBox(1, 100, 1, shadowOpacityHBox);
shadowOpacitySpinBox->setSuffix(" %");
connect(shadowOpacitySlider, TQT_SIGNAL(valueChanged(int)), shadowOpacitySpinBox,
TQT_SLOT(setValue(int)));
connect(shadowOpacitySpinBox, TQT_SIGNAL(valueChanged(int)), shadowOpacitySlider,
TQT_SLOT(setValue(int)));
connect(shadowOpacitySlider, TQT_SIGNAL(valueChanged(int)),
TQT_SLOT(slotSelectionChanged()));
inactiveShadowOpacityHBox = new TQHBox(inactiveShadowSettings);
inactiveShadowOpacityHBox->setSpacing(KDialog::spacingHint());
inactiveShadowOpacityLabel = new TQLabel(i18n("Maximum opacity:"),
inactiveShadowOpacityHBox);
inactiveShadowOpacitySlider = new TQSlider(1, 100, 10, 50, Qt::Horizontal,
inactiveShadowOpacityHBox);
inactiveShadowOpacitySlider->setTickmarks(TQSlider::Below);
inactiveShadowOpacitySlider->setTickInterval(10);
inactiveShadowOpacitySpinBox = new TQSpinBox(1, 100, 1,
inactiveShadowOpacityHBox);
inactiveShadowOpacitySpinBox->setSuffix(" %");
connect(inactiveShadowOpacitySlider, TQT_SIGNAL(valueChanged(int)),
inactiveShadowOpacitySpinBox,
TQT_SLOT(setValue(int)));
connect(inactiveShadowOpacitySpinBox, TQT_SIGNAL(valueChanged(int)),
inactiveShadowOpacitySlider,
TQT_SLOT(setValue(int)));
connect(inactiveShadowOpacitySlider, TQT_SIGNAL(valueChanged(int)),
TQT_SLOT(slotSelectionChanged()));
shadowXOffsetHBox = new TQHBox(activeShadowSettings);
shadowXOffsetHBox->setSpacing(KDialog::spacingHint());
shadowXOffsetLabel = new TQLabel(
i18n("Offset rightward (may be negative):"),
shadowXOffsetHBox);
shadowXOffsetSpinBox = new TQSpinBox(-1024, 1024, 1, shadowXOffsetHBox);
shadowXOffsetSpinBox->setSuffix(i18n(" pixels"));
connect(shadowXOffsetSpinBox, TQT_SIGNAL(valueChanged(int)),
TQT_SLOT(slotSelectionChanged()));
inactiveShadowXOffsetHBox = new TQHBox(inactiveShadowSettings);
inactiveShadowXOffsetHBox->setSpacing(KDialog::spacingHint());
inactiveShadowXOffsetLabel = new TQLabel(
i18n("Offset rightward (may be negative):"),
inactiveShadowXOffsetHBox);
inactiveShadowXOffsetSpinBox = new TQSpinBox(-1024, 1024, 1,
inactiveShadowXOffsetHBox);
inactiveShadowXOffsetSpinBox->setSuffix(i18n(" pixels"));
connect(inactiveShadowXOffsetSpinBox, TQT_SIGNAL(valueChanged(int)),
TQT_SLOT(slotSelectionChanged()));
shadowYOffsetHBox = new TQHBox(activeShadowSettings);
shadowYOffsetHBox->setSpacing(KDialog::spacingHint());
shadowYOffsetLabel = new TQLabel(
i18n("Offset downward (may be negative):"),
shadowYOffsetHBox);
shadowYOffsetSpinBox = new TQSpinBox(-1024, 1024, 1, shadowYOffsetHBox);
shadowYOffsetSpinBox->setSuffix(i18n(" pixels"));
connect(shadowYOffsetSpinBox, TQT_SIGNAL(valueChanged(int)),
TQT_SLOT(slotSelectionChanged()));
inactiveShadowYOffsetHBox = new TQHBox(inactiveShadowSettings);
inactiveShadowYOffsetHBox->setSpacing(KDialog::spacingHint());
inactiveShadowYOffsetLabel = new TQLabel(
i18n("Offset downward (may be negative):"),
inactiveShadowYOffsetHBox);
inactiveShadowYOffsetSpinBox = new TQSpinBox(-1024, 1024, 1,
inactiveShadowYOffsetHBox);
inactiveShadowYOffsetSpinBox->setSuffix(i18n(" pixels"));
connect(inactiveShadowYOffsetSpinBox, TQT_SIGNAL(valueChanged(int)),
TQT_SLOT(slotSelectionChanged()));
shadowThicknessHBox = new TQHBox(activeShadowSettings);
shadowThicknessHBox->setSpacing(KDialog::spacingHint());
shadowThicknessLabel = new TQLabel(
i18n("Thickness to either side of window:"),
shadowThicknessHBox);
shadowThicknessSpinBox = new TQSpinBox(1, 100, 1,
shadowThicknessHBox);
shadowThicknessSpinBox->setSuffix(i18n(" pixels"));
connect(shadowThicknessSpinBox, TQT_SIGNAL(valueChanged(int)),
TQT_SLOT(slotSelectionChanged()));
inactiveShadowThicknessHBox = new TQHBox(inactiveShadowSettings);
inactiveShadowThicknessHBox->setSpacing(KDialog::spacingHint());
inactiveShadowThicknessLabel = new TQLabel(
i18n("Thickness to either side of window:"),
inactiveShadowThicknessHBox);
inactiveShadowThicknessSpinBox = new TQSpinBox(1, 100, 1,
inactiveShadowThicknessHBox);
inactiveShadowThicknessSpinBox->setSuffix(i18n(" pixels"));
connect(inactiveShadowThicknessSpinBox, TQT_SIGNAL(valueChanged(int)),
TQT_SLOT(slotSelectionChanged()));
// Load all installed decorations into memory
// Set up the decoration lists and other UI settings
findDecorations();
@ -162,6 +324,7 @@ KWinDecorationModule::KWinDecorationModule(TQWidget* parent, const char* name, c
tabWidget->insertTab( pluginPage, i18n("&Window Decoration") );
tabWidget->insertTab( buttonPage, i18n("&Buttons") );
tabWidget->insertTab( shadowPage, i18n("&Shadows") );
connect( buttonPositionWidget, TQT_SIGNAL(changed()), this, TQT_SLOT(slotButtonsChanged()) ); // update preview etc.
connect( buttonPositionWidget, TQT_SIGNAL(changed()), this, TQT_SLOT(slotSelectionChanged()) ); // emit changed()...
@ -171,7 +334,12 @@ KWinDecorationModule::KWinDecorationModule(TQWidget* parent, const char* name, c
connect( cbUseCustomButtonPositions, TQT_SIGNAL(clicked()), TQT_SLOT(slotSelectionChanged()) );
connect(cbUseCustomButtonPositions, TQT_SIGNAL(toggled(bool)), buttonPositionWidget, TQT_SLOT(setEnabled(bool)));
connect(cbUseCustomButtonPositions, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotButtonsChanged()) );
connect(cbWindowShadow, TQT_SIGNAL(toggled(bool)), activeShadowSettings, TQT_SLOT(setEnabled(bool)));
connect(cbWindowShadow, TQT_SIGNAL(toggled(bool)), inactiveShadowSettings, TQT_SLOT(setEnabled(bool)));
connect(cbWindowShadow, TQT_SIGNAL(toggled(bool)), whichShadowSettings, TQT_SLOT(setEnabled(bool)));
connect( cbShowToolTips, TQT_SIGNAL(clicked()), TQT_SLOT(slotSelectionChanged()) );
connect( cbWindowShadow, TQT_SIGNAL(clicked()), TQT_SLOT(slotSelectionChanged()) );
connect( cBorder, TQT_SIGNAL( activated( int )), TQT_SLOT( slotBorderChanged( int )));
// connect( cbUseMiniWindows, TQT_SIGNAL(clicked()), TQT_SLOT(slotSelectionChanged()) );
@ -465,6 +633,28 @@ void KWinDecorationModule::readConfig( KConfig* conf )
border_size = BorderNormal;
checkSupportedBorderSizes();
// Shadows tab
// ===========
bool shadowEnabled = conf->readBoolEntry("ShadowEnabled", false);
cbWindowShadow->setChecked(shadowEnabled);
activeShadowSettings->setEnabled(shadowEnabled);
inactiveShadowSettings->setEnabled(shadowEnabled);
whichShadowSettings->setEnabled(shadowEnabled);
shadowColourButton->setColor(conf->readColorEntry("ShadowColour", &Qt::black));
shadowOpacitySlider->setValue((int)ceil(conf->readDoubleNumEntry("ShadowOpacity", 0.70) * 100));
shadowXOffsetSpinBox->setValue(conf->readNumEntry("ShadowXOffset", 0));
shadowYOffsetSpinBox->setValue(conf->readNumEntry("ShadowYOffset", 10));
cbShadowDocks->setChecked(conf->readBoolEntry("ShadowDocks", false));
cbShadowOverrides->setChecked(conf->readBoolEntry("ShadowOverrides", false));
cbShadowTopMenus->setChecked(conf->readBoolEntry("ShadowTopMenus", false));
shadowThicknessSpinBox->setValue(conf->readNumEntry("ShadowThickness", 10));
cbInactiveShadow->setChecked(conf->readBoolEntry("InactiveShadowEnabled", false));
inactiveShadowColourButton->setColor(conf->readColorEntry("InactiveShadowColour", &Qt::black));
inactiveShadowOpacitySlider->setValue((int)ceil(conf->readDoubleNumEntry("InactiveShadowOpacity", 0.70) * 100));
inactiveShadowXOffsetSpinBox->setValue(conf->readNumEntry("InactiveShadowXOffset", 0));
inactiveShadowYOffsetSpinBox->setValue(conf->readNumEntry("InactiveShadowYOffset", 5));
inactiveShadowThicknessSpinBox->setValue(conf->readNumEntry("InactiveShadowThickness", 5));
emit KCModule::changed(false);
}
@ -489,6 +679,27 @@ void KWinDecorationModule::writeConfig( KConfig* conf )
conf->writeEntry("ButtonsOnRight", buttonPositionWidget->buttonsRight() );
conf->writeEntry("BorderSize", border_size );
// Shadow settings
conf->writeEntry("ShadowEnabled", cbWindowShadow->isChecked());
conf->writeEntry("ShadowColour", shadowColourButton->color());
conf->writeEntry("ShadowOpacity", shadowOpacitySlider->value() / 100.0);
conf->writeEntry("ShadowXOffset", shadowXOffsetSpinBox->value());
conf->writeEntry("ShadowYOffset", shadowYOffsetSpinBox->value());
conf->writeEntry("ShadowThickness", shadowThicknessSpinBox->value());
conf->writeEntry("ShadowDocks", cbShadowDocks->isChecked());
conf->writeEntry("ShadowOverrides", cbShadowOverrides->isChecked());
conf->writeEntry("ShadowTopMenus", cbShadowTopMenus->isChecked());
conf->writeEntry("InactiveShadowEnabled", cbInactiveShadow->isChecked());
conf->writeEntry("InactiveShadowColour", inactiveShadowColourButton->color());
conf->writeEntry("InactiveShadowOpacity",
inactiveShadowOpacitySlider->value() / 100.0);
conf->writeEntry("InactiveShadowXOffset",
inactiveShadowXOffsetSpinBox->value());
conf->writeEntry("InactiveShadowYOffset",
inactiveShadowYOffsetSpinBox->value());
conf->writeEntry("InactiveShadowThickness",
inactiveShadowThicknessSpinBox->value());
oldLibraryName = currentLibraryName;
currentLibraryName = libName;
@ -541,6 +752,7 @@ void KWinDecorationModule::defaults()
cbUseCustomButtonPositions->setChecked( false );
buttonPositionWidget->setEnabled( false );
cbShowToolTips->setChecked( true );
cbWindowShadow->setChecked( false );
// cbUseMiniWindows->setChecked( false);
// Don't set default for now
// decorationList->setSelected(
@ -552,6 +764,21 @@ void KWinDecorationModule::defaults()
border_size = BorderNormal;
checkSupportedBorderSizes();
shadowColourButton->setColor(Qt::black);
shadowOpacitySlider->setValue(70);
shadowXOffsetSpinBox->setValue(0);
shadowYOffsetSpinBox->setValue(10);
shadowThicknessSpinBox->setValue(10);
cbShadowDocks->setChecked(false);
cbShadowOverrides->setChecked(false);
cbShadowTopMenus->setChecked(false);
cbInactiveShadow->setChecked(false);
inactiveShadowColourButton->setColor(Qt::black);
inactiveShadowOpacitySlider->setValue(70);
inactiveShadowXOffsetSpinBox->setValue(0);
inactiveShadowYOffsetSpinBox->setValue(5);
inactiveShadowThicknessSpinBox->setValue(5);
// Set plugin defaults
emit pluginDefaults();
}

@ -127,6 +127,19 @@ class KWinDecorationModule : public KCModule, virtual public KWinDecorationIface
// Page 2
ButtonPositionWidget *buttonPositionWidget;
TQVBox* buttonPage;
// Page 3
TQVBox *shadowPage;
KColorButton *inactiveShadowColourButton, *shadowColourButton;
TQCheckBox *cbShadowDocks, *cbShadowOverrides, *cbShadowTopMenus;
TQCheckBox *cbInactiveShadow, *cbWindowShadow;
TQGroupBox *activeShadowSettings, *inactiveShadowSettings;
TQGroupBox *whichShadowSettings;
TQSlider *inactiveShadowOpacitySlider, *shadowOpacitySlider;
TQSpinBox *inactiveShadowOpacitySpinBox, *shadowOpacitySpinBox;
TQSpinBox *inactiveShadowXOffsetSpinBox, *shadowXOffsetSpinBox;
TQSpinBox *inactiveShadowYOffsetSpinBox, *shadowYOffsetSpinBox;
TQSpinBox *inactiveShadowThicknessSpinBox, *shadowThicknessSpinBox;
};

@ -134,37 +134,89 @@ void Workspace::propagateClients( bool propagate_new_clients )
// when passig pointers around.
// restack the windows according to the stacking order
#if 0
Window* new_stack = new Window[ stacking_order.count() + 2 ];
int pos = 0;
#endif
NET::WindowType t;
Window shadow;
Window *dock_shadow_stack, *window_stack;
int i, numDocks, pos, topmenu_space_pos;
dock_shadow_stack = new Window[ stacking_order.count() * 2 ];
window_stack = new Window[ stacking_order.count() * 2 + 2 ];
i = 0;
pos = 0;
topmenu_space_pos = 1; // not 0, that's supportWindow !!!
// Stack all windows under the support window. The support window is
// not used for anything (besides the NETWM property), and it's not shown,
// but it was lowered after kwin startup. Stacking all clients below
// it ensures that no client will be ever shown above override-redirect
// windows (e.g. popups).
#if 0
new_stack[ pos++ ] = supportWindow->winId();
int topmenu_space_pos = 1; // not 0, that's supportWindow !!!
#endif
window_stack[pos++] = supportWindow->winId();
for( ClientList::ConstIterator it = stacking_order.fromLast();
it != stacking_order.end();
--it )
{
#if 0
new_stack[ pos++ ] = (*it)->frameId();
if( (*it)->belongsToLayer() >= DockLayer )
topmenu_space_pos = pos;
}
#endif
t = (*it)->windowType();
switch (t)
{
case NET::Dock:
window_stack[pos++] = (*it)->frameId();
if ((shadow = (*it)->shadowId()) != None)
dock_shadow_stack[i++] = shadow;
break;
case NET::Desktop:
numDocks = i;
for (i = 0; i < numDocks; i++)
// Shadows for dock windows go just above the desktop
window_stack[pos++] = dock_shadow_stack[i];
window_stack[pos++] = (*it)->frameId();
break;
case NET::TopMenu:
topmenu_space_pos = pos;
// fall through
default:
window_stack[pos++] = (*it)->frameId();
if ((shadow = (*it)->shadowId()) != None)
// If the current window also has a shadow, place it
// immediately under the current window
window_stack[pos++] = shadow;
}
}
if( topmenu_space != NULL )
{ // make sure the topmenu space is below all topmenus, fullscreens, etc.
for( int i = pos;
i > topmenu_space_pos;
--i )
#if 0
new_stack[ i ] = new_stack[ i - 1 ];
new_stack[ topmenu_space_pos ] = topmenu_space->winId();
#endif
window_stack[ i ] = window_stack[ i - 1 ];
window_stack[ topmenu_space_pos ] = topmenu_space->winId();
++pos;
}
// TODO isn't it too inefficient to restart always all clients?
// TODO don't restack not visible windows?
assert( new_stack[ 0 ] = supportWindow->winId());
#if 0
XRestackWindows(qt_xdisplay(), new_stack, pos);
delete [] new_stack;
#endif
XRestackWindows(qt_xdisplay(), window_stack, pos);
delete [] dock_shadow_stack;
delete [] window_stack;
if ( propagate_new_clients )
{
@ -342,6 +394,11 @@ void Workspace::raiseClient( Client* c )
unconstrained_stacking_order.remove( c );
unconstrained_stacking_order.append( c );
if (options->shadowEnabled(c->isActive()))
{
c->removeShadow();
c->drawDelayedShadow();
}
if( !c->isSpecialWindow())
{

@ -97,6 +97,7 @@ public:
LowerOp,
FullScreenOp,
NoBorderOp,
ShadowOp,
NoOp,
SetupWindowShortcutOp,
ApplicationRulesOp ///< @since 3.5
@ -116,7 +117,7 @@ public:
ColorHandle, ///< The color for the resize handle
NUM_COLORS
};
/**
* These flags specify which settings changed when rereading settings.
* Each setting in class KDecorationOptions specifies its matching flag.
@ -130,7 +131,7 @@ public:
SettingTooltips = 1 << 4, ///< The tooltip setting was changed
SettingBorder = 1 << 5 ///< The border size setting was changed
};
/**
* Border size. KDecorationOptions::preferredBorderSize() returns
* one of these values.
@ -261,7 +262,7 @@ public:
* The changed flags for this setting is SettingTooltips.
*/
bool showTooltips() const;
/**
* The preferred border size selected by the user, e.g. for accessibility
* reasons, or when using high resolution displays. It's up to the decoration
@ -322,9 +323,9 @@ class KWIN_EXPORT KDecoration
* Destroys the KDecoration.
*/
virtual ~KDecoration();
// requests from decoration
/**
* Returns the KDecorationOptions object, which is used to access
* configuration settings for the decoration.
@ -417,7 +418,7 @@ class KWIN_EXPORT KDecoration
* to support older code). For a description of all window types,
* see the definition of the NET::WindowType type. Note that
* some window types never have decorated windows.
*
*
* An example of usage:
* @code
* const unsigned long supported_types = NET::NormalMask | NET::DesktopMask
@ -671,7 +672,7 @@ class KWIN_EXPORT KDecoration
/**
* This function is called to reset the decoration on settings changes.
* It is usually invoked by calling KDecorationFactory::resetDecorations().
*
*
* @param changed Specifies which settings were changed, given by the SettingXXX masks
*/
virtual void reset( unsigned long changed );

@ -372,6 +372,7 @@ bool Client::manage( Window w, bool isMapped )
setSkipTaskbar( session->skipTaskbar, true );
setSkipPager( session->skipPager );
setShade( session->shaded ? ShadeNormal : ShadeNone );
setShadowed( session->shadowed );
if( session->maximized != MaximizeRestore )
{
maximize( (MaximizeMode) session->maximized );

@ -193,7 +193,24 @@ unsigned long Options::updateSettings()
if (resetKompmgr)
config->writeEntry("ResetKompmgr",FALSE);
// window drop shadows
config->setGroup("Style");
shadow_colour = config->readColorEntry("ShadowColour", &Qt::black);
shadow_docks = config->readBoolEntry("ShadowDocks", false);
shadow_overrides = config->readBoolEntry("ShadowOverrides", false);
shadow_topMenus = config->readBoolEntry("ShadowTopMenus", false);
shadow_inactive_colour = config->readColorEntry("InactiveShadowColour", &Qt::black);
shadow_inactive_enabled = config->readBoolEntry("InactiveShadowEnabled", false);
shadow_inactive_opacity = config->readDoubleNumEntry("InactiveShadowOpacity", 0.70);
shadow_inactive_thickness = config->readNumEntry("InactiveShadowThickness", 5);
shadow_inactive_x_offset = config->readNumEntry("InactiveShadowXOffset", 0);
shadow_inactive_y_offset = config->readNumEntry("InactiveShadowYOffset", 5);
shadow_enabled = config->readBoolEntry("ShadowEnabled", false);
shadow_opacity = config->readDoubleNumEntry("ShadowOpacity", 0.70);
shadow_thickness = config->readNumEntry("ShadowThickness", 10);
shadow_x_offset = config->readNumEntry("ShadowXOffset", 0);
shadow_y_offset = config->readNumEntry("ShadowYOffset", 10);
// Read button tooltip animation effect from kdeglobals
// Since we want to allow users to enable window decoration tooltips
@ -243,6 +260,8 @@ Options::WindowOperation Options::windowOperation(const TQString &name, bool res
return HMaximizeOp;
else if (name == "Lower")
return LowerOp;
else if (name == "Shadow")
return ShadowOp;
return NoOp;
}
@ -285,6 +304,69 @@ bool Options::showGeometryTip()
return show_geometry_tip;
}
TQColor &Options::shadowColour(bool active)
{
return active ? shadow_colour : shadow_inactive_colour;
}
bool Options::shadowWindowType(NET::WindowType t)
{
bool retval;
switch (t)
{
case NET::Dialog:
case NET::Normal:
retval = true;
break;
case NET::Desktop:
case NET::Menu:
case NET::Toolbar:
retval = false;
break;
case NET::Dock:
retval = shadow_docks;
break;
case NET::Override:
retval = shadow_overrides;
break;
case NET::TopMenu:
retval = shadow_topMenus;
break;
default:
retval = false;
break;
}
return retval;
}
bool Options::shadowEnabled(bool active)
{
return active ? shadow_enabled :
(shadow_enabled && shadow_inactive_enabled);
}
double Options::shadowOpacity(bool active)
{
return active ? shadow_opacity : shadow_inactive_opacity;
}
int Options::shadowThickness(bool active)
{
return active ? shadow_thickness : shadow_inactive_thickness;
}
int Options::shadowXOffset(bool active)
{
return active ? shadow_x_offset : shadow_inactive_x_offset;
}
int Options::shadowYOffset(bool active)
{
return active ? shadow_y_offset : shadow_inactive_y_offset;
}
int Options::electricBorders()
{
return electric_borders;

@ -268,6 +268,45 @@ class Options : public KDecorationOptions
*/
bool showGeometryTip();
/**
* @returns A TQColor representing the colour that window drop shadows should
* be.
*/
TQColor &shadowColour(bool active=true);
/**
* @returns true if shadows should be drawn around windows of the
* specified type
*/
bool shadowWindowType(NET::WindowType t);
/**
* @returns true if window shadows should be drawn
*/
bool shadowEnabled(bool active=true);
/**
* @returns Window shadow's opacity between 0.01 and 1.00.
*/
double shadowOpacity(bool active=true);
/**
* @returns How thick a shadow should be to either side of of a window.
*/
int shadowThickness(bool active=true);
/**
* @returns Number of pixels along the X-axis by which to offset window
* shadows.
*/
int shadowXOffset(bool active=true);
/**
* @returns Number of pixels along the Y-axis by which to offset window
* shadows.
*/
int shadowYOffset(bool active=true);
enum { ElectricDisabled = 0, ElectricMoveOnly = 1, ElectricAlways = 2 };
/**
* @returns true if electric borders are enabled. With electric borders
@ -336,6 +375,21 @@ class Options : public KDecorationOptions
bool show_geometry_tip;
bool topmenus;
bool desktop_topmenu;
TQColor shadow_colour;
TQColor shadow_inactive_colour;
bool shadow_docks;
bool shadow_overrides;
bool shadow_topMenus;
bool shadow_inactive_enabled;
bool shadow_enabled;
double shadow_inactive_opacity;
double shadow_opacity;
int shadow_inactive_thickness;
int shadow_thickness;
int shadow_inactive_x_offset;
int shadow_x_offset;
int shadow_inactive_y_offset;
int shadow_y_offset;
// List of window classes for which not to use focus stealing prevention
TQStringList ignoreFocusStealingClasses;

@ -106,6 +106,7 @@ void Workspace::storeSession( KConfig* config, SMSavePhase phase )
// the config entry is called "sticky" for back. comp. reasons
config->writeEntry( TQString("sticky")+n, c->isOnAllDesktops() );
config->writeEntry( TQString("shaded")+n, c->isShade() );
config->writeEntry( TQString("shadowed")+n, c->isShadowed() );
// the config entry is called "staysOnTop" for back. comp. reasons
config->writeEntry( TQString("staysOnTop")+n, c->keepAbove() );
config->writeEntry( TQString("keepBelow")+n, c->keepBelow() );
@ -172,6 +173,7 @@ void Workspace::loadSessionInfo()
info->minimized = config->readBoolEntry( TQString("iconified")+n, FALSE );
info->onAllDesktops = config->readBoolEntry( TQString("sticky")+n, FALSE );
info->shaded = config->readBoolEntry( TQString("shaded")+n, FALSE );
info->shadowed = config->readBoolEntry( TQString("shadowed")+n, TRUE );
info->keepAbove = config->readBoolEntry( TQString("staysOnTop")+n, FALSE );
info->keepBelow = config->readBoolEntry( TQString("keepBelow")+n, FALSE );
info->skipTaskbar = config->readBoolEntry( TQString("skipTaskbar")+n, FALSE );

@ -39,6 +39,7 @@ struct SessionInfo
bool minimized;
bool onAllDesktops;
bool shaded;
bool shadowed;
bool keepAbove;
bool keepBelow;
bool skipTaskbar;

@ -65,6 +65,7 @@ TQPopupMenu* Workspace::clientPopup()
advanced_popup->insertItem( SmallIconSet( "window_fullscreen" ),
i18n("&Fullscreen")+'\t'+keys->shortcut("Window Fullscreen").seq(0).toString(), Options::FullScreenOp );
advanced_popup->insertItem( i18n("&No Border")+'\t'+keys->shortcut("Window No Border").seq(0).toString(), Options::NoBorderOp );
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 );
advanced_popup->insertItem( SmallIconSet( "wizard" ), i18n("&Special Window Settings..."), Options::WindowRulesOp );
@ -172,6 +173,10 @@ void Workspace::clientPopupAboutToShow()
advanced_popup->setItemEnabled( Options::FullScreenOp, active_popup_client->userCanSetFullScreen() );
advanced_popup->setItemChecked( Options::NoBorderOp, active_popup_client->noBorder() );
advanced_popup->setItemEnabled( Options::NoBorderOp, active_popup_client->userCanSetNoBorder() );
advanced_popup->setItemEnabled( Options::ShadowOp, (options->shadowWindowType(active_popup_client->windowType()) && options->shadowEnabled(active_popup_client->isActive())) );
advanced_popup->setItemChecked( Options::ShadowOp, active_popup_client->isShadowed() );
popup->setItemEnabled( Options::MinimizeOp, active_popup_client->isMinimizable() );
popup->setItemEnabled( Options::CloseOp, active_popup_client->isCloseable() );
if (options->useTranslucency)
@ -398,6 +403,9 @@ void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
case Options::ShadeOp:
c->performMouseCommand( Options::MouseShade, TQCursor::pos());
break;
case Options::ShadowOp:
c->setShadowed( !c->isShadowed() );
break;
case Options::OnAllDesktopsOp:
c->setOnAllDesktops( !c->isOnAllDesktops() );
break;

@ -90,6 +90,7 @@ Workspace::Workspace( bool restore )
rules_updates_disabled( false ),
active_client (0),
last_active_client (0),
next_active_client (0),
most_recently_raised (0),
movingClient(0),
pending_take_activity ( NULL ),
@ -699,6 +700,24 @@ void Workspace::updateFocusChains( Client* c, FocusChainChange change )
}
}
void Workspace::updateOverlappingShadows(unsigned long window)
{
Client *client;
if ((client = findClient(WindowMatchPredicate((WId)window))))
// Redraw overlapping shadows without waiting for the specified window
// to redraw its own shadow
client->drawOverlappingShadows(false);
}
void Workspace::setShadowed(unsigned long window, bool shadowed)
{
Client *client;
if ((client = findClient(WindowMatchPredicate((WId)window))))
client->setShadowed(shadowed);
}
void Workspace::updateCurrentTopMenu()
{
if( !managingTopMenus())

@ -231,6 +231,8 @@ class Workspace : public TQObject, public KWinInterface, public KDecorationDefin
void unclutterDesktop();
void doNotManage(TQString);
bool setCurrentDesktop( int new_desktop );
void updateOverlappingShadows(WId window);
void setShadowed(WId window, bool shadowed);
void nextDesktop();
void previousDesktop();
void circulateDesktopApplications();
@ -518,6 +520,7 @@ class Workspace : public TQObject, public KWinInterface, public KDecorationDefin
Client* active_client;
Client* last_active_client;
Client* next_active_client; // will be active after active_client deactivates
Client* most_recently_raised; // used _only_ by raiseOrLowerClient()
Client* movingClient;
Client* pending_take_activity;
@ -704,7 +707,15 @@ inline bool Workspace::initializing() const
inline Client* Workspace::activeClient() const
{
return active_client;
// next_active_client is a kludge for drop shadows. If a window that is
// activated is not also raised (i.e. when focus follows mouse), then the
// newly activated window and its shadow won't cover visual artifacts that
// might exist in the inactive window's shadow. We work around this by
// (re)drawing the inactive window's shadow after the active window's shadow
// is drawn, but to do that the inactive window needs to know which window
// will become active next. next_active_client is a Client pointer for that
// purpose.
return next_active_client != NULL ? next_active_client : active_client;
}
inline Client* Workspace::mostRecentlyActivatedClient() const

Loading…
Cancel
Save