V Brně na FIT VUT probíhá třídenní open source komunitní konference DevConf.CZ 2025. Vstup je zdarma, nutná je ale registrace. Na programu je celá řada zajímavých přednášek, lightning talků, meetupů a workshopů. Přednášky lze sledovat i online na YouTube kanálu konference. Aktuální dění lze sledovat na Matrixu, 𝕏 nebo Mastodonu.
Vyloučení technologií, které by mohly představovat bezpečnostní riziko pro stát, má umožnit zákon o kybernetické bezpečnosti, který včera Senát schválil spolu s novelami navazujících právních předpisů. Norma, kterou nyní dostane k podpisu prezident, počítá rovněž s prověřováním dodavatelů technologií pro stát. Normy mají nabýt účinnosti od třetího měsíce po jejich vyhlášení ve Sbírce zákonů.
Open source platforma Home Assistant (Demo, GitHub, Wikipedie) pro monitorování a řízení inteligentní domácnosti byla vydána v nové verzi 2025.6.
Po Red Hat Enterprise Linuxu a AlmaLinuxu byl v nové stabilní verzi 10.0 vydán také Rocky Linux. Přehled novinek v poznámkách k vydání.
Bylo vydáno Eclipse IDE 2025-06 aneb Eclipse 4.36. Představení novinek tohoto integrovaného vývojového prostředí také na YouTube.
Americká filmová studia Walt Disney a Universal Pictures podala žalobu na provozovatele populárního generátoru obrázků pomocí umělé inteligence (AI) Midjourney. Zdůvodňují to údajným porušováním autorských práv. V žalobě podané u federálního soudu v Los Angeles označují firmu za „bezednou jámu plagiátorství“, neboť podle nich bez povolení bezostyšně kopíruje a šíří postavy z filmů jako Star Wars, Ledové království nebo Já, padouch, aniž by do nich investovala jediný cent.
Ultra Ethernet Consortium (UEC), jehož cílem je optimalizace a další vývoj Ethernetu s důrazem na rostoucí síťové požadavky AI a HPC, vydalo specifikaci Ultra Ethernet 1.0 (pdf, YouTube).
Francouzský prezident Emmanuel Macron chce zakázat přístup na sociální sítě pro děti do 15 let. Francie podle něj tento krok udělá sama do několika měsíců, i pokud se na něm neshodnou další státy Evropské unie. Reaguje tak na úterní vraždu vychovatelky, kterou ve východofrancouzském městě Nogent pobodal 14letý mladík. Jednotlivé sociální sítě podle něj mají možnost věk ověřit a vymáhat zákaz pomocí systémů na rozpoznávání tváří.
Byl aktualizován seznam 500 nejvýkonnějších superpočítačů na světě TOP500. Nejvýkonnějším superpočítačem zůstává El Capitan od HPE (Cray) s výkonem 1,742 exaFLOPS. Druhý Frontier má výkon 1,353 exaFLOPS. Třetí Aurora má výkon 1,012 exaFLOPS. Nejvýkonnější český počítač C24 klesl na 165 místo. Karolina, GPU partition klesla na 195. místo a Karolina, CPU partition na 421. místo. Další přehledy a statistiky na stránkách projektu.
Oficiálně byl vydán Android 16. Detaily na blogu a stránkách věnovaných vývojářům.
Plasmoidy, to nejsou jen applety na plochu, ale zahrnují i tzv. runnery. Runner je knihovna, kterou využívá KRunner. Když píšete název nějaké aplikace, KRunner postupně volá hlavní funkce všech dostupných runnerů a předává jim zadaný řetězec (tzv. Context). Každý runner vrací seznam relativních položek (Plasma::QueryMatch). Při kliknutí na vybraný QueryMatch KRunner zavolá funkci run příslušného Runneru, který zařídí, aby se vykonala příslušná událost.
Jako příklad pro dnešní článek použijeme jeden můj starší runner, který umožňuje prohledávat kontakty z Kopete. Kliknutím na kontakt se rovnou otevře chatovací okno Kopete. Celá komunikace probíha přes rozhraní DBus. Podobný, ale ještě o něco propracovanější runner najdete v KDE SC 4.4.
Runner je třída odvozená od Plasma::AbstractRunner a musí implementovat tři metody:
Konstruktor, ve kterém se nastavují výchozí vlastnosti Runneru.
match(Plasma::RunnerContext &context), která se volá vždy, když se změní text v KRunneru. Ten získáme pomocí metody Plasma::RunnerContext.query(). Plasma::RunnerContext má ještě jednu další šikovnou vlastnost, kterou zjistíme pomocí metody isValid(). Ta vrací true, pokud je RunnerContext stále platný, a false, pokud se RunnerContext mezitím změnil (např. uživatel napsal další znak) – v takovém případě runner zpravidla skončí, protože už běží jeho nová instance s novým kontextem a ten stavající je zneplatněn (jeho výstup nebude zobrazen).
Třetí metodou, kterou musí runnery implementovat, je run(Plasma::RunnerContext &context, Plasma::QueryMatch &match), která se volá, když uživatel klikne na položku v seznamu výsledků. Jako parametr přijímá ukazatel na příslušný QueryMatch. V QueryMatch lze, kromě zobrazovaných hodnot, uložit ještě hodnotu skrytou, která obsahuje například URL, která se má otevřít a podobně. Context obsahuje aktuální kontext, pro který je daný QueryMatch platný.
A teď od teorie k praxi.
kopetecontacts.h
#ifndef KOPETECONTACTS_H #define KOPETECONTACTS_H #include <Plasma/AbstractRunner> #include <KIcon> class KopeteContactsRunner : public Plasma::AbstractRunner { Q_OBJECT public: KopeteContactsRunner(QObject *parent, const QVariantList& args ); ~KopeteContactsRunner() { } void match(Plasma::RunnerContext &context); void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match); private: KIcon m_icon; }; // Makro pro registraci runneru K_EXPORT_PLASMA_RUNNER(kopetecontacts, KopeteContactsRunner) #endif // KOPETECONTACTS_H #endif
Důležité je nezapomenout na makro pro registraci runneru do KDE. První parametr je název pluginu, pod kterým ho systém bude znát. Musí odpovídat hodnotě X-KDE-PluginInfo-Name v souboru .desktop. Druhým parametrem je název třídy runneru.
kopetecontacts.cpp
#include "kopetecontactsrunner.h" // Vloží podporu QtDbus #include <QtDBus/QDBusInterface> #include <QtDBus/QDBusReply> #include <KIcon> KopeteContactsRunner::KopeteContactsRunner(QObject *parent, const QVariantList& args) : Plasma::AbstractRunner(parent, args) { // Umlčí překladač Q_UNUSED(args); // Název runneru setObjectName("KopeteContacts"); // Použije ikonku Kopete m_icon = KIcon("kopete"); // Bude ignorovat všechny generické typy kontextu setIgnoredTypes(Plasma::RunnerContext::Directory | Plasma::RunnerContext::File | Plasma::RunnerContext::NetworkLocation | Plasma::RunnerContext::Executable | Plasma::RunnerContext::ShellCommand); // Přiklad syntaxe addSyntax(Plasma::RunnerSyntax(":q:", "Zahaji chat s :q:")); // DBus protocol je pomalý… setSpeed(AbstractRunner::SlowSpeed); } void KopeteContactsRunner::match(Plasma::RunnerContext &context) { // Vyhledávání nebude case-sensitive QString searchedName = context.query().toLower(); // Nebude se vyhledávat pro kontexty kratší než 3 znaky if (searchedName.length() < 3) { return; } // Pokusí se navázat DBus spojení s Kopete QDBusInterface kopeteDBusTest("org.kde.kopete", "/Kopete", "org.freedesktop.DBus.Introspectable"); QDBusReply<QString>kopeteReply = kopeteDBusTest.call("Introspect"); if (!kopeteReply.isValid()) { return; } // Vytvoří seznam výsledků QList<Plasma::QueryMatch> matches; // Načte seznam všech kontaktu QDBusInterface kopeteDBus("org.kde.kopete","/Kopete","org.kde.Kopete"); QDBusReply<QStringList> kopeteContacts = kopeteDBus.call("contacts"); QString contactName; // Projde všechny kontakty for (int i = 0; i < kopeteContacts.value().size(); i++) { // Nemá smysl pokračovat, pokud aktuální kontext už neni platný if (!context.isValid()) { return; } // Načte informace o kontaktu QDBusReply<QVariantMap>contactData = kopeteDBus.call("contactProperties",kopeteContacts.value().at(i)); // Uloží jméno kontaktu contactName = contactData.value().value("display_name").toString(); // Zjistí, jestli kontext odpovídá kontaktu bool matched = contactName.contains(searchedName, Qt::CaseInsensitive); // Pokud ano, tak přidáme výsledek do QueryMatch if (matched) { // Vytvoří nový QueryMatch Plasma::QueryMatch matchItem(this); // Nastaví mu ikonu matchItem.setIcon(m_icon); // Jako hlavní název QueryMatch nastaví název kontaktu matchItem.setText(contactName); // Načte status kontaktu QString statusMessage = contactData.value().value("status_message").toString(); if (not statusMessage.isEmpty()) { statusMessage.prepend(": "); } // Jako popis QueryMatch nastaví název a popis statusu matchItem.setSubtext(contactData.value().value("status").toString().append(statusMessage)); // Jako data (skrytá, nezobrazují se) nastaví UID matchItem.setData(kopeteContacts.value().at(i)); // Pokud kontakt přesně odpovídá kontextu, nastavíme ExactMatch if (contactName == searchedName) { matchItem.setType(Plasma::QueryMatch::ExactMatch); } else { matchItem.setType(Plasma::QueryMatch::PossibleMatch); } // Přidá tento QueryMatch do seznamu matches.append(matchItem); } } // Uloží do kontextu seznam QueryMatchů context.addMatches(searchedName,matches); } void KopeteContactsRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) { // Umlčí překladač Q_UNUSED(context); QString uid = match.data().toString(); // Pokusí se navázat DBus spojení s Kopete QDBusInterface kopeteDBusTest("org.kde.kopete", "/Kopete", "org.freedesktop.DBus.Introspectable"); QDBusReply<QString>kopeteReply = kopeteDBusTest.call("Introspect"); if (!kopeteReply.isValid()) { return; } QDBusInterface kopeteDBus("org.kde.kopete","/Kopete","org.kde.Kopete"); kopeteDBus.call("openChat",uid); } #include "kopetecontactsrunner.moc"
V konstruktoru se podíváme podrobněji na metody setSpeed a addSyntax. Metoda setSpeed nastavuje rychlost Plasmoidů. Výchozí hodnota je rychlá, ale pokud runner pužívá internetové připojení nebo DBus, měla by se rychlost nastavit na AbstractRunner::Slow – KRunner pak počítá s tím, že na takový runner musí čekat o něco déle. Metoda addSyntax přijímá objekt Plasma::RunnerSyntax. Plasma::RunnerSyntax v konstruktoru přijímá dva parametry – syntaxi vstupu, kde :q: je symbol pro vyhledávaný výraz a popis vstupu. Pokud například chcete, aby vstup vypadal „kontakt jméno_kontaktu“, vložili byste do addSyntax objekt Plasma::RunnerSyntax("kontakt :q:","Vyhledá kontakt :q:")).
V metodě match je na konci volána metoda context.addMatches, která jako parametr přijímá seznam všech nalezených položek, které se mají zobrazit.
Stejně jako applet, i runner musí mít svůj soubor .desktop, podle kterého ho KDE může najít.
plasma-runner-idossearchrunner.desktop
[Desktop Entry] Name=Kopete Contacts Comment=Start chat with your Kopete contacts ServiceTypes=Plasma/Runner Type=Service Icon=kopete X-KDE-Library=krunner_kopetecontacts X-KDE-PluginInfo-Author=Dan Vratil X-KDE-PluginInfo-Email=vratil@progdansoft.com X-KDE-PluginInfo-Name=kopetecontacts X-KDE-PluginInfo-Version=0.1 X-KDE-PluginInfo-License=GPL X-KDE-PluginInfo-EnabledByDefault=true
Důležité je, aby X-KDE-PluginInfo-Name odpovídalo hodnotě v makru v hlavičkovém souboru.
CMakeLists.txt
# Název projektu project(kopetecontactsrunner) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) # Najde požadované komponenty find_package(KDE4 REQUIRED) find_package(Qt4 REQUIRED) find_package(KDE4Workspace REQUIRED) find_package(Kopete REQUIRED) include (KDE4Defaults) # Nastaví definice add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) # Nastaví adresáře s hlavičkovými soubory include_directories (${KDE4_INCLUDES} ${KDE4WORKSPACE_INCLUDE_DIR} ${QT_INCLUDE_DIR} ${QT_QTDBUS_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libs) set(krunner_kopetecontacts_SRCS kopetecontactsrunner.cpp ) # Přidá plugin do KDE kde4_add_plugin(krunner_kopetecontacts ${krunner_kopetecontacts_SRCS}) # Slinkuje knihovnu target_link_libraries(krunner_kopetecontacts ${KDE4_PLASMA_LIBS}) # Nainstaluje soubory install(TARGETS krunner_kopetecontacts DESTINATION ${PLUGIN_INSTALL_DIR} ) install(FILES plasma-runner-kopetecontacts.desktop DESTINATION ${SERVICES_INSTALL_DIR})
Nyní je potřeba restartovat KRunner:
kquitap krunner kstart krunner
Nyní můžete runner otestovat – když začnete psát název některého ze svých kontaktů v Kopete, budou se relevantní kontakty zobrazovat v KRunneru.
Možností, jak rozšířit KRunner, je mnoho. Runnery mohou, stejně jako applety, také používat DataEnginy a mít dialog pro konfiguraci. Jedinou nevýhodou je, že není možná interakce s uživatelem (kromě úvodního vstupu). Nakonec ještě přikládám tarball se zdrojovými kódy.
Nástroje: Tisk bez diskuse
Tiskni
Sdílej:
$qdbus org.psi-im.Psi /Main method void org.psi_im.Psi.Main.openURI(QString uri) method void org.psi_im.Psi.Main.raise() method void org.psi_im.Psi.Main.setStatus(QString status, QString message) method void org.psi_im.Psi.Main.sleep() method void org.psi_im.Psi.Main.wake() method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name) method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name) method void org.freedesktop.DBus.Properties.Set(QString interface_name, QString property_name, QDBusVariant value) method QString org.freedesktop.DBus.Introspectable.Introspect()