Kaydet (Commit) 557e52e8 authored tarafından Luboš Luňák's avatar Luboš Luňák

set window icon also as _NET_WM_ICON (fdo#71494)

The old X way of just using WMHints doesn't seem to work at least with KWin,
which just falls back to finding a matching application icon based on WM_CLASS.

Change-Id: Ia014eb106cd370da74099fa750968df87acbda81
üst 019c342c
...@@ -76,6 +76,7 @@ public: ...@@ -76,6 +76,7 @@ public:
NET_NUMBER_OF_DESKTOPS, NET_NUMBER_OF_DESKTOPS,
NET_CURRENT_DESKTOP, NET_CURRENT_DESKTOP,
NET_WORKAREA, NET_WORKAREA,
NET_WM_ICON,
// atoms for Gnome WM hints // atoms for Gnome WM hints
WIN_SUPPORTING_WM_CHECK, WIN_SUPPORTING_WM_CHECK,
......
...@@ -109,6 +109,7 @@ static const WMAdaptorProtocol aProtocolTab[] = ...@@ -109,6 +109,7 @@ static const WMAdaptorProtocol aProtocolTab[] =
{ "_NET_CURRENT_DESKTOP", WMAdaptor::NET_CURRENT_DESKTOP }, { "_NET_CURRENT_DESKTOP", WMAdaptor::NET_CURRENT_DESKTOP },
{ "_NET_NUMBER_OF_DESKTOPS", WMAdaptor::NET_NUMBER_OF_DESKTOPS }, { "_NET_NUMBER_OF_DESKTOPS", WMAdaptor::NET_NUMBER_OF_DESKTOPS },
{ "_NET_WM_DESKTOP", WMAdaptor::NET_WM_DESKTOP }, { "_NET_WM_DESKTOP", WMAdaptor::NET_WM_DESKTOP },
{ "_NET_WM_ICON", WMAdaptor::NET_WM_ICON },
{ "_NET_WM_ICON_NAME", WMAdaptor::NET_WM_ICON_NAME }, { "_NET_WM_ICON_NAME", WMAdaptor::NET_WM_ICON_NAME },
{ "_NET_WM_PING", WMAdaptor::NET_WM_PING }, { "_NET_WM_PING", WMAdaptor::NET_WM_PING },
{ "_NET_WM_STATE", WMAdaptor::NET_WM_STATE }, { "_NET_WM_STATE", WMAdaptor::NET_WM_STATE },
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "vcl/layout.hxx" #include "vcl/layout.hxx"
#include "vcl/printerinfomanager.hxx" #include "vcl/printerinfomanager.hxx"
#include "vcl/settings.hxx" #include "vcl/settings.hxx"
#include "vcl/bmpacc.hxx"
#include <prex.h> #include <prex.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
...@@ -193,13 +194,69 @@ void X11SalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode ) ...@@ -193,13 +194,69 @@ void X11SalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode )
GetGenericData()->ErrorTrapPop(); GetGenericData()->ErrorTrapPop();
} }
typedef std::vector< unsigned long > NetWmIconData;
static void CreateNetWmAppIcon( sal_uInt16 nIcon, NetWmIconData& netwm_icon )
{
const int sizes[ 3 ] = { 48, 32, 16 };
netwm_icon.resize( 48 * 48 + 32 * 32 + 16 * 16 + 3 * 2 );
int pos = 0;
for( int i = 0; i < 3; ++i )
{
int size = sizes[ i ];
sal_uInt16 nIconSizeOffset;
if( size >= 48 )
nIconSizeOffset = SV_ICON_SIZE48_START;
else if( size >= 32 )
nIconSizeOffset = SV_ICON_SIZE32_START;
else
nIconSizeOffset = SV_ICON_SIZE16_START;
BitmapEx aIcon( ResId(nIconSizeOffset + nIcon, *ImplGetResMgr()));
if( aIcon.IsEmpty())
continue;
Bitmap icon = aIcon.GetBitmap();
AlphaMask mask;
switch( aIcon.GetTransparentType())
{
case TRANSPARENT_NONE:
{
sal_uInt8 nTrans = 0;
mask = AlphaMask( icon.GetSizePixel(), &nTrans );
}
break;
case TRANSPARENT_COLOR:
mask = AlphaMask( icon.CreateMask( aIcon.GetTransparentColor() ) );
break;
case TRANSPARENT_BITMAP:
mask = aIcon.GetAlpha();
break;
}
BitmapReadAccess* iconData = icon.AcquireReadAccess();
BitmapReadAccess* maskData = mask.AcquireReadAccess();
netwm_icon[ pos++ ] = size; // width
netwm_icon[ pos++ ] = size; // height
for( int y = 0; y < size; ++y )
for( int x = 0; x < size; ++x )
{
BitmapColor col = iconData->GetColor( y, x );
BitmapColor alpha = maskData->GetColor( y, x );
netwm_icon[ pos++ ] = (((( 255 - alpha.GetBlue()) * 256U ) + col.GetRed()) * 256 + col.GetGreen()) * 256 + col.GetBlue();
}
icon.ReleaseAccess( iconData );
mask.ReleaseAccess( maskData );
}
netwm_icon.resize( pos );
}
static bool lcl_SelectAppIconPixmap( SalDisplay *pDisplay, SalX11Screen nXScreen, static bool lcl_SelectAppIconPixmap( SalDisplay *pDisplay, SalX11Screen nXScreen,
sal_uInt16 nIcon, sal_uInt16 iconSize, sal_uInt16 nIcon, sal_uInt16 iconSize,
Pixmap& icon_pixmap, Pixmap& icon_mask) Pixmap& icon_pixmap, Pixmap& icon_mask, NetWmIconData& netwm_icon)
{ {
if( ! ImplGetResMgr() ) if( ! ImplGetResMgr() )
return false; return false;
CreateNetWmAppIcon( nIcon, netwm_icon );
sal_uInt16 nIconSizeOffset; sal_uInt16 nIconSizeOffset;
if( iconSize >= 48 ) if( iconSize >= 48 )
...@@ -279,6 +336,7 @@ void X11SalFrame::Init( sal_uLong nSalFrameStyle, SalX11Screen nXScreen, SystemP ...@@ -279,6 +336,7 @@ void X11SalFrame::Init( sal_uLong nSalFrameStyle, SalX11Screen nXScreen, SystemP
XWMHints Hints; XWMHints Hints;
Hints.flags = InputHint; Hints.flags = InputHint;
Hints.input = (nSalFrameStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ? False : True; Hints.input = (nSalFrameStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ? False : True;
NetWmIconData netwm_icon;
int x = 0, y = 0; int x = 0, y = 0;
unsigned int w = 500, h = 500; unsigned int w = 500, h = 500;
...@@ -480,7 +538,7 @@ void X11SalFrame::Init( sal_uLong nSalFrameStyle, SalX11Screen nXScreen, SystemP ...@@ -480,7 +538,7 @@ void X11SalFrame::Init( sal_uLong nSalFrameStyle, SalX11Screen nXScreen, SystemP
bOk = lcl_SelectAppIconPixmap( pDisplay_, m_nXScreen, bOk = lcl_SelectAppIconPixmap( pDisplay_, m_nXScreen,
mnIconID != 1 ? mnIconID : mnIconID != 1 ? mnIconID :
(mpParent ? mpParent->mnIconID : 1), 32, (mpParent ? mpParent->mnIconID : 1), 32,
Hints.icon_pixmap, Hints.icon_mask ); Hints.icon_pixmap, Hints.icon_mask, netwm_icon );
} }
catch( com::sun::star::uno::Exception& ) catch( com::sun::star::uno::Exception& )
{ {
...@@ -679,6 +737,11 @@ void X11SalFrame::Init( sal_uLong nSalFrameStyle, SalX11Screen nXScreen, SystemP ...@@ -679,6 +737,11 @@ void X11SalFrame::Init( sal_uLong nSalFrameStyle, SalX11Screen nXScreen, SystemP
SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) ) SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) )
== SAL_FRAME_STYLE_DEFAULT ) == SAL_FRAME_STYLE_DEFAULT )
pDisplay_->getWMAdaptor()->maximizeFrame( this, true, true ); pDisplay_->getWMAdaptor()->maximizeFrame( this, true, true );
if( !netwm_icon.empty() && GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_ICON ))
XChangeProperty( GetXDisplay(), mhWindow,
GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_ICON ),
XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&netwm_icon.front(), netwm_icon.size());
} }
m_nWorkArea = GetDisplay()->getWMAdaptor()->getCurrentWorkArea(); m_nWorkArea = GetDisplay()->getWMAdaptor()->getCurrentWorkArea();
...@@ -1009,15 +1072,16 @@ void X11SalFrame::SetIcon( sal_uInt16 nIcon ) ...@@ -1009,15 +1072,16 @@ void X11SalFrame::SetIcon( sal_uInt16 nIcon )
} }
pHints = &Hints; pHints = &Hints;
NetWmIconData netwm_icon;
bool bOk = lcl_SelectAppIconPixmap( GetDisplay(), m_nXScreen, bool bOk = lcl_SelectAppIconPixmap( GetDisplay(), m_nXScreen,
nIcon, iconSize, nIcon, iconSize,
pHints->icon_pixmap, pHints->icon_mask ); pHints->icon_pixmap, pHints->icon_mask, netwm_icon );
if ( !bOk ) if ( !bOk )
{ {
// load default icon (0) // load default icon (0)
bOk = lcl_SelectAppIconPixmap( GetDisplay(), m_nXScreen, bOk = lcl_SelectAppIconPixmap( GetDisplay(), m_nXScreen,
0, iconSize, 0, iconSize,
pHints->icon_pixmap, pHints->icon_mask ); pHints->icon_pixmap, pHints->icon_mask, netwm_icon );
} }
if( bOk ) if( bOk )
{ {
...@@ -1026,6 +1090,10 @@ void X11SalFrame::SetIcon( sal_uInt16 nIcon ) ...@@ -1026,6 +1090,10 @@ void X11SalFrame::SetIcon( sal_uInt16 nIcon )
pHints->flags |= IconMaskHint; pHints->flags |= IconMaskHint;
XSetWMHints( GetXDisplay(), GetShellWindow(), pHints ); XSetWMHints( GetXDisplay(), GetShellWindow(), pHints );
if( !netwm_icon.empty() && GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_ICON ))
XChangeProperty( GetXDisplay(), mhWindow,
GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_ICON ),
XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&netwm_icon.front(), netwm_icon.size());
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment