2013-06-21

[Technology] GNOME Shell, memory usage, CPU usage, and graphics

I have a "Intel Corporation Mobile 945GM/GMS/GME, 943/940GML Express Integrated Graphics Controller" according to lspci.  It's in an HP Compaq tc4400.  It's nice.  However, it doesn't like GNOME Shell when it comes to multiple monitors.



The reason is bug 699705: "Intel Gen 3 Rendering Limits are Pitiful".  A solution might be coming under the name "per-crtc pixmaps" in a future edition of the XRANDR protocol, requiring support in GNOME Shell as well.  Basically, the way memory is allocated right now, a screen that spans multiple monitors becomes too big, and GNOME Shell can't handle it.  It used to crash; now it just takes 100% CPU to draw VERY SLOWLY.



I own a nice second monitor, and I've suffered under using GNOME Shell on just one screen for too long.  Consequently, I'm now back to just using gnome-panel and metacity, and I've noticed something weird.



When I'm using just a single monitor, using GNOME Shell, if any application (with a window, at least), uses up to 50% of available RAM (e.g. Firefox, Chromium), my system slows to crawl and starts swapping like crazy.  In theory, there's still a lot of memory available, though. 



When I use metacity + gnome-panel, whether I'm using one monitor or two, I have Firefox up to 64% of available memory (nauseating) and there's no swapping yet!



Does using GNOME Shell somehow double memory usage, double what's reported under top?

[Technology] DOMException, its nature and appropriateness for GError reporting

I've had to recently study the nature of the various DOMExceptions specified by the DOM Level 3 Core spec, to better understand whether we want to use the GError reporting system of GLib in GXml, or whether we want to use something else.  I defaulted to using GError, because the spec presents them as exceptions to be raised, and because I was used to handling libgdata errors (which are legitimately run-time errors) with GError.



The GLib Error Reporting documentation is pretty clear about when it's appropriate to use GError: basically, only when it's a run-time issue that a programmer can't reasonably anticipate.


First and foremost: GError should only be used to report recoverable runtime errors, never to report programming errors. If the programmer has screwed up, then you should use g_warning(), g_return_if_fail(), g_assert(), g_error(), or some similar facility. (Incidentally, remember that the g_error() function should only be used for programming errors, it should not be used to print any error reportable via GError.)



Examples of recoverable runtime errors are "file not found" or "failed to parse input." Examples of programming errors are "NULL passed to strcmp()" or "attempted to free the same pointer twice." These two kinds of errors are fundamentally different: runtime errors should be handled or reported to the user, programming errors should be eliminated by fixing the bug in the program. This is why most functions in GLib and GTK+ do not use the GError facility.

Below are my feelings on which DOMExceptions constitute programming errors (and shouldn't use GError) or run-time errors (and should). I look at run-time errors as consequences of the environment in which GXml is used (e.g. is it the fault of a document we're reading in, the content of which we have little control), and programming errors the direct result of a programmed call that's supplying bad data or misusing the document.



I find most of the DOMExceptions to be programming errors.  If you believe that something is more properly a run-time error and deserves GError reporting, please comment and explain why!  I am not an expert.  Like, for invalid characters, GXml might be used by a GUI where a user is entering data, and enters characters that aren't supported.  I think input checking like that should be handled in the application instead of in the GXml library, though; it shouldn't get as far as trying to actually set an attribute with bad data.  Perhaps we could provide convenience validation methods to GXml, though.  Thoughts welcome.







R: Runtime, GError
P: Programming
N: N/A

Defined Constants

N DOMSTRING_SIZE_ERR
If the specified range of text does not fit into a DOMString.
we don't have our own DOMString type, we just use gchar* arrays, which don't really have 
a fixed limit, just as much as you can alloc in a single go.

P HIERARCHY_REQUEST_ERR
If any Node is inserted somewhere it doesn't belong.
this would be a programmer error, like trying to append a node to be a child of itself.

P INDEX_SIZE_ERR
If index or size is negative, or greater than the allowed value.
programmer error, they should check size before accessing non-existent members of lists

P INUSE_ATTRIBUTE_ERR
If an attempt is made to add an attribute that is already in use elsewhere.
programmer error

? INVALID_ACCESS_ERR, introduced in DOM Level 2.
If a parameter or an operation is not supported by the underlying object.
nclear as to when this might happen; property of a document or implementation or the DOM?

?P INVALID_CHARACTER_ERR
If an invalid or illegal character is specified, such as in an XML name.
I'd almost think it's a run-time error, because it probably reflects an issue with the 
document we're working on. Invalid characters are related to the XML version of a document,
and which features our implementation supports. Right now, we basically don't deal with 
this (!). libxml2 has version information, of course, but I'm not sure how it handles 
invalid characters yet. TODO: figure this out.
However, I think of it more as programmer error, because almost all the methods its 
associated with are where the programmer provides a string that might contain it, rather 
than just accessing a string already in the Document. The other ones involve bringing
foreign nodes into documents, and the programmer has the option of checking version 
information and characters beforehand to ensure compatibility
*Document.adoptNode
Document.createAttribute
Document.createElement
Document.createEntityReference
Document.createProcessingInstruction
*Document.importNode
Document.renameNode
Node.prefix.set
Element.setAttribute
DOMImplementation.createDocument
DOMImplementation.createDocumentType

? INVALID_MODIFICATION_ERR, introduced in DOM Level 2.
If an attempt is made to modify the type of the underlying object.
Not really specified for any methods

? INVALID_STATE_ERR, introduced in DOM Level 2.
If an attempt is made to use an object that is not, or is no longer, usable.
Not really specified for any methods

P NAMESPACE_ERR, introduced in DOM Level 2.
If an attempt is made to create or change an object in a way which is incorrect 
with regard to namespaces.
The result of bad input from a programmer, for qualified names.
DOMImplementation.createDocument
DOMImplementation.createDocumentType
DOMImplementation.createAttributeNS
DOMImplementation.createElementNS
DOMImplementation.renameNode
Node.prefix.set

P NOT_FOUND_ERR
If an attempt is made to reference a Node in a context where it does not exist.
Programmer error, they're specifying the node in reference, so like with insertBefore, 
removeChild, etc.

?RP NOT_SUPPORTED_ERR
If the implementation does not support the requested type of object or operation.
We couldn't don't deal with the features of our implementation or XML versions (that's bad, 
but oh well); not exactly sure where this would fall. Sometimes it seems like it would be 
a programming error (trying to adopt a Document node into another Document with adoptNode) 
but other times, like when creating a document, I could see that being a runtime error.

? NO_DATA_ALLOWED_ERR
If data is specified for a Node which does not support data.
Currently nothing raised it according to the spec, and there aren't any obvious cases 
where I want to.

?PR NO_MODIFICATION_ALLOWED_ERR
If an attempt is made to modify an object where modifications are not allowed.
We currently don't have a concept of a read only node, and thus no way to check. I'm not
sure if libxml2 has a concept of readability either. Its common for most nodes to want to 
raise this, so perhaps it's a real use case we should support, but even then, it feels like
 something that isn't variable at run time, and that a programmer might be able to reasonably 
anticipate and check for.

P SYNTAX_ERR, introduced in DOM Level 2.
If an invalid or illegal string is specified.
Probably a programmer error, if they're the ones specifying strings.

P TYPE_MISMATCH_ERR, introduced in DOM Level 3.
If the type of an object is incompatible with the expected type of the parameter 
associated to the object.
Only used by DOMConfiguration.setParameter, which we don't support. This seems like a 
programmer thing, anyway
DOMConfiguration.setParameter

P VALIDATION_ERR, introduced in DOM Level 3.
If a call to a method such as insertBefore or removeChild would make the Node invalid 
with respect to "partial validity", this exception would be raised and the operation 
would not be done. This code is used in [DOM Level 3 Validation]. Refer to this 
specification for further information.

P WRONG_DOCUMENT_ERR
If a Node is used in a different document than the one that created it (that doesn't 
support it).
Definitely a programmer error.

[GNOME] GXml's summer adventure: API bikeshedding to start!

If you are a developer interested in using GXml or interested in XML in GNOME, I'd appreciate your feedback on two proposed API changes contained below. :)

 

So GXml is back in the Google Summer of Code under the mentorship of Owen Taylor, and it's my pleasure to be able to focus time on it again, before I finally graduate.  Over the next week, I'm going to write 6 articles about the key focuses for this summer


  • Developer support: API changes

  • Developer support: migration guide, examples, patches

  • Developer support: library documentation, usage examples, online and devhelp

  • Measurements: Memory

  • Measurements: CPU, scalability

  • Measurements: developer impact


Just so you know, work done so far includes


  • cleaning up the GXml Bugzilla by closing resolved bugs and responding to others.

  • plugged the most severe memory leaks, which is its own post, which will document how I did it! 

  • test ports of dconf and glade (still testing)



