After struggling for hours with this too and trying what felt like everything and anything I finally came up with a solution that works!
The main issue here is that the browser doesn't fire the onChange() event of the input fields when it populates the username and password.
ZK relies on this to update its own component's value. Furthermore, this also makes it impossible for us to know exactly when the browser has populated the values.
The work-around that I have is to add a timer to your page which fires repeatedly and forces ZK's updateChange() routine from the client-side.
Given this basic scenario:
<form>
<textbox id="loginUsername"/>
<textbox id="loginPassword" type="password"/>
<button id="loginButton" type="submit"/>
</form>
This timer would do the trick:
<timer id="timer" delay="500" repeats="true" w:onTimer="zk.Widget.$('$loginUsername').updateChange_();zk.Widget.$('$loginPassword').updateChange_();" />
It's important to note that the w:onTimer property is a client-side property and requires the following declaration in your top most element:
xmlns:w="client"
Even though it seems a bit brute-force it has no negative effects on the user inputting his / her username and password if it was not populated by the browser and you could easily stop the timer once the user does something on the page.