new splashscreens "none" and "simple"
Lubos Lunak <[email protected]>
| Newsgroups | gmane.comp.kde.devel.optimize |
|---|---|
| Message-ID | <[email protected]> |
Hello, the attached patches reduce my KDE startup time 12s->11s (hot caches, 3xKonsole,Klipper). The time is basically saved by avoiding ksplash altogether. The first new "splashscreen" is the none splashscreen. It's the most efficient splashscreen possible ;), and it's kinda boring (reminds of KDE1.x). The "simple" splashscreen actually even is a splashscreen, coded completely in Xlib, so it's very efficient. And it's also very tedious to code, just in case you wonder why it's only black&white and no texts. Since it doesn't use dcop, it needs also patching kded, ksmserver, kwin, kicker and kdesktop to send X messages about the progress. One thing I'd need to check is that I added it properly to KSplashML. It works for me, but I'm not sure it did it the way it's supposed to be, KSplashML seems to be a bit complicated for being just a splashscreen. And BTW, I don't propose that either of these splashscreens becomes the default. Comments? -- Lubos Lunak KDE developer --------------------------------------------------------------------- SuSE CR, s.r.o. e-mail: [email protected] , [email protected] Drahobejlova 27 tel: +420 2 9654 2373 190 00 Praha 9 fax: +420 2 9654 2374 Czech Republic http://www.suse.cz/ _______________________________________________ Kde-optimize mailing list [email protected] https://mail.kde.org/mailman/listinfo/kde-optimize
ksplashml.patch
(text/x-diff, 11.3 KB)
--- ksplashml/pics/themes/simple/Theme.rc.sav 2004-09-14 12:34:31.243170432 +0200 +++ ksplashml/pics/themes/simple/Theme.rc 2004-09-14 12:36:32.000000000 +0200 @@ -0,0 +1,7 @@ +# Default KSplash/ML Theme + +[KSplash Theme: Simple] +Name = Simple Splash Screen +Description = Very Simple Optimized Splash Screen +Version = 1.0 +Author = Lubos Lunak <[email protected]> --- ksplashml/pics/themes/simple/Makefile.am.sav 2004-09-14 12:34:28.470591928 +0200 +++ ksplashml/pics/themes/simple/Makefile.am 2004-09-14 12:35:36.643228112 +0200 @@ -0,0 +1,4 @@ +EXTRA_DIST=Theme.rc Preview.png + +ksplashml_pics_default_datadir = $(kde_datadir)/ksplash/Themes/Simple +ksplashml_pics_default_data_DATA = $(EXTRA_DIST) Soubory ksplashml/pics/themes/simple/Preview.png.sav a ksplashml/pics/themes/simple/Preview.png jsou různé --- ksplashml/pics/themes/none/Theme.rc.sav 2004-09-14 12:34:35.582510752 +0200 +++ ksplashml/pics/themes/none/Theme.rc 2004-09-14 12:32:40.853952144 +0200 @@ -0,0 +1,6 @@ +# Default KSplash/ML Theme + +[KSplash Theme: None] +Name = No Splash Screen +Description = Splash Screen Turned Off +Version = 1.0 --- ksplashml/pics/themes/none/Makefile.am.sav 2004-09-14 12:34:34.068740880 +0200 +++ ksplashml/pics/themes/none/Makefile.am 2004-09-14 12:31:35.442896136 +0200 @@ -0,0 +1,4 @@ +EXTRA_DIST=Theme.rc + +ksplashml_pics_default_datadir = $(kde_datadir)/ksplash/Themes/None +ksplashml_pics_default_data_DATA = $(EXTRA_DIST) --- ksplashml/themeengine/Makefile.am.sav 2003-10-06 22:50:50.000000000 +0200 +++ ksplashml/themeengine/Makefile.am 2004-09-14 12:53:47.000000000 +0200 @@ -1,4 +1,4 @@ -SUBDIRS = . default standard redmond +SUBDIRS = . default standard redmond simple INCLUDES = -I$(srcdir)/.. $(all_includes) diff -u -p -d -N -r -x Makefile -x Makefile.in -x Makefile.rules.in -x Makefile.calls.in -x '*~' ksplashml/themeengine/simple.sav/configure.in.in ksplashml/themeengine/simple/configure.in.in --- ksplashml/themeengine/simple.sav/configure.in.in 1970-01-01 01:00:00.000000000 +0100 +++ ksplashml/themeengine/simple/configure.in.in 2004-09-14 13:03:42.350961584 +0200 @@ -0,0 +1,21 @@ +xinerama_save_ldflags="$LDFLAGS" +LDFLAGS="$X_LDFLAGS" + +LIB_XINERAMA= + +KDE_CHECK_HEADER(X11/extensions/Xinerama.h, + [ + AC_CHECK_LIB(Xinerama,XineramaQueryExtension, + [ + AC_DEFINE(HAVE_XINERAMA, 1, [Define if you have the Xinerama extension]) + LIB_XINERAMA="-lXinerama -lXext" + ], + [], + [ $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS ]) + ], [], + [ + #include <X11/Xlib.h> + ] ) + +AC_SUBST(LIB_XINERAMA) +LDFLAGS="$xinerama_save_ldflags" diff -u -p -d -N -r -x Makefile -x Makefile.in -x Makefile.rules.in -x Makefile.calls.in -x '*~' ksplashml/themeengine/simple.sav/main.cpp ksplashml/themeengine/simple/main.cpp --- ksplashml/themeengine/simple.sav/main.cpp 1970-01-01 01:00:00.000000000 +0100 +++ ksplashml/themeengine/simple/main.cpp 2004-09-14 13:31:02.640599656 +0200 @@ -0,0 +1,169 @@ +/*************************************************************************** + * Copyright 2004 Lubos Lunak <[email protected]> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License (version 2) as * + * published by the Free Software Foundation. (The original KSplash/ML * + * codebase (upto version 0.95.3) is BSD-licensed.) * + * * + ***************************************************************************/ + +#include <config.h> + +#include <X11/Xlib.h> +#include <X11/extensions/Xinerama.h> +#include <stdio.h> +#include <unistd.h> +#include <time.h> +#include <string.h> + +//#define DEBUG + +int main( int argc, char* argv[]) + { + if( fork() != 0 ) + return 0; + Display* dpy = XOpenDisplay( NULL ); + if( dpy == NULL ) + return 1; + bool test = false; + if( argc == 2 && strcmp( argv[ 1 ], "--test" ) == 0 ) + test = true; + int sx, sy, sw, sh; +#ifdef HAVE_XINERAMA + // Xinerama code from Qt + XineramaScreenInfo *xinerama_screeninfo = 0; + int unused; + bool use_xinerama = XineramaQueryExtension( dpy, &unused, &unused ) + && XineramaIsActive( dpy ); + if (use_xinerama) + { + int screenCount; + xinerama_screeninfo = XineramaQueryScreens( dpy, &screenCount ); + sx = xinerama_screeninfo[ 0 ].x_org; + sy = xinerama_screeninfo[ 0 ].y_org; + sw = xinerama_screeninfo[ 0 ].width; + sh = xinerama_screeninfo[ 0 ].height; + } + else +#endif + { + sx = sy = 0; + sw = WidthOfScreen( ScreenOfDisplay( dpy, DefaultScreen( dpy ))); + sh = HeightOfScreen( ScreenOfDisplay( dpy, DefaultScreen( dpy ))); + } + XSetWindowAttributes attrs; + attrs.override_redirect = True; + const int states = 7; + const int frame = 3; + const int segment = sw / 2 / states; + const int w = segment * states + 2 * frame; + const int h = sh / 20 + frame; + Window win = XCreateWindow( dpy, DefaultRootWindow( dpy ), sx + ( sw - w ) / 2, sy + ( sh - h ) /2, w, h, + 0, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attrs ); + Pixmap pix = XCreatePixmap( dpy, DefaultRootWindow( dpy ), w, h, DefaultDepth( dpy, 0 )); + XGCValues values; + values.foreground = WhitePixel( dpy, 0 ); + GC gc = XCreateGC( dpy, pix, GCForeground, &values ); + XFillRectangle( dpy, pix, gc, 0, 0, w, h ); + values.foreground = BlackPixel( dpy, 0 ); + XChangeGC( dpy, gc, GCForeground, &values ); +// XFillRectangle( dpy, pix, gc, 0, 0, w, frame ); +// XFillRectangle( dpy, pix, gc, 0, h - frame, w, frame ); +// XFillRectangle( dpy, pix, gc, 0, 0, frame, h ); +// XFillRectangle( dpy, pix, gc, w - frame, 0, frame, h ); + XSetWindowBackgroundPixmap( dpy, win, pix ); + XSelectInput( dpy, win, ButtonPressMask ); + XSelectInput( dpy, DefaultRootWindow( dpy ), SubstructureNotifyMask ); + XMapWindow( dpy, win ); + int pos = 0; + int state = 1; // cannot check dcop connection - make this state initial + const int delay = 10; // ms + time_t final_time = time( NULL ) + 60; + time_t test_time = time( NULL ) + 1; + Atom kde_splash_progress = XInternAtom( dpy, "_KDE_SPLASH_PROGRESS", False ); + for(;;) + { + while( XPending( dpy )) + { + XEvent ev; + XNextEvent( dpy, &ev ); + if( ev.type == ButtonPress && ev.xbutton.window == win ) + { + final_time = time( NULL ); + break; + } + if( ev.type == ConfigureNotify && ev.xconfigure.event == DefaultRootWindow( dpy )) + XRaiseWindow( dpy, win ); + if( ev.type == ClientMessage && ev.xclient.window == DefaultRootWindow( dpy ) + && ev.xclient.message_type == kde_splash_progress ) + { + // based on ksplash + const char* s = ev.xclient.data.b; +#ifdef DEBUG + fprintf( stderr,"MESSAGE: %s\n", s ); +#endif + if( strcmp( s, "dcop" ) == 0 && state < 1 ) + state = 1; // not actually used, state starts from 1, because dcop cannot be checked + else if( strcmp( s, "kded" ) == 0 && state < 2 ) + state = 2; + else if( strcmp( s, "kcminit" ) == 0 ) + ; // unused + else if( strcmp( s, "ksmserver" ) == 0 && state < 3 ) + state = 3; + else if( strcmp( s, "wm started" ) == 0 && state < 4 ) + state = 4; + else if( strcmp( s, "kdesktop" ) == 0 && state < 5 ) + state = 5; + else if( strcmp( s, "kicker" ) == 0 && state < 6 ) + state = 6; + else if( strcmp( s, "session ready" ) == 0 && state < 7 ) + state = 7; + } + } + if( test && time( NULL ) >= test_time ) + { + ++state; + test_time = time( NULL ) + 1; + } + if( pos != state ) + { + while( pos < state && pos < states ) + { +#ifdef DEBUG + fprintf( stderr, "POS: %d\n", pos ); +#endif + final_time = time( NULL ) + 60; + XFillRectangle( dpy, pix, gc, frame + pos * segment, frame, segment, h - 2 * frame ); + XSetWindowBackgroundPixmap( dpy, win, pix ); + XClearWindow( dpy, win ); + ++pos; + if( pos >= states ) + { +#ifdef DEBUG + fprintf( stderr, "CLOSING DOWN\n" ); +#endif + final_time = time( NULL ) + 2; + } + } + } + fd_set set; + FD_ZERO( &set ); + FD_SET( XConnectionNumber( dpy ), &set ); + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = delay * 1000; + select( XConnectionNumber( dpy ) + 1, &set, NULL, NULL, &tv ); + if( time( NULL ) >= final_time ) + { +#ifdef DEBUG + fprintf( stderr, "EXITING\n" ); +#endif + break; // ---> + } + } + XFreePixmap( dpy, pix ); + XDestroyWindow( dpy, win ); + XFreeGC( dpy, gc ); + XCloseDisplay( dpy ); + } diff -u -p -d -N -r -x Makefile -x Makefile.in -x Makefile.rules.in -x Makefile.calls.in -x '*~' ksplashml/themeengine/simple.sav/Makefile.am ksplashml/themeengine/simple/Makefile.am --- ksplashml/themeengine/simple.sav/Makefile.am 1970-01-01 01:00:00.000000000 +0100 +++ ksplashml/themeengine/simple/Makefile.am 2004-09-14 13:07:40.750719312 +0200 @@ -0,0 +1,7 @@ + +INCLUDES = $(all_includes) + +bin_PROGRAMS = ksplashsimple +ksplashsimple_SOURCES = main.cpp +ksplashsimple_LDFLAGS = $(all_libraries) $(KDE_RPATH) +ksplashsimple_LDADD = $(LIB_XINERAMA) $(LIB_X11) --- ksplashml/kcmksplash/installer.cpp.sav 2004-07-10 23:58:43.000000000 +0200 +++ ksplashml/kcmksplash/installer.cpp 2004-09-14 13:26:09.254201168 +0200 @@ -330,10 +330,10 @@ void SplashInstaller::slotSetTheme(int i path = mThemesList->text2path[path]; enabled = false; KURL url; + QString themeName; if (!path.isEmpty()) { // Make sure the correct plugin is installed. - QString themeName; int i = path.findRev('/'); if (i >= 0) themeName = path.mid(i+1); @@ -381,7 +381,7 @@ void SplashInstaller::slotSetTheme(int i error = i18n("Could not load theme configuration file."); } } - mBtnTest->setEnabled(enabled); + mBtnTest->setEnabled(enabled && themeName != "None" ); mText->setText(infoTxt); if (!enabled) { @@ -458,6 +458,17 @@ void SplashInstaller::slotTest() if (r >= 0) themeName = themeName.mid(r+1); + // special handling for none and simple splashscreens + if( themeName == "None" ) + return; + if( themeName == "Simple" ) + { + KProcess proc; + proc << "ksplashsimple" << "--test"; + if (!proc.start(KProcess::Block)) + KMessageBox::error(this,i18n("Unable to start ksplashsimple.")); + return; + } KProcess proc; proc << "ksplash" << "--test" << "--theme" << themeName; if (!proc.start(KProcess::Block))
Preview.png
(image/png, 52.1 KB) - not displayed
desktop.cc.patch
(text/x-diff, 730 B)
--- desktop.cc.sav 2004-09-01 13:36:03.000000000 +0200
+++ desktop.cc 2004-09-14 12:12:52.202654608 +0200
@@ -279,6 +279,16 @@ KDesktop::slotStart()
if (!m_bInit) return;
kapp->dcopClient()->send( "ksplash", "", "upAndRunning(QString)", QString("kdesktop"));
+#ifdef Q_WS_X11
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = XInternAtom( qt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
+ e.xclient.display = qt_xdisplay();
+ e.xclient.window = qt_xrootwin();
+ e.xclient.format = 8;
+ strcpy( e.xclient.data.b, "kdesktop" );
+ XSendEvent( qt_xdisplay(), qt_xrootwin(), False, SubstructureNotifyMask, &e );
+#endif
// In case we started without database
KImageIO::registerFormats();
kded.cpp.patch
(text/x-diff, 1016 B)
--- kded.cpp.sav 2004-09-12 23:37:38.000000000 +0200
+++ kded.cpp 2004-09-14 12:06:56.741692888 +0200
@@ -48,6 +48,11 @@
#include <kio/global.h>
#include <kservicetype.h>
+#ifdef Q_WS_X11
+#include <X11/Xlib.h>
+#include <fixx11h.h>
+#endif
+
Kded *Kded::_self = 0;
static bool checkStamps = true;
@@ -841,7 +846,16 @@ extern "C" int kdemain(int argc, char *a
QByteArray data;
client->send( "*", "ksycoca", "notifyDatabaseChanged()", data );
client->send( "ksplash", "", "upAndRunning(QString)", QString("kded"));
-
+#ifdef Q_WS_X11
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = XInternAtom( qt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
+ e.xclient.display = qt_xdisplay();
+ e.xclient.window = qt_xrootwin();
+ e.xclient.format = 8;
+ strcpy( e.xclient.data.b, "kded" );
+ XSendEvent( qt_xdisplay(), qt_xrootwin(), False, SubstructureNotifyMask, &e );
+#endif
int result = k.exec(); // keep running
delete kded;
kicker.cpp.patch
(text/x-diff, 983 B)
--- kicker.cpp.sav 2004-06-13 19:08:36.000000000 +0200
+++ kicker.cpp 2004-09-14 12:13:54.914121016 +0200
@@ -40,6 +40,11 @@
#include <kiconloader.h>
#include <kdebug.h>
+#ifdef Q_WS_X11
+#include <X11/Xlib.h>
+#include <fixx11h.h>
+#endif
+
#include "extensionmanager.h"
#include "menumanager.h"
#include "panel.h"
@@ -69,6 +74,16 @@ Kicker* Kicker::kicker() { return (Kicke
dcopClient()->setDefaultObject("Panel");
dcopClient()->send( "ksplash", "", "upAndRunning(QString)", KCmdLineArgs::appName());
+#ifdef Q_WS_X11
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = XInternAtom( qt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
+ e.xclient.display = qt_xdisplay();
+ e.xclient.window = qt_xrootwin();
+ e.xclient.format = 8;
+ strcpy( e.xclient.data.b, "kicker" );
+ XSendEvent( qt_xdisplay(), qt_xrootwin(), False, SubstructureNotifyMask, &e );
+#endif
disableSessionManagement();
main.cpp.patch
(text/x-diff, 767 B)
--- main.cpp.sav 2004-08-04 14:39:34.000000000 +0200
+++ main.cpp 2004-09-14 12:14:32.342431048 +0200
@@ -122,9 +122,16 @@ Application::Application( )
initting = FALSE; // startup done, we are up and running now.
dcopClient()->send( "ksplash", "", "upAndRunning(QString)", QString("wm started"));
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = XInternAtom( qt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
+ e.xclient.display = qt_xdisplay();
+ e.xclient.window = qt_xrootwin();
+ e.xclient.format = 8;
+ strcpy( e.xclient.data.b, "wm started" );
+ XSendEvent( qt_xdisplay(), qt_xrootwin(), False, SubstructureNotifyMask, &e );
}
-
Application::~Application()
{
delete Workspace::self();
server.cpp.patch
(text/x-diff, 894 B)
--- server.cpp.sav 2004-08-26 18:55:15.000000000 +0200
+++ server.cpp 2004-09-14 12:17:14.819730744 +0200
@@ -49,6 +49,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE
#include <time.h>
#include <errno.h>
#include <string.h>
+#include <assert.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
@@ -1548,6 +1549,15 @@ void KSMServer::publishProgress( int pro
void KSMServer::upAndRunning( const QString& msg )
{
DCOPRef( "ksplash" ).send( "upAndRunning", msg );
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = XInternAtom( qt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
+ e.xclient.display = qt_xdisplay();
+ e.xclient.window = qt_xrootwin();
+ e.xclient.format = 8;
+ assert( strlen( msg.latin1()) < 20 );
+ strcpy( e.xclient.data.b, msg.latin1());
+ XSendEvent( qt_xdisplay(), qt_xrootwin(), False, SubstructureNotifyMask, &e );
}
startkde.patch
(text/x-diff, 575 B)
--- startkde.sav 2004-08-08 12:53:51.000000000 +0200 +++ startkde 2004-09-14 13:35:01.491288832 +0200 @@ -194,7 +194,14 @@ if kreadconfig --file kpersonalizerrc -- fi # the splashscreen and progress indicator -ksplash --nodcop +splash=`kreadconfig --file ksplashrc --group KSplash --key Theme` +if test "$splash" = "None"; then + echo >/dev/null #nothing +elif test "$splash" = "Simple"; then + ksplashsimple +else + ksplash --nodcop +fi # We set LD_BIND_NOW to increase the efficiency of kdeinit. # kdeinit unsets this variable before loading applications.