Developer support


Improving developer support is the main focus for this GSoC, and it includes these tasks:


  • clean up and break API (GError & GXmlDomNode: today's topic)

  • improve examples of usage

  • improve documentation for usage

  • make sure documentation is available online and in devhelp

  • push to get external patches accepted (e.g. libxml2's vapi changes)

  • more test ports, get patches accepted :D


Today I'm just going to talk about the first task.


Proposed API changes


With the idea of making development and code readability as frictionless as possible, there are two largely cosmetic but API-breaking changes I'm considering now, before 1.0. 

 

Proposal 1: GXmlDomNode: Rename to GXmlNode



The motivation for this is that


  • GXmlNode will result in less typing and make it easier to read

  • GXmlDomNode is inconsistent with other names, because it's the only one that specifies its part of the DOM (we don't do GXmlDomDocument) besides DomError (which mirrors DomException in the DOM Core spec).


It's named GXmlDomNode because, with namespaced languages, GXml.Node would conflict with GLib.Node (GNode), and at the time I didn't want to write GXml.Node all the time.  However, GXml.Node isn't much worse than writing DomNode in a namespaced language, and GXmlNode is much nicer than GXmlDomNode in C.  Especially when you start working on its methods, like gxml_dom_node_append_child ();



Thoughts?  Please provide feedback as a comment below or e-mail me directly!



Proposal 2: GError: remove parametre, use global-ish variable?



Some people previously complained about our explicit handling of errors through a GError parametre as cumbersome and inefficient.  Also, the way GXml has started using GError may be excessive and not how GError was intended to be used. 



[UPDATE: GError's documentation specifically rejects using GError for programming errors, since it's intended only for run-time errors.  I've written a post analysing DOMExceptions, and whether they qualify as run-time errors or programming errors.  Comments welcome, there, too.  I basically conclude that most of the DOMExceptions are programming errors and don't qualify for GError reporting.]



The DOM Core spec specifies many possible DOMExceptions to be raised.   Currently, the methods that are expected to raise an exception are declared to throw a GXml.DOMError, but in reality, many of those do not throw anything.  (I filed bug 702832 on vala requesting warnings for functions that declare errors that are never thrown.)  I haven't implemented error handling in most of the situations because they often seem truly exceptional, and are cases that the programmer should be able to anticipate and deal with in advance  [UPDATE: and thus, I feel, programming errors, and not appropriate for GError].  (I will pragmatically support DOMExceptions as needed in the future; file a bug if you want one supported!)



Consequently, I am considering breaking API and to cease throwing errors, instead switching to either setting a thread-specific global error variable, or a document-level error variable.  I'd document whether a method might set an error, so someone can check.   This is similar to what libxml2 already does, with its xmlGetLastError.  The document's return value would also provide some indication that something went wrong (e.g. NULL).



[UPDATE: additionally, we can allow verbose error reporting, so if a programming error is encountered, we'll use g_warning () or g_error () to log it with where it happened, and where in the document.]



Right now, the functions that do throw GErrors are mostly GXmlDocument constructors, GXmlDocument factory methods (it constructs any other GXml node type), and GXmlDomNode children management (insert, replace, etc), which are all very common.  In theory, if we're going to raise an exception for everything as requested by the DOM Core spec, though, there'd be many more, and we'd have to break API anyway to support it all.



The result of removing most GError reporting should be in general usage, code should be a little
smaller and easier to read, with less unnecessary text, while cases
where errors are anticipated can still be caught and checked.  [UPDATE: also, we'll comply with the intent of GError]



Please provide feedback as a comment below or e-mail me directly!  Also feel free to debate the nature of DOMExceptions.




Example of changes: C

For those who don't need errors:



GXmlDomNode *vader = gxml_document_create_element (doc, "DarthVader", NULL);

GXmlDomNode *luke = gxml_document_create_element (doc, "LukeSkywalker", NULL);

gxml_dom_node_append_child (vader, luke, NULL)



becomes:

GXmlNode *vader = gxml_document_create_element (doc, "DarthVader");

GXmlNode *luke = gxml_document_create_element (doc, "LukeSkywalker");

gxml_node_append_child (vader, luke);





For those who do need the errors:



GError *error = NULL;



GXmlDomNode *vader = gxml_document_create_element (doc, "DarthVader", &error);

if (error != NULL) {

  // handle error



GXmlDomNode *luke = gxml_document_create_element (doc, "LukeSkywalker", &error);

if (error != NULL) {

  // handle error


gxml_dom_node_append_child (vader, luke, &error)

if (error != NULL) {

  // handle error







becomes:  



GError *error = NULL;



GXmlNode *vader = gxml_document_create_element (doc, "DarthVader");

if ((error = gxml_last_error ()) != NULL) {

  // handle error



GXmlNode *luke = gxml_document_create_element (doc, "LukeSkywalker");

if ((error = gxml_last_error ()) != NULL) {

  // handle error



gxml_node_append_child (vader, luke)

if ((error = gxml_last_error ()) != NULL) {

  // handle error

}



Example of changes: Vala

For those who don't need errors:



try {

  DomNode darth = doc.create_element ("DarthVader");

  DomNode luke = doc.create_element ("LukeSkywalker");

  darth.append_child (luke);

} catch (DomError e) {

}



becomes:



GXml.Node darth = doc.create_element ("DarthVader");GXml.Node luke = doc.create_element ("LukeSkywalker");

darth.append_child (luke);



For those who do need errors:



try {

  DomNode darth = doc.create_element ("DarthVader");

  DomNode luke = doc.create_element ("LukeSkywalker");

  darth.append_child (luke);

} catch (DomError e) {

  // handle error

}



becomes:



GXml.Node darth = doc.create_element ("DarthVader");

if (GXml.last_error != null) {

  // handle error



GXml.Node luke = doc.create_element ("LukeSkywalker");

if (GXml.last_error != null) {

  // handle error



darth.append_child (luke);

if (GXml.last_error != null) {

  // handle error







I will appreciate any feedback. :)

2013-06-20

[Technology] "element annotation from state 6 is unknown"

When compiling, I dislike seeing lots of warnings when my code compiles.



While building GXml, I encounter this for most files:



  GICOMP GXml-0.3.gir 

/usr/share/gir-1.0/Gee-0.8.gir:8:51: warning: element annotation from state 6 is unknown, ignoring 

...

/usr/share/gir-1.0/Gee-0.8.gir:3383:50: warning: element annotation from state 15 is unknown, ignoring 

...

/usr/share/gir-1.0/Gee-0.8.gir:3992:1: warning: element property from state 23 is unknown, ignoring 

...

GXml-0.3.gir:10:51: warning: element annotation from state 6 is unknown, ignoring 

GXml-0.3.gir:28:1: warning: element errordomain from state 6 is unknown, ignoring


The GObject Introspection compiler apparently has an issue with some elements in .gir files.  Looking at /usr/share/gir-1.0/Gee-0.8.gir, it's in XML.  Then I looked in gobject-introspection, and at it's girparser.c file, where the warning is printed.


The property element


There I found a large conditional branching block of code, start_element_handler (), that tried to identify elements by their name and their state.  If an element starts with 'p', it checks which p-elements it could be, and one such check calls start_property (), which checks if the element name is "property" and its context's state (is it either STATE_CLASS or STATE_INTERFACE?).  The element "property" is part of the third warning above.



A quick grep of Gee-0.8.gir (grep -P "(^\t<|<property)" /usr/share/gir-1.0/Gee-0.8.gir | grep -B 1 "<property" | grep -P -v "<property") shows that the parent of every property element is a class or interface, except for one, which is a <record>, and corresponds to the line number for the warning.



Indeed, some more grepping (grep -P "(^\t<|<property)" /usr/share/gir-1.0/Gee-0.8.gir | grep -B 1 "<property" | grep -P -v "<property" | sed -r -e 's,.* name="([^"]*)".*,\1,g' | grep -v "\-\-" | while read line; do grep " $line.*{$" /usr/share/vala/vapi/gee-0.8.vapi ; done) reveals that every other structure with a property extends from GLib.Object, whereas Lazy does not.  So, while Vala allows this property on this record, the girparser doesn't expect it there.



https://live.gnome.org/Vala/Manual/Classes#Types_of_class

^ this explains the difference a little, with GObject-derived classes supporting managed properties, and Fundamental GType classes (which I think <record> corresponds to) supporting unmanaged ones.



I probably need to file a bug. :)  Solutions will be extending what the girparser expects, reducing what valac allows, or just simply avoiding using certain features (if I really want to ignore the warning badly enough).


The annotation element


Looking at girparser.c, there's no handling for "annotation" at all that I can find.



Inside the Gee-0.8.gir file, some problematic annotations are these:

<namespace name="Gee" version="0.8" c:prefix="Gee">
        <annotation key="ccode.gir-version" value="0.8"/>
        <annotation key="ccode.gir-namespace" value="Gee"/>




        ...

                <property name="equal-func" writable="1">
                        <annotation key="ccode.notify" value="false"/>
                        <type name="Gee.EqualDataFunc" c:type="GeeEqualDataFunc"/>
                </property>




I wonder how prevalent such annotations are, and what provokes them.  I'm trying to create a test case right now, so I can file a bug.



So, for my GXml warnings, the annotations are in my Attr.vala file, with this line above the namespace start:

[CCode (gir_namespace = "GXml", gir_version = "0.3")]



I'm not sure that I actually want to avoid that.


Bug filed


For now, I've file a bug, 702824.  I'm not sure what the most desirable outcome is, but perhaps annotation and properties in records could be acknowledged and not warned about.


2013-06-17

[Technology] SELinux and audit.log not updating

Disclaimer: I am neither a FUSE nor an SELinux expert 

So, I have a FUSE filesystem for the home directory of one of the users on my computer, and launching chromium-browser and some other programs who had data directories in the FUSE filesystem failed to launch.


Learning about SELinux


It appears that generally only the mounting user can see the mounted filesystem, so I wondered whether that was part of the problem, but testing chromium-browser on a test /tmp/ directory with permissions 700 still worked.  I then tried the regular thing, and checked if it was SELinux.  It's always SELinux.  Indeed, briefly setting setenforce 0 allowed chromium-browser to launch.  Obviously that's not a real solution; it's like taking the battery out of a beeping smoke alarm.



Recently on Google+ I perused a thread on SELinux linked to stopdisablingselinux.com, which leads to a 52 minute RedHat video on how to properly use it.  While I feel that 52 minutes is a bit long to convince the average user, I'd like to better understand SELinux, so I watched it. 



I recommend watching it if you're curious about how to work with SELinux because it was pretty clear and crisp.  Types, labels, policies and useful commands.


auditd, audit.log not updating?




Now, I'll confess that I've known there's been something amiss with my configuration, in that, for a while (since upgrading to Fedora 16!), I have not seen any sealerts.  I've confirmed that SELinux was operating and haven't had the time to diagnose the problem further.  At first I thought that sealerts were no longer being displayed by intent, but then a Fedora 18 Live USB key started displaying some.   With my new knowledge, I solved two problems in one day.



To find out what was going on with fuse and chromium-browser, I manually checked /var/log/audit/audit.log to discover that it had not been updated since November 2011!   I checked to see whether auditd was running using systemctl and ps, and it was not.  It probably hasn't started since that upgrade.  Probably systemd-migration related.  Referring to the Fedora 18 security manual, the solution to this was simple, /sbin/chkconfig --levels 2345 auditd on, so it will usually start, and systemctl start auditd.service, so it would start right now. 


Using FUSE file systems as home directories


Then, I tested chromium-browser again, sometimes starting with its user-data-dir in the FUSE filesystem, other times in /tmp/, and the problem I was encountering was this:

type=ANOM_ABEND msg=audit(1371441397.452:21): auid=504 uid=504 gid=504 ses=2 subj=unconfined_u:unconfined_r:chrome_sandbox_t:s0-s0:c0.c1044 pid=21858 comm="chromium-browse" reason="memory violation" sig=11



Sadly, setroubleshootd couldn't offer any solutions to this, so I googled ANOM_ABEND and "memory violation" and fuse, and discovered the boolean use_fusefs_home_dirs.  There weren't many search results, but this was enough.  Using setsebool use_fusefs_home_dirs 1 allowed chromium-browser and others to run normally.  Hooray!


Concluding Thoughts


Upgrading and migrating settings and customisation

 

So, two thoughts: Fedora and Linux distributions in general often have problems when upgrading.  Fedora used to (still does?) advise that you install through Anaconda, and I think I was supposed to install a clean system.  I don't think that's very user friendly, having to burn ISOs, and feel like it should happen in place managed by software (not during a user session, of course).  Eventually preupgrade came along, and eventually it become acceptable.  Still, though, upgrades often end up with subtly broken configuration.  gnome-documents was supposed to be notable in one upgrade, but I had to manually install it, because the upgrade didn't add it as a new package for the new release.  Worse than system configuration breaking (like auditd's autostarting at boot) might be user configuration for apps changing and rarely is any migration offered.  I have config files that are many years old that are no longer used and just sit there, or contain now invalid configuration.   There are stale gconf keys.  One solution is to start fresh and copy over data, but then it's a pain re-onfiguring all my favourite apps, and I might not know what customisations I've lost.  One solution is to reduce the amount of customisation that is allowed, so you don't have to support complex migrations later, and I feel like that's the current trend.  I think I'd like a standardised settings and migration standard.  I suppose GSettings and dconf helps deal with a class of settings within GNOME applications, but of course many tools are not GNOME, and even many GNOME applications store data in ~/.config/.  Ah well.  At least awareness and familiarity with my system (a luxury) helps me avoid anything catastrophic, though not so much, as I haven't had time to fix my SELinux logging for over a year.



User feedback from security applications



SELinux is getting better, with sealert and setroubleshoot, but it and the firewall have some issues in offering feedback to users.  Even with auditd and the other tools, SELinux wasn't able to indicate to me that use_fusefs_home_dirs set to 0 was preventing my browser from running.  It's the type of feedback that would be nice to save me an hour of my day.  I've seen many neat features appear in applications, using mDNS networking and Avahi, that "mysteriously" don't work, and in reality it's because the firewall silently blocks it.  Promoting features in applications that can't work out-of-the-box and where the user can't readily know why it isn't working is sad.   Perhaps developers are afraid of the syndrome where you present security information to a user and then they blindly click "allow" to everything, no matter how dangerous or malicious.  Is that better or worse than googling and reading in a dozen forums the solution of "disable the firewall" or "disable SELinux" for people who can't be bothered (time is precious) to understand and crisply fix their problem.

Dieses Blog durchsuchen

Labels

#Technology #GNOME gnome gxml fedora bugs linux vala google #General firefox security gsoc GUADEC android bug xml fedora 18 javascript libxml2 programming web blogger encryption fedora 17 gdom git emacs libgdata memory mozilla open source serialisation upgrade web development API Spain containers design evolution fedora 16 fedora 20 fedora 22 fedup file systems friends future glib gnome shell internet luks music performance phone photos php podman preupgrade tablet testing typescript yum #Microblog Network Manager adb apache art automation bash brno catastrophe css data loss debian debugging deja-dup disaster docker emusic errors ext4 facebook fedora 19 gee gir gitlab gitorious gmail gobject google talk google+ gtk html libxml mail microsoft mtp mysql namespaces nautilus nextcloud owncloud picasaweb pitivi ptp python raspberry pi resizing rpm school selinux signal sms speech dispatcher systemd technology texting time management uoguelph usability video web design youtube #Tech Air Canada C Electron Element Empathy Europe GError GNOME 3 GNOME Files Go Google Play Music Grimes IRC Mac OS X Mario Kart Memento Nintendo Nintendo Switch PEAP Selenium Splatoon UI VPN Xiki accessibility advertising ai albums anaconda anonymity apple ask asus eee top automake autonomous automobiles b43 backup battery berlin bit rot broadcom browsers browsing canada canadian english cars chrome clarity comments communication compiler complaints computer computers configuration console constructive criticism cron cropping customisation dataloss dconf debug symbols design patterns desktop summit development discoverability distribution diy dnf documentation drm duplicity e-mail efficiency email english environment estate experimenting ext3 fedora 11 festival file formats firejail flac flatpak forgottotagit freedom friendship fuse galaxy nexus galton gay rights gdb german germany gimp gio gjs gnome software gnome-control-center google assistant google calendar google chrome google hangouts google reader gqe graphviz growth gtest gtg gvfs gvfs metadata hard drive hard drives hardware help hp humour ide identity instagram installation instant messaging integration intel interactivity introspection jabber java java 13 jobs kernel keyboard language language servers languages law learning lenovo letsencrypt libreoffice librpm life livecd liveusb login lsp macbook maintainership mariadb mario matrix memory leaks messaging mounting mouse netflix new zealand node nodelist numix obama oci ogg oggenc oh the humanity open open standards openoffice optimisation org-mode organisation package management packagekit paint shedding parallelism pdo perl pipelight privacy productivity progress progressive web apps pumpkin pwa pyright quality recursion redhat refactoring repairs report rhythmbox rust sandboxes scheduling screenshots self-navigating car shell sleep smartphones software software engineering speed sql ssd synergy tabs test tests themes thesis tracker travel triumf turtles tv tweak twist typing university update usb user experience valadoc video editing volunteering vpnc waf warm wayland weather web apps website wifi wiki wireless wishes work xinput xmpp xorg xpath
Powered by Blogger